Repository: cordova-plugin-file
Updated Branches:
  refs/heads/master 61c0f76f1 -> 1e2593f42


CB-10798, CB-10384: Fixing permissions for Marshmallow. This closes #170


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/1e2593f4
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/1e2593f4
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/1e2593f4

Branch: refs/heads/master
Commit: 1e2593f42455aa78d7fff7400a834beb37a0683c
Parents: 61c0f76
Author: Raghav Katyal <rakat...@microsoft.com>
Authored: Fri Mar 11 11:03:30 2016 -0800
Committer: Raghav Katyal <rakat...@microsoft.com>
Committed: Fri Mar 18 18:54:33 2016 -0700

----------------------------------------------------------------------
 src/android/FileUtils.java | 121 ++++++++++++++++++++++++++++++----------
 1 file changed, 90 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/1e2593f4/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index aa81fa0..e9169bc 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -73,8 +73,11 @@ public class FileUtils extends CordovaPlugin {
      * Permission callback codes
      */
 
-    public static final int READ_PERM = 0;
-    public static final int WRITE_PERM = 1;
+    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 WRITE = 3;
+    public static final int READ = 4;
 
     public static int UNKNOWN_ERR = 1000;
 
@@ -347,19 +350,17 @@ public class FileUtils extends CordovaPlugin {
             threadhelper( new FileOp( ){
                 public void run(JSONArray args) throws JSONException, 
FileNotFoundException, IOException, NoModificationAllowedException {
                     String fname=args.getString(0);
+                    String nativeURL = 
resolveLocalFileSystemURI(fname).getString("nativeURL");
                     String data=args.getString(1);
                     int offset=args.getInt(2);
                     Boolean isBinary=args.getBoolean(3);
-                    /*
-                     * If we don't have the package name in the path, we're 
reading and writing to places we need permission for
-                     */
-                    if(fname.contains(cordova.getActivity().getPackageName()) 
||
-                            hasReadPermission()) {
-                        long fileSize = write(fname, data, offset, isBinary);
-                        callbackContext.sendPluginResult(new 
PluginResult(PluginResult.Status.OK, fileSize));
+
+                    if(needPermission(nativeURL, WRITE)) {
+                        getWritePermission();
                     }
                     else {
-                        getWritePermission();
+                        long fileSize = write(fname, data, offset, isBinary);
+                        callbackContext.sendPluginResult(new 
PluginResult(PluginResult.Status.OK, fileSize));
                     }
 
                 }
@@ -433,28 +434,41 @@ public class FileUtils extends CordovaPlugin {
         else if (action.equals("getDirectory")) {
             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);
-                    callbackContext.success(obj);
+                    String dirname = args.getString(0);
+                    String path = args.getString(1);
+                    String nativeURL = 
resolveLocalFileSystemURI(dirname).getString("nativeURL");
+                    boolean containsCreate = (args.isNull(2)) ? false : 
args.getJSONObject(2).optBoolean("create", false);
+
+                    if(containsCreate && needPermission(nativeURL, WRITE)) {
+                        getPermissionDir(WRITE);
+                    }
+                    else if(!containsCreate && needPermission(nativeURL, 
READ)) {
+                        getPermissionDir(READ);
+                    }
+                    else {
+                        JSONObject obj = getFile(dirname, path, 
args.optJSONObject(2), true);
+                        callbackContext.success(obj);
+                    }
                 }
             }, rawArgs, callbackContext);
         }
         else if (action.equals("getFile")) {
             threadhelper( new FileOp( ){
                 public void run(JSONArray args) throws FileExistsException, 
IOException, TypeMismatchException, EncodingException, JSONException {
-                    String dirname=args.getString(0);
-                    /*
-                     * If we don't have the package name in the path, we're 
reading and writing to places we need permission for
-                     */
-                    
if(dirname.contains(cordova.getActivity().getPackageName()) ||
-                            hasReadPermission()) {
-                        String path = args.getString(1);
-                        JSONObject obj = getFile(dirname, path, 
args.optJSONObject(2), false);
-                        callbackContext.success(obj);
+                    String dirname = args.getString(0);
+                    String path = args.getString(1);
+                    String nativeURL = 
resolveLocalFileSystemURI(dirname).getString("nativeURL");
+                    boolean containsCreate = (args.isNull(2)) ? false : 
args.getJSONObject(2).optBoolean("create", false);
+
+                    if(containsCreate && needPermission(nativeURL, WRITE)) {
+                        getPermissionFile(WRITE);
+                    }
+                    else if(!containsCreate && needPermission(nativeURL, 
READ)) {
+                        getPermissionFile(READ);
                     }
                     else {
-                        getReadPermission();
+                        JSONObject obj = getFile(dirname, path, 
args.optJSONObject(2), false);
+                        callbackContext.success(obj);
                     }
                 }
             }, rawArgs, callbackContext);
@@ -533,14 +547,27 @@ public class FileUtils extends CordovaPlugin {
         return true;
     }
 
-    private void getReadPermission() {
-        PermissionHelper.requestPermission(this, READ_PERM, 
Manifest.permission.READ_EXTERNAL_STORAGE);
+    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 getWritePermission() {
-        PermissionHelper.requestPermission(this, WRITE_PERM, 
Manifest.permission.WRITE_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 boolean hasReadPermission() {
         return PermissionHelper.hasPermission(this, 
Manifest.permission.READ_EXTERNAL_STORAGE);
@@ -550,6 +577,26 @@ public class FileUtils extends CordovaPlugin {
         return PermissionHelper.hasPermission(this, 
Manifest.permission.WRITE_EXTERNAL_STORAGE);
     }
 
+    private boolean needPermission(String nativeURL, int permissionType) 
throws JSONException {
+        JSONObject j = requestAllPaths();
+        String[] allowedStorageDirectories = 
{j.getString("applicationStorageDirectory"), 
j.getString("externalApplicationStorageDirectory")};
+
+        if(permissionType == READ && hasReadPermission()) {
+            return false;
+        }
+        else if(permissionType == WRITE && hasWritePermission()) {
+            return false;
+        }
+
+        // Permission required if the native url lies outside the allowed 
storage directories
+        for(String directory : allowedStorageDirectories) {
+            if(nativeURL.startsWith(directory)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
 
     public LocalFilesystemURL resolveNativeUri(Uri nativeUri) {
         LocalFilesystemURL localURL = null;
@@ -1113,10 +1160,10 @@ public class FileUtils extends CordovaPlugin {
         }
         switch(requestCode)
         {
-            case READ_PERM:
+            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 dirname = args.getString(0);
 
                         String path = args.getString(1);
                         JSONObject obj = getFile(dirname, path, 
args.optJSONObject(2), false);
@@ -1124,7 +1171,18 @@ public class FileUtils extends CordovaPlugin {
                     }
                 }, lastRawArgs, callback);
                 break;
-            case WRITE_PERM:
+            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);
@@ -1136,6 +1194,7 @@ public class FileUtils extends CordovaPlugin {
                     }
                 }, lastRawArgs, callback);
                 break;
+
         }
 
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org
For additional commands, e-mail: commits-h...@cordova.apache.org

Reply via email to