Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 94 additions & 3 deletions src/android/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ Licensed to the Apache Software Foundation (ASF) under one
*/
package org.apache.cordova.file;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;
Expand All @@ -41,6 +44,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.security.Permission;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -65,9 +69,27 @@ public class FileUtils extends CordovaPlugin {
public static int TYPE_MISMATCH_ERR = 11;
public static int PATH_EXISTS_ERR = 12;

/*
* Permission callback codes
*/

public static final int READ_PERM = 0;
public static final int WRITE_PERM = 1;

public static int UNKNOWN_ERR = 1000;

private boolean configured = false;
private String lastRawArgs;

private CallbackContext callback;

/*
* We need both read and write when accessing the storage, I think.
*/

private String [] permissions = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is unused - why not just remove it.

Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE };

// This field exists only to support getEntry, below, which has been deprecated
private static FileUtils filePlugin;
Expand Down Expand Up @@ -237,6 +259,8 @@ public Uri remapUri(Uri uri) {
}

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;
Expand Down Expand Up @@ -412,9 +436,18 @@ else if (action.equals("getFile")) {
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);
callbackContext.success(obj);
/*
* 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);
}
else {
getReadPermission();
}
}
}, rawArgs, callbackContext);
}
Expand Down Expand Up @@ -492,6 +525,30 @@ public void run(JSONArray args) throws FileNotFoundException, JSONException, Mal
return true;
}

private void getReadPermission() {
cordova.requestPermission(this, READ_PERM, Manifest.permission.READ_EXTERNAL_STORAGE);
}

private void getWritePermission() {
cordova.requestPermission(this, WRITE_PERM, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}


private boolean hasReadPermission() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return PackageManager.PERMISSION_GRANTED == cordova.getActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
else
return true;
}

private boolean hasWritePermission() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return PackageManager.PERMISSION_GRANTED == cordova.getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
else
return true;
}


public LocalFilesystemURL resolveNativeUri(Uri nativeUri) {
LocalFilesystemURL localURL = null;

Expand Down Expand Up @@ -1019,4 +1076,38 @@ private long truncateFile(String srcURLstr, long size) throws FileNotFoundExcept
throw new MalformedURLException("Unrecognized filesystem URL");
}
}


/*
* Handle the response
*/

public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) throws JSONException {
for(int r:grantResults)
{
if(r == PackageManager.PERMISSION_DENIED)
{
callback.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR));
}
}
switch(requestCode)
{
case READ_PERM:
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 WRITE_PERM:

break;
}

}
}