@@ -73,8 +73,11 @@ public class FileUtils extends CordovaPlugin {
7373 * Permission callback codes
7474 */
7575
76- public static final int READ_PERM = 0 ;
77- public static final int WRITE_PERM = 1 ;
76+ public static final int GET_FILE_CALLBACK_CODE = 0 ;
77+ public static final int WRITE_CALLBACK_CODE = 1 ;
78+ public static final int GET_DIRECTORY_CALLBACK_CODE = 2 ;
79+ public static final int WRITE = 3 ;
80+ public static final int READ = 4 ;
7881
7982 public static int UNKNOWN_ERR = 1000 ;
8083
@@ -347,19 +350,17 @@ else if (action.equals("write")) {
347350 threadhelper ( new FileOp ( ){
348351 public void run (JSONArray args ) throws JSONException , FileNotFoundException , IOException , NoModificationAllowedException {
349352 String fname =args .getString (0 );
353+ String nativeURL = resolveLocalFileSystemURI (fname ).getString ("nativeURL" );
350354 String data =args .getString (1 );
351355 int offset =args .getInt (2 );
352356 Boolean isBinary =args .getBoolean (3 );
353- /*
354- * If we don't have the package name in the path, we're reading and writing to places we need permission for
355- */
356- if (fname .contains (cordova .getActivity ().getPackageName ()) ||
357- hasReadPermission ()) {
358- long fileSize = write (fname , data , offset , isBinary );
359- callbackContext .sendPluginResult (new PluginResult (PluginResult .Status .OK , fileSize ));
357+
358+ if (needPermission (nativeURL , WRITE )) {
359+ getWritePermission ();
360360 }
361361 else {
362- getWritePermission ();
362+ long fileSize = write (fname , data , offset , isBinary );
363+ callbackContext .sendPluginResult (new PluginResult (PluginResult .Status .OK , fileSize ));
363364 }
364365
365366 }
@@ -433,28 +434,41 @@ public void run(JSONArray args) throws JSONException, IOException {
433434 else if (action .equals ("getDirectory" )) {
434435 threadhelper ( new FileOp ( ){
435436 public void run (JSONArray args ) throws FileExistsException , IOException , TypeMismatchException , EncodingException , JSONException {
436- String dirname =args .getString (0 );
437- String path =args .getString (1 );
438- JSONObject obj = getFile (dirname , path , args .optJSONObject (2 ), true );
439- callbackContext .success (obj );
437+ String dirname = args .getString (0 );
438+ String path = args .getString (1 );
439+ String nativeURL = resolveLocalFileSystemURI (dirname ).getString ("nativeURL" );
440+ boolean containsCreate = (args .isNull (2 )) ? false : args .getJSONObject (2 ).optBoolean ("create" , false );
441+
442+ if (containsCreate && needPermission (nativeURL , WRITE )) {
443+ getPermissionDir (WRITE );
444+ }
445+ else if (!containsCreate && needPermission (nativeURL , READ )) {
446+ getPermissionDir (READ );
447+ }
448+ else {
449+ JSONObject obj = getFile (dirname , path , args .optJSONObject (2 ), true );
450+ callbackContext .success (obj );
451+ }
440452 }
441453 }, rawArgs , callbackContext );
442454 }
443455 else if (action .equals ("getFile" )) {
444456 threadhelper ( new FileOp ( ){
445457 public void run (JSONArray args ) throws FileExistsException , IOException , TypeMismatchException , EncodingException , JSONException {
446- String dirname =args .getString (0 );
447- /*
448- * If we don't have the package name in the path, we're reading and writing to places we need permission for
449- */
450- if (dirname .contains (cordova .getActivity ().getPackageName ()) ||
451- hasReadPermission ()) {
452- String path = args .getString (1 );
453- JSONObject obj = getFile (dirname , path , args .optJSONObject (2 ), false );
454- callbackContext .success (obj );
458+ String dirname = args .getString (0 );
459+ String path = args .getString (1 );
460+ String nativeURL = resolveLocalFileSystemURI (dirname ).getString ("nativeURL" );
461+ boolean containsCreate = (args .isNull (2 )) ? false : args .getJSONObject (2 ).optBoolean ("create" , false );
462+
463+ if (containsCreate && needPermission (nativeURL , WRITE )) {
464+ getPermissionFile (WRITE );
465+ }
466+ else if (!containsCreate && needPermission (nativeURL , READ )) {
467+ getPermissionFile (READ );
455468 }
456469 else {
457- getReadPermission ();
470+ JSONObject obj = getFile (dirname , path , args .optJSONObject (2 ), false );
471+ callbackContext .success (obj );
458472 }
459473 }
460474 }, rawArgs , callbackContext );
@@ -533,14 +547,27 @@ public void run(JSONArray args) throws FileNotFoundException, JSONException, Mal
533547 return true ;
534548 }
535549
536- private void getReadPermission () {
537- PermissionHelper .requestPermission (this , READ_PERM , Manifest .permission .READ_EXTERNAL_STORAGE );
550+ private void getPermissionFile (int permissionType ) {
551+ if (permissionType == READ ) {
552+ PermissionHelper .requestPermission (this , GET_FILE_CALLBACK_CODE , Manifest .permission .READ_EXTERNAL_STORAGE );
553+ }
554+ else {
555+ PermissionHelper .requestPermission (this , GET_FILE_CALLBACK_CODE , Manifest .permission .WRITE_EXTERNAL_STORAGE );
556+ }
538557 }
539558
540- private void getWritePermission () {
541- PermissionHelper .requestPermission (this , WRITE_PERM , Manifest .permission .WRITE_EXTERNAL_STORAGE );
559+ private void getPermissionDir (int permissionType ) {
560+ if (permissionType == READ ) {
561+ PermissionHelper .requestPermission (this , GET_DIRECTORY_CALLBACK_CODE , Manifest .permission .READ_EXTERNAL_STORAGE );
562+ }
563+ else {
564+ PermissionHelper .requestPermission (this , GET_DIRECTORY_CALLBACK_CODE , Manifest .permission .WRITE_EXTERNAL_STORAGE );
565+ }
542566 }
543567
568+ private void getWritePermission () {
569+ PermissionHelper .requestPermission (this , WRITE_CALLBACK_CODE , Manifest .permission .WRITE_EXTERNAL_STORAGE );
570+ }
544571
545572 private boolean hasReadPermission () {
546573 return PermissionHelper .hasPermission (this , Manifest .permission .READ_EXTERNAL_STORAGE );
@@ -550,6 +577,26 @@ private boolean hasWritePermission() {
550577 return PermissionHelper .hasPermission (this , Manifest .permission .WRITE_EXTERNAL_STORAGE );
551578 }
552579
580+ private boolean needPermission (String nativeURL , int permissionType ) throws JSONException {
581+ JSONObject j = requestAllPaths ();
582+ String [] allowedStorageDirectories = {j .getString ("applicationStorageDirectory" ), j .getString ("externalApplicationStorageDirectory" )};
583+
584+ if (permissionType == READ && hasReadPermission ()) {
585+ return false ;
586+ }
587+ else if (permissionType == WRITE && hasWritePermission ()) {
588+ return false ;
589+ }
590+
591+ // Permission required if the native url lies outside the allowed storage directories
592+ for (String directory : allowedStorageDirectories ) {
593+ if (nativeURL .startsWith (directory )) {
594+ return false ;
595+ }
596+ }
597+ return true ;
598+ }
599+
553600
554601 public LocalFilesystemURL resolveNativeUri (Uri nativeUri ) {
555602 LocalFilesystemURL localURL = null ;
@@ -1113,18 +1160,29 @@ public void onRequestPermissionResult(int requestCode, String[] permissions,
11131160 }
11141161 switch (requestCode )
11151162 {
1116- case READ_PERM :
1163+ case GET_FILE_CALLBACK_CODE :
11171164 threadhelper ( new FileOp ( ){
11181165 public void run (JSONArray args ) throws FileExistsException , IOException , TypeMismatchException , EncodingException , JSONException {
1119- String dirname = args .getString (0 );
1166+ String dirname = args .getString (0 );
11201167
11211168 String path = args .getString (1 );
11221169 JSONObject obj = getFile (dirname , path , args .optJSONObject (2 ), false );
11231170 callback .success (obj );
11241171 }
11251172 }, lastRawArgs , callback );
11261173 break ;
1127- case WRITE_PERM :
1174+ case GET_DIRECTORY_CALLBACK_CODE :
1175+ threadhelper ( new FileOp ( ){
1176+ public void run (JSONArray args ) throws FileExistsException , IOException , TypeMismatchException , EncodingException , JSONException {
1177+ String dirname = args .getString (0 );
1178+
1179+ String path = args .getString (1 );
1180+ JSONObject obj = getFile (dirname , path , args .optJSONObject (2 ), true );
1181+ callback .success (obj );
1182+ }
1183+ }, lastRawArgs , callback );
1184+ break ;
1185+ case WRITE_CALLBACK_CODE :
11281186 threadhelper ( new FileOp ( ){
11291187 public void run (JSONArray args ) throws JSONException , FileNotFoundException , IOException , NoModificationAllowedException {
11301188 String fname =args .getString (0 );
@@ -1136,6 +1194,7 @@ public void run(JSONArray args) throws JSONException, FileNotFoundException, IOE
11361194 }
11371195 }, lastRawArgs , callback );
11381196 break ;
1197+
11391198 }
11401199
11411200 }
0 commit comments