You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by rk...@apache.org on 2016/03/30 19:49:54 UTC
cordova-plugin-file git commit: CB-10977 android: Removing global
state used for permission requests
Repository: cordova-plugin-file
Updated Branches:
refs/heads/master 1e2593f42 -> 6aeb9d9d1
CB-10977 android: Removing global state used for permission requests
This closes #174
Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/6aeb9d9d
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/6aeb9d9d
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/6aeb9d9d
Branch: refs/heads/master
Commit: 6aeb9d9d1a91c2657218e6c81dfe2b57bd46f7d7
Parents: 1e2593f
Author: Richard Knoll <ri...@gmail.com>
Authored: Mon Mar 28 12:09:21 2016 -0700
Committer: Richard Knoll <ri...@gmail.com>
Committed: Wed Mar 30 10:24:35 2016 -0700
----------------------------------------------------------------------
plugin.xml | 1 +
src/android/FileUtils.java | 142 ++++++++++++++++------------------
src/android/PendingRequests.java | 94 ++++++++++++++++++++++
3 files changed, 163 insertions(+), 74 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/6aeb9d9d/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
index 4c79325..46dbbdb 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -146,6 +146,7 @@ to config.xml in order for the application to find previously stored files.
<source-file src="src/android/LocalFilesystem.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/ContentFilesystem.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/AssetFilesystem.java" target-dir="src/org/apache/cordova/file" />
+ <source-file src="src/android/PendingRequests.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/PermissionHelper.java" target-dir="src/org/apache/cordova/file" />
<!-- android specific file apis -->
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/6aeb9d9d/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index e9169bc..cf193d0 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -73,18 +73,20 @@ public class FileUtils extends CordovaPlugin {
* Permission callback codes
*/
- public static final int GET_FILE_CALLBACK_CODE = 0;
- public static final int WRITE_CALLBACK_CODE = 1;
- public static final int GET_DIRECTORY_CALLBACK_CODE = 2;
+ public static final int ACTION_GET_FILE = 0;
+ public static final int ACTION_WRITE = 1;
+ public static final int ACTION_GET_DIRECTORY = 2;
+
public static final int WRITE = 3;
public static final int READ = 4;
public static int UNKNOWN_ERR = 1000;
private boolean configured = false;
- private String lastRawArgs;
- private CallbackContext callback;
+ private PendingRequests pendingRequests;
+
+
/*
* We need both read and write when accessing the storage, I think.
@@ -171,6 +173,7 @@ public class FileUtils extends CordovaPlugin {
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
this.filesystems = new ArrayList<Filesystem>();
+ this.pendingRequests = new PendingRequests();
String tempRoot = null;
String persistentRoot = null;
@@ -262,14 +265,12 @@ public class FileUtils extends CordovaPlugin {
}
public boolean execute(String action, final String rawArgs, final CallbackContext callbackContext) {
- this.callback = callbackContext;
- lastRawArgs = rawArgs;
if (!configured) {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "File plugin is not configured. Please see the README.md file for details on how to update config.xml"));
return true;
}
if (action.equals("testSaveLocationExists")) {
- threadhelper( new FileOp( ){
+ threadhelper(new FileOp() {
public void run(JSONArray args) {
boolean b = DirectoryManager.testSaveLocationExists();
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
@@ -356,7 +357,7 @@ public class FileUtils extends CordovaPlugin {
Boolean isBinary=args.getBoolean(3);
if(needPermission(nativeURL, WRITE)) {
- getWritePermission();
+ getWritePermission(rawArgs, ACTION_WRITE, callbackContext);
}
else {
long fileSize = write(fname, data, offset, isBinary);
@@ -440,10 +441,10 @@ public class FileUtils extends CordovaPlugin {
boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean("create", false);
if(containsCreate && needPermission(nativeURL, WRITE)) {
- getPermissionDir(WRITE);
+ getWritePermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext);
}
else if(!containsCreate && needPermission(nativeURL, READ)) {
- getPermissionDir(READ);
+ getReadPermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext);
}
else {
JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true);
@@ -461,10 +462,10 @@ public class FileUtils extends CordovaPlugin {
boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean("create", false);
if(containsCreate && needPermission(nativeURL, WRITE)) {
- getPermissionFile(WRITE);
+ getWritePermission(rawArgs, ACTION_GET_FILE, callbackContext);
}
else if(!containsCreate && needPermission(nativeURL, READ)) {
- getPermissionFile(READ);
+ getReadPermission(rawArgs, ACTION_GET_FILE, callbackContext);
}
else {
JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false);
@@ -547,26 +548,14 @@ public class FileUtils extends CordovaPlugin {
return true;
}
- private void getPermissionFile(int permissionType) {
- if(permissionType == READ) {
- PermissionHelper.requestPermission(this, GET_FILE_CALLBACK_CODE, Manifest.permission.READ_EXTERNAL_STORAGE);
- }
- else {
- PermissionHelper.requestPermission(this, GET_FILE_CALLBACK_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
- }
+ private void getReadPermission(String rawArgs, int action, CallbackContext callbackContext) {
+ int requestCode = pendingRequests.createRequest(rawArgs, action, callbackContext);
+ PermissionHelper.requestPermission(this, requestCode, Manifest.permission.READ_EXTERNAL_STORAGE);
}
- private void getPermissionDir(int permissionType) {
- if(permissionType == READ) {
- PermissionHelper.requestPermission(this, GET_DIRECTORY_CALLBACK_CODE, Manifest.permission.READ_EXTERNAL_STORAGE);
- }
- else {
- PermissionHelper.requestPermission(this, GET_DIRECTORY_CALLBACK_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
- }
- }
-
- private void getWritePermission() {
- PermissionHelper.requestPermission(this, WRITE_CALLBACK_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
+ private void getWritePermission(String rawArgs, int action, CallbackContext callbackContext) {
+ int requestCode = pendingRequests.createRequest(rawArgs, action, callbackContext);
+ PermissionHelper.requestPermission(this, requestCode, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
private boolean hasReadPermission() {
@@ -1151,51 +1140,56 @@ public class FileUtils extends CordovaPlugin {
public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) throws JSONException {
- for(int r:grantResults)
- {
- if(r == PackageManager.PERMISSION_DENIED)
+
+ final PendingRequests.Request req = pendingRequests.getAndRemove(requestCode);
+ if (req != null) {
+ for(int r:grantResults)
{
- callback.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR));
+ if(r == PackageManager.PERMISSION_DENIED)
+ {
+ req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR));
+ return;
+ }
}
+ switch(req.getAction())
+ {
+ case ACTION_GET_FILE:
+ threadhelper( new FileOp( ){
+ public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
+ String dirname = args.getString(0);
+
+ String path = args.getString(1);
+ JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false);
+ req.getCallbackContext().success(obj);
+ }
+ }, req.getRawArgs(), req.getCallbackContext());
+ break;
+ case ACTION_GET_DIRECTORY:
+ threadhelper( new FileOp( ){
+ public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
+ String dirname = args.getString(0);
+
+ String path = args.getString(1);
+ JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true);
+ req.getCallbackContext().success(obj);
+ }
+ }, req.getRawArgs(), req.getCallbackContext());
+ break;
+ case ACTION_WRITE:
+ threadhelper( new FileOp( ){
+ public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {
+ String fname=args.getString(0);
+ String data=args.getString(1);
+ int offset=args.getInt(2);
+ Boolean isBinary=args.getBoolean(3);
+ long fileSize = write(fname, data, offset, isBinary);
+ req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
+ }
+ }, req.getRawArgs(), req.getCallbackContext());
+ break;
+ }
+ } else {
+ Log.d(LOG_TAG, "Received permission callback for unknown request code");
}
- switch(requestCode)
- {
- case GET_FILE_CALLBACK_CODE:
- threadhelper( new FileOp( ){
- public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
- String dirname = args.getString(0);
-
- String path = args.getString(1);
- JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false);
- callback.success(obj);
- }
- }, lastRawArgs, callback);
- break;
- case GET_DIRECTORY_CALLBACK_CODE:
- threadhelper( new FileOp( ){
- public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
- String dirname = args.getString(0);
-
- String path = args.getString(1);
- JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true);
- callback.success(obj);
- }
- }, lastRawArgs, callback);
- break;
- case WRITE_CALLBACK_CODE:
- threadhelper( new FileOp( ){
- public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {
- String fname=args.getString(0);
- String data=args.getString(1);
- int offset=args.getInt(2);
- Boolean isBinary=args.getBoolean(3);
- long fileSize = write(fname, data, offset, isBinary);
- callback.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
- }
- }, lastRawArgs, callback);
- break;
-
- }
-
}
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/6aeb9d9d/src/android/PendingRequests.java
----------------------------------------------------------------------
diff --git a/src/android/PendingRequests.java b/src/android/PendingRequests.java
new file mode 100644
index 0000000..23d6d73
--- /dev/null
+++ b/src/android/PendingRequests.java
@@ -0,0 +1,94 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+package org.apache.cordova.file;
+
+import android.util.SparseArray;
+
+import org.apache.cordova.CallbackContext;
+
+/**
+ * Holds pending runtime permission requests
+ */
+class PendingRequests {
+ private int currentReqId = 0;
+ private SparseArray<Request> requests = new SparseArray<Request>();
+
+ /**
+ * Creates a request and adds it to the array of pending requests. Each created request gets a
+ * unique result code for use with requestPermission()
+ * @param rawArgs The raw arguments passed to the plugin
+ * @param action The action this request corresponds to (get file, etc.)
+ * @param callbackContext The CallbackContext for this plugin call
+ * @return The request code that can be used to retrieve the Request object
+ */
+ public synchronized int createRequest(String rawArgs, int action, CallbackContext callbackContext) {
+ Request req = new Request(rawArgs, action, callbackContext);
+ requests.put(req.requestCode, req);
+ return req.requestCode;
+ }
+
+ /**
+ * Gets the request corresponding to this request code and removes it from the pending requests
+ * @param requestCode The request code for the desired request
+ * @return The request corresponding to the given request code or null if such a
+ * request is not found
+ */
+ public synchronized Request getAndRemove(int requestCode) {
+ Request result = requests.get(requestCode);
+ requests.remove(requestCode);
+ return result;
+ }
+
+ /**
+ * Holds the options and CallbackContext for a call made to the plugin.
+ */
+ public class Request {
+
+ // Unique int used to identify this request in any Android permission callback
+ private int requestCode;
+
+ // Action to be performed after permission request result
+ private int action;
+
+ // Raw arguments passed to plugin
+ private String rawArgs;
+
+ // The callback context for this plugin request
+ private CallbackContext callbackContext;
+
+ private Request(String rawArgs, int action, CallbackContext callbackContext) {
+ this.rawArgs = rawArgs;
+ this.action = action;
+ this.callbackContext = callbackContext;
+ this.requestCode = currentReqId ++;
+ }
+
+ public int getAction() {
+ return this.action;
+ }
+
+ public String getRawArgs() {
+ return rawArgs;
+ }
+
+ public CallbackContext getCallbackContext() {
+ return callbackContext;
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org