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