Bug 1337692 - Check runtime permission in FilePicker. r?sebastian draft
authorNevin Chen <cnevinchen@gmail.com>
Wed, 22 Feb 2017 19:05:31 +0800
changeset 488445 c72d899ddc3de29e010bf5817196b010edba3351
parent 469313 ece0e0fd16a30d37249a18c41fa65143d7c01b8f
child 546727 9612183aed0505f4fb1f764744031a4a3bcf4b0c
push id46528
push userbmo:cnevinchen@gmail.com
push dateThu, 23 Feb 2017 04:07:14 +0000
reviewerssebastian
bugs1337692
milestone54.0a1
Bug 1337692 - Check runtime permission in FilePicker. r?sebastian MozReview-Commit-ID: 9Bb9olB0V7n
mobile/android/base/java/org/mozilla/gecko/FilePicker.java
--- a/mobile/android/base/java/org/mozilla/gecko/FilePicker.java
+++ b/mobile/android/base/java/org/mozilla/gecko/FilePicker.java
@@ -1,19 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.permissions.Permissions;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 
+import android.Manifest;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.Parcelable;
@@ -55,26 +57,58 @@ public class FilePicker implements Bundl
             final int tabId = message.getInt("tabId", -1);
             final String title = message.getString("title");
 
             if ("mimeType".equals(mode)) {
                 mimeType = message.getString("mimeType");
             } else if ("extension".equals(mode)) {
                 mimeType = GeckoAppShell.getMimeTypeFromExtensions(message.getString("extensions"));
             }
+            final String[] requiredPermission = checkIfPermissionNeeded(mimeType);
 
-            showFilePickerAsync(title, mimeType, new ResultHandler() {
-                @Override
-                public void gotFile(final String filename) {
-                    callback.sendSuccess(filename);
-                }
-            }, tabId);
+            final String finalMimeType = mimeType;
+            // Use activity context cause we want to prompt for runtime permission. (bug 1337692)
+            Permissions.from(GeckoAppShell.getGeckoInterface().getActivity())
+                    .withPermissions(requiredPermission)
+                    .andFallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            // Do nothing if permission not granted.
+                        }
+                    })
+                    .run(new Runnable() {
+                        @Override
+                        public void run() {
+                            showFilePickerAsync(title, finalMimeType, new ResultHandler() {
+                                @Override
+                                public void gotFile(final String filename) {
+                                    callback.sendSuccess(filename);
+                                }
+                            }, tabId);
+                        }
+                    });
+
+
         }
     }
 
+    private String[] checkIfPermissionNeeded(final String mimeType) {
+        if (mimeType == null) {
+            return new String[] { Manifest.permission.READ_EXTERNAL_STORAGE };
+        }
+        if (mimeType.startsWith("audio/")) {
+            return new String[] { Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE };
+        } else if (mimeType.startsWith("image/")) {
+            return new String[] { Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE };
+        } else if (mimeType.startsWith("video/")) {
+            return new String[] { Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE };
+        }
+        return new String[] { Manifest.permission.READ_EXTERNAL_STORAGE };
+    }
+
     private void addActivities(Intent intent, HashMap<String, Intent> intents, HashMap<String, Intent> filters) {
         PackageManager pm = context.getPackageManager();
         List<ResolveInfo> lri = pm.queryIntentActivities(intent, 0);
         for (ResolveInfo ri : lri) {
             ComponentName cn = new ComponentName(ri.activityInfo.applicationInfo.packageName, ri.activityInfo.name);
             if (filters != null && !filters.containsKey(cn.toString())) {
                 Intent rintent = new Intent(intent);
                 rintent.setComponent(cn);