Skip to content

Commit

Permalink
Pass GalleryProvider URIs to Muzei
Browse files Browse the repository at this point in the history
Fixes a long standing issue where grants to Muzei were not extended to the view Intent. This a limitation where we need to create a temp file for using ExifInterface, but that's a limitation of ExifInterface (it only operates on Files)
  • Loading branch information
ianhanniballake committed Sep 2, 2016
1 parent 10014a3 commit ab1f4da
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 44 deletions.
Expand Up @@ -172,6 +172,9 @@ public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
@Override
public void onClick(View view) {
viewIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Make sure any data URIs granted to Muzei are passed onto the
// started Activity
viewIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
startActivity(viewIntent);
} catch (ActivityNotFoundException | SecurityException e) {
Expand Down
Expand Up @@ -164,14 +164,13 @@ private void publishNextArtwork(Uri forceUri) {
scheduleNext();

Cursor chosenUris = getContentResolver().query(GalleryContract.ChosenPhotos.CONTENT_URI,
new String[] { GalleryContract.ChosenPhotos.COLUMN_NAME_URI },
new String[] { BaseColumns._ID },
null, null, null);
int numChosenUris = (chosenUris != null) ? chosenUris.getCount() : 0;

Artwork currentArtwork = getCurrentArtwork();
String lastToken = (currentArtwork != null) ? currentArtwork.getToken() : null;

boolean useStoredFile = true;
Uri imageUri;
Random random = new Random();
if (forceUri != null) {
Expand All @@ -180,14 +179,13 @@ private void publishNextArtwork(Uri forceUri) {
} else if (numChosenUris > 0) {
while (true) {
chosenUris.moveToPosition(random.nextInt(chosenUris.getCount()));
imageUri = Uri.parse(chosenUris.getString(
chosenUris.getColumnIndex(GalleryContract.ChosenPhotos.COLUMN_NAME_URI)));
imageUri = ContentUris.withAppendedId(GalleryContract.ChosenPhotos.CONTENT_URI,
chosenUris.getLong(chosenUris.getColumnIndex(BaseColumns._ID)));
if (numChosenUris <= 1 || !imageUri.toString().equals(lastToken)) {
break;
}
}
} else {
useStoredFile = false;
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Expand Down Expand Up @@ -264,18 +262,13 @@ private void publishNextArtwork(Uri forceUri) {
byline = getString(R.string.gallery_touch_to_view);
}

Uri finalImageUri = imageUri;
if (useStoredFile) {
finalImageUri = Uri.fromFile(GalleryProvider.getCacheFileForUri(this, imageUri.toString()));
}

publishArtwork(new Artwork.Builder()
.imageUri(finalImageUri)
.imageUri(imageUri)
.title(title)
.byline(byline)
.token(token)
.viewIntent(new Intent(Intent.ACTION_VIEW)
.setDataAndType(finalImageUri, "image/jpeg"))
.setDataAndType(imageUri, "image/jpeg"))
.build());
}

Expand Down Expand Up @@ -322,7 +315,7 @@ private void ensureMetadataExists(@NonNull Uri imageUri) {
ContentValues values = new ContentValues();
values.put(GalleryContract.MetadataCache.COLUMN_NAME_URI, imageUri.toString());

File imageFile = GalleryProvider.getCacheFileForUri(this, imageUri.toString());
File imageFile = GalleryProvider.getLocalFileForUri(this, imageUri.toString());
if (imageFile == null) {
return;
}
Expand Down
Expand Up @@ -278,36 +278,36 @@ private Uri insertChosenPhotos(@NonNull final Uri uri, final ContentValues value
if (!values.containsKey(GalleryContract.ChosenPhotos.COLUMN_NAME_URI))
throw new IllegalArgumentException("Initial values must contain URI " + values);
String imageUri = values.getAsString(GalleryContract.ChosenPhotos.COLUMN_NAME_URI);
try {
boolean persistedPermission = false;
Uri uriToTake = Uri.parse(imageUri);
// Try to persist access to the URI, saving us from having to store a local copy
if (getContext() != null && DocumentsContract.isDocumentUri(getContext(), uriToTake)) {
try {
getContext().getContentResolver().takePersistableUriPermission(uriToTake, Intent.FLAG_GRANT_READ_URI_PERMISSION);
persistedPermission = true;
// If we have a persisted URI permission, we don't need a local copy
File cachedFile = getCacheFileForUri(getContext(), imageUri);
if (cachedFile != null && cachedFile.exists()) {
if (!cachedFile.delete()) {
Log.w(TAG, "Unable to delete " + cachedFile);
}
boolean persistedPermission = false;
Uri uriToTake = Uri.parse(imageUri);
// Try to persist access to the URI, saving us from having to store a local copy
if (getContext() != null && DocumentsContract.isDocumentUri(getContext(), uriToTake)) {
try {
getContext().getContentResolver().takePersistableUriPermission(uriToTake, Intent.FLAG_GRANT_READ_URI_PERMISSION);
persistedPermission = true;
// If we have a persisted URI permission, we don't need a local copy
File cachedFile = getCacheFileForUri(getContext(), imageUri);
if (cachedFile != null && cachedFile.exists()) {
if (!cachedFile.delete()) {
Log.w(TAG, "Unable to delete " + cachedFile);
}
} catch (SecurityException ignored) {
// If we don't have FLAG_GRANT_PERSISTABLE_URI_PERMISSION (such as when using ACTION_GET_CONTENT),
// this will fail. It'll also fail for URIs originating from our own app.
// These cases are handled below
}
} catch (SecurityException ignored) {
// If we don't have FLAG_GRANT_PERSISTABLE_URI_PERMISSION (such as when using ACTION_GET_CONTENT),
// this will fail. It'll also fail for URIs originating from our own app.
// These cases are handled below
}
if (!persistedPermission &&
!imageUri.startsWith(ContentResolver.SCHEME_CONTENT + "://" + getContext().getPackageName())) {
// We only need to make a local copy if we weren't able to persist the permission
// and the URI is not from our package (we always have access to those URIs)
writeUriToFile(imageUri, getCacheFileForUri(getContext(), imageUri));
}
if (!persistedPermission &&
!imageUri.startsWith(ContentResolver.SCHEME_CONTENT + "://" + getContext().getPackageName())) {
// We only need to make a local copy if we weren't able to persist the permission
// and the URI is not from our package (we always have access to those URIs)
try {
writeUriToFile(getContext(), imageUri, getCacheFileForUri(getContext(), imageUri));
} catch (IOException e) {
Log.e(TAG, "Error downloading gallery image " + imageUri, e);
throw new SQLException("Error downloading gallery image " + imageUri);
}
} catch (IOException e) {
Log.e(TAG, "Error downloading gallery image " + imageUri, e);
throw new SQLException("Error downloading gallery image " + imageUri);
}
final SQLiteDatabase db = databaseHelper.getWritableDatabase();
long rowId = db.insert(GalleryContract.ChosenPhotos.TABLE_NAME,
Expand All @@ -324,15 +324,14 @@ private Uri insertChosenPhotos(@NonNull final Uri uri, final ContentValues value
throw new SQLException("Failed to insert row into " + uri);
}

private void writeUriToFile(String uri, File destFile) throws IOException {
ContentResolver contentResolver = getContext() != null ? getContext().getContentResolver() : null;
if (contentResolver == null) {
private static void writeUriToFile(Context context, String uri, File destFile) throws IOException {
if (context == null) {
return;
}
InputStream in = null;
OutputStream out = null;
try {
in = contentResolver.openInputStream(Uri.parse(uri));
in = context.getContentResolver().openInputStream(Uri.parse(uri));
if (in == null) {
return;
}
Expand Down Expand Up @@ -483,7 +482,23 @@ private ParcelFileDescriptor openFileChosenPhoto(@NonNull final Uri uri, @NonNul
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.parseMode(mode));
}

static File getCacheFileForUri(Context context, @NonNull String imageUri) {
static File getLocalFileForUri(Context context, @NonNull String imageUri) {
File cachedFile = getCacheFileForUri(context, imageUri);
if (cachedFile != null) {
return cachedFile;
}
// Create a local file
File tempFile = new File(context.getCacheDir(), "tempimage");
try {
writeUriToFile(context, imageUri, tempFile);
return tempFile;
} catch (IOException e) {
Log.e(TAG, "Error downloading gallery image " + imageUri, e);
return null;
}
}

private static File getCacheFileForUri(Context context, @NonNull String imageUri) {
File directory = new File(context.getExternalFilesDir(null), "gallery_images");
if (!directory.exists() && !directory.mkdirs()) {
return null;
Expand Down

0 comments on commit ab1f4da

Please sign in to comment.