Bug 1450449 - Part 2: Use content:// URI for capturing images from FilePicker. r?jchen draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Sat, 12 May 2018 23:02:19 +0200
changeset 803595 f6464ef0686ed9328c58dcc4a0852b2f6dc0ea3e
parent 803366 703dce7078d2296c209dd0b2e5aabf1790c76361
child 803596 cffc3091e60c1c103755925afa362e542f8c84a5
push id112161
push usermozilla@buttercookie.de
push dateMon, 04 Jun 2018 18:00:37 +0000
reviewersjchen
bugs1450449
milestone62.0a1
Bug 1450449 - Part 2: Use content:// URI for capturing images from FilePicker. r?jchen Since it is only us and the camera app who have to deal with the content:// URI, it should be safe enough to use content:// URIs on all supported versions. MozReview-Commit-ID: JMIhBRlCiA4
mobile/android/base/java/org/mozilla/gecko/FilePicker.java
mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
--- a/mobile/android/base/java/org/mozilla/gecko/FilePicker.java
+++ b/mobile/android/base/java/org/mozilla/gecko/FilePicker.java
@@ -174,17 +174,17 @@ public class FilePicker implements Bundl
                 Intent intent = IntentHelper.getAudioCaptureIntent();
                 addActivities(intent, intents, baseIntents);
             }
         } else if (mimeType.startsWith("image/") ) {
             addActivities(baseIntent, baseIntents, null);
             if (mimeType.equals("image/*") &&
                     hasPermissionsForMimeType(mimeType, availPermissions)) {
                 // We also add a capture intent
-                Intent intent = IntentHelper.getImageCaptureIntent(
+                Intent intent = IntentHelper.getImageCaptureIntent(context,
                         new File(Environment.getExternalStorageDirectory(),
                                 fileHandler.generateImageName()));
                 addActivities(intent, intents, baseIntents);
             }
         } else if (mimeType.startsWith("video/")) {
             addActivities(baseIntent, baseIntents, null);
             if (mimeType.equals("video/*") &&
                     hasPermissionsForMimeType(mimeType, availPermissions)) {
@@ -200,17 +200,17 @@ public class FilePicker implements Bundl
             addActivities(baseIntent, baseIntents, null);
 
             Intent intent;
             if (hasPermissionsForMimeType("audio/*", availPermissions)) {
                 intent = IntentHelper.getAudioCaptureIntent();
                 addActivities(intent, intents, baseIntents);
             }
             if (hasPermissionsForMimeType("image/*", availPermissions)) {
-                intent = IntentHelper.getImageCaptureIntent(
+                intent = IntentHelper.getImageCaptureIntent(context,
                         new File(Environment.getExternalStorageDirectory(),
                                 fileHandler.generateImageName()));
                 addActivities(intent, intents, baseIntents);
             }
             if (hasPermissionsForMimeType("video/*", availPermissions)) {
                 intent = IntentHelper.getVideoCaptureIntent();
                 addActivities(intent, intents, baseIntents);
             }
--- a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
@@ -10,25 +10,27 @@ import org.mozilla.gecko.overlays.ui.Sha
 import org.mozilla.gecko.util.ActivityResultHandler;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
 
 import android.annotation.TargetApi;
 import android.app.Activity;
+import android.content.ClipData;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.provider.Browser;
 import android.provider.MediaStore;
 import android.support.annotation.Nullable;
 import android.support.v4.app.FragmentActivity;
+import android.support.v4.content.FileProvider;
 import android.text.TextUtils;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 
 import java.io.File;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.List;
@@ -238,20 +240,31 @@ public final class IntentHelper implemen
         intent.putExtra(INTENT_EXTRA_SESSION_UUID, GeckoApplication.getSessionUUID());
         return intent;
     }
 
     public static Intent getAudioCaptureIntent() {
         return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
     }
 
-    public static Intent getImageCaptureIntent(final File destinationFile) {
+    public static Intent getImageCaptureIntent(final Context context, final File destinationFile) {
         final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-        intent.putExtra(MediaStore.EXTRA_OUTPUT,
-                Uri.fromFile(destinationFile));
+        Uri destination = FileProvider.getUriForFile(context,
+                AppConstants.MOZ_FILE_PROVIDER_AUTHORITY, destinationFile);
+        intent.putExtra(MediaStore.EXTRA_OUTPUT, destination);
+
+        if (AppConstants.Versions.preLollipop) {
+            // As per https://github.com/commonsguy/cw-omnibus/blob/master/Camera/FileProvider/
+            // app/src/main/java/com/commonsware/android/camcon/MainActivity.java - at least we
+            // don't have to support anything below Jelly Bean.
+            ClipData clip =
+                    ClipData.newUri(context.getContentResolver(), null, destination);
+            intent.setClipData(clip);
+        }
+        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
         return intent;
     }
 
     public static Intent getVideoCaptureIntent() {
         return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
     }
 
     /**