Skip to content

Commit

Permalink
Attempt to use file URIs when possible.
Browse files Browse the repository at this point in the history
  • Loading branch information
bpellin committed Mar 13, 2016
1 parent 21935a2 commit 62a2d52
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 17 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG
@@ -1,4 +1,4 @@
* Support Storage Access Framework in browse links.
* Improve file URI handling

KeePassDroid (2.0.5)
* Add .kdbx Twofish support from drizzt
Expand Down
31 changes: 16 additions & 15 deletions app/src/main/java/com/keepassdroid/PasswordActivity.java
Expand Up @@ -56,6 +56,7 @@
import com.keepassdroid.fileselect.BrowserDialog;
import com.keepassdroid.intents.Intents;
import com.keepassdroid.settings.AppSettingsActivity;
import com.keepassdroid.utils.EmptyUtils;
import com.keepassdroid.utils.Interaction;
import com.keepassdroid.utils.UriUtil;
import com.keepassdroid.utils.Util;
Expand Down Expand Up @@ -86,12 +87,15 @@ public static void Launch(Activity act, String fileName) throws FileNotFoundExce
}

public static void Launch(Activity act, String fileName, String keyFile) throws FileNotFoundException {
/*
File dbFile = new File(fileName);
if ( ! dbFile.exists() ) {
throw new FileNotFoundException();
Uri uri = UriUtil.parseDefaultFile(fileName);
String scheme = uri.getScheme();

if (!EmptyUtils.isNullOrEmpty(scheme) && scheme.equalsIgnoreCase("file")) {
File dbFile = new File(fileName);
if (!dbFile.exists()) {
throw new FileNotFoundException();
}
}
*/

Intent i = new Intent(act, PasswordActivity.class);
i.putExtra(KEY_FILENAME, fileName);
Expand Down Expand Up @@ -122,16 +126,9 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
String filename = data.getDataString();
if (filename != null) {
/*
if (filename.startsWith("file://")) {
filename = filename.substring(7);
}
filename = URLDecoder.decode(filename);
*/

EditText fn = (EditText) findViewById(R.id.pass_keyfile);
fn.setText(filename);
mKeyUri = UriUtil.parseDefaultFile(filename);
}
}
break;
Expand All @@ -141,12 +138,16 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
Uri uri = data.getData();
if (uri != null) {
String path = uri.getPath();
if (requestCode==GET_CONTENT) {
uri = UriUtil.translate(this, uri);
}
String path = uri.toString();
if (path != null) {
EditText fn = (EditText) findViewById(R.id.pass_keyfile);
fn.setText(path);

}
mKeyUri = uri;
}
}
}
Expand Down Expand Up @@ -441,7 +442,7 @@ public void onClick(View v) {
}
else {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("file/*");
i.setType("*/*");

try {
startActivityForResult(i, GET_CONTENT);
Expand Down
Expand Up @@ -192,7 +192,7 @@ public void onClick(View v) {
}
else {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("file/*");
i.setType("*/*");

try {
startActivityForResult(i, GET_CONTENT);
Expand Down Expand Up @@ -337,6 +337,9 @@ else if ((requestCode == GET_CONTENT || requestCode == OPEN_DOC) && resultCode =
if (data != null) {
Uri uri = data.getData();
if (uri != null) {
if (requestCode == GET_CONTENT) {
uri = UriUtil.translate(this, uri);
}
filename = uri.toString();
}
}
Expand Down
74 changes: 74 additions & 0 deletions app/src/main/java/com/keepassdroid/utils/UriUtil.java
Expand Up @@ -20,8 +20,12 @@
package com.keepassdroid.utils;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

import com.keepassdroid.compat.StorageAF;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
Expand Down Expand Up @@ -71,4 +75,74 @@ else if (scheme.equals("content")) {
return null;
}
}

/**
* Many android apps respond with non-writeable content URIs that correspond to files.
* This will attempt to translate the content URIs to file URIs when possible/appropriate
* @param uri
* @return
*/
public static Uri translate(Context ctx, Uri uri) {
// StorageAF provides nice URIs
if (StorageAF.useStorageFramework(ctx) || hasWritableContentUri(uri)) { return uri; }

String scheme = uri.getScheme();
if (EmptyUtils.isNullOrEmpty(scheme)) { return uri; }

String filepath = null;
// Use content resolver to try and find the file
if (scheme.equalsIgnoreCase("content")) {
Cursor cursor = ctx.getContentResolver().query(uri, new String[] {android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
cursor.moveToFirst();

filepath = cursor.getString(0);
cursor.close();

if (!isValidFilePath(filepath)) {
filepath = null;
}
}

// Try using the URI path as a straight file
if (EmptyUtils.isNullOrEmpty(filepath)) {
filepath = uri.getPath();
if (!isValidFilePath(filepath)) {
filepath = null;
}
}

// Update the file to a file URI
if (!EmptyUtils.isNullOrEmpty(filepath)) {
Uri.Builder b = new Uri.Builder();
uri = b.scheme("file").authority("").path(filepath).build();
}

return uri;
}

private static boolean isValidFilePath(String filepath) {
File file = new File(filepath);
return file.exists() && file.canRead();
}

/**
* Whitelist for known content providers that support writing
* @param uri
* @return
*/
private static boolean hasWritableContentUri(Uri uri) {
String scheme = uri.getScheme();

if (EmptyUtils.isNullOrEmpty(scheme)) { return false; }

if (!scheme.equalsIgnoreCase("content")) { return false; }

switch (uri.getAuthority()) {
case "com.google.android.apps.docs.storage":
return true;
}

return false;
}

}

0 comments on commit 62a2d52

Please sign in to comment.