Bug 1392176 Implement prompts for browser.permissions.request() on Android draft
authorAndrew Swan <aswan@mozilla.com>
Tue, 12 Sep 2017 19:06:45 -0700
changeset 665805 1556a5f841795c4e8815d5c3435b1e8069505b87
parent 665514 cd0d088a099c58226219457f4e4137ac43d2f845
child 666499 cc48a03a64d7d28f3c408752e416da9d451e964b
push id80183
push useraswan@mozilla.com
push dateFri, 15 Sep 2017 23:43:30 +0000
bugs1392176
milestone57.0a1
Bug 1392176 Implement prompts for browser.permissions.request() on Android MozReview-Commit-ID: Dufy1pRFtgK
mobile/android/app/mobile.js
mobile/android/chrome/content/ExtensionPermissions.js
mobile/android/components/extensions/ext-tabs.js
mobile/android/locales/en-US/chrome/browser.properties
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -226,16 +226,17 @@ pref("extensions.getAddons.getWithPerfor
 /* preference for the locale picker */
 pref("extensions.getLocales.get.url", "");
 pref("extensions.compatability.locales.buildid", "0");
 
 /* Don't let XPIProvider install distribution add-ons; we do our own thing on mobile. */
 pref("extensions.installDistroAddons", false);
 
 pref("extensions.webextPermissionPrompts", true);
+pref("extensions.webextOptionalPermissionPrompts", true);
 
 // Add-on content security policies.
 pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* moz-extension: blob: filesystem: 'unsafe-eval' 'unsafe-inline'; object-src 'self' https://* moz-extension: blob: filesystem:;");
 pref("extensions.webextensions.default-content-security-policy", "script-src 'self'; object-src 'self';");
 
 pref("extensions.legacy.enabled", false);
 
 /* block popups by default, and notify the user about blocked popups */
--- a/mobile/android/chrome/content/ExtensionPermissions.js
+++ b/mobile/android/chrome/content/ExtensionPermissions.js
@@ -5,17 +5,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 var ExtensionPermissions = {
   // id -> object containing update details (see applyUpdate() )
   updates: new Map(),
 
   // Prepare the strings needed for a permission notification.
   _prepareStrings(info) {
     let appName = Strings.brand.GetStringFromName("brandShortName");
-    let info2 = Object.assign({appName, addonName: info.addon.name}, info);
+    let info2 = Object.assign({appName}, info);
     let strings = ExtensionData.formatPermissionStrings(info2, Strings.browser);
 
     // We dump the main body of the dialog into a big android
     // TextView.  Build a big string with the full contents here.
     let message = "";
     if (strings.msgs.length > 0) {
       message = [strings.listIntro, ...strings.msgs.map(s => `\u2022 ${s}`)].join("\n");
     }
@@ -38,18 +38,18 @@ var ExtensionPermissions = {
     // If we can't render an icon, show the default
     return "DEFAULT";
   },
 
   async observe(subject, topic, data) {
     switch (topic) {
       case "webextension-permission-prompt": {
         let {target, info} = subject.wrappedJSObject;
-
-        let details = this._prepareStrings(info);
+        let stringInfo = Object.assign({addonName: info.addon.name}, info);
+        let details = this._prepareStrings(stringInfo);
         details.icon = this._prepareIcon(info.icon);
         details.type = "Extension:PermissionPrompt";
         let accepted = await EventDispatcher.instance.sendRequestForResult(details);
 
         if (accepted) {
           info.resolve();
         } else {
           info.reject();
@@ -57,16 +57,17 @@ var ExtensionPermissions = {
         break;
       }
 
       case "webextension-update-permissions":
         let info = subject.wrappedJSObject;
         let {addon, resolve, reject} = info;
         let stringInfo = Object.assign({
           type: "update",
+          addonName: addon.name,
         }, info);
 
         let details = this._prepareStrings(stringInfo);
 
         // If there are no promptable permissions, just apply the update
         if (details.message.length == 0) {
           resolve();
           return;
@@ -82,20 +83,40 @@ var ExtensionPermissions = {
         if (first) {
           EventDispatcher.instance.sendRequest({
             type: "Extension:ShowUpdateIcon",
             value: true,
           });
         }
         break;
 
-      case "webextension-optional-permission-prompt":
-        // To be implemented in bug 1392176, just auto-approve until then
-        subject.wrappedJSObject.resolve(true);
-        break;
+      case "webextension-optional-permission-prompt": {
+        let info = subject.wrappedJSObject;
+        let {name, resolve} = info;
+        let stringInfo = Object.assign({
+          type: "optional",
+          addonName: name,
+        }, info);
+
+        let details = this._prepareStrings(stringInfo);
+
+        // If there are no promptable permissions, just apply the update
+        if (details.message.length == 0) {
+          resolve(true);
+          return;
+        }
+
+        // Store all the details about the update until the user chooses to
+        // look at update, at which point we will pick up in this.applyUpdate()
+        details.icon = this._prepareIcon(info.icon || "dummy.svg");
+
+        details.type = "Extension:PermissionPrompt";
+        let accepted = await EventDispatcher.instance.sendRequestForResult(details);
+        resolve(accepted);
+      }
     }
   },
 
   async applyUpdate(id) {
     if (!this.updates.has(id)) {
       return;
     }
 
--- a/mobile/android/components/extensions/ext-tabs.js
+++ b/mobile/android/components/extensions/ext-tabs.js
@@ -1,18 +1,16 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
-XPCOMUtils.defineLazyModuleGetter(this, "MatchPattern",
-                                  "resource://gre/modules/MatchPattern.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
                                   "resource://gre/modules/PromiseUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
 const getBrowserWindow = window => {
--- a/mobile/android/locales/en-US/chrome/browser.properties
+++ b/mobile/android/locales/en-US/chrome/browser.properties
@@ -125,16 +125,24 @@ webextPerms.add.label=Add
 webextPerms.cancel.label=Cancel
 
 # LOCALIZATION NOTE (webextPerms.updateText)
 # %S is replaced with the localized name of the updated extension.
 webextPerms.updateText=%S has been updated. You must approve new permissions before the updated version will install. Choosing “Cancel” will maintain your current add-on version.
 
 webextPerms.updateAccept.label=Update
 
+# LOCALIZATION NOTE (webextPerms.optionalPermsHeader)
+# %S is replaced with the localized name of the extension requesting new
+# permissions.
+webextPerms.optionalPermsHeader=%S requests additional permissions.
+webextPerms.optionalPermsListIntro=It wants to:
+webextPerms.optionalPermsAllow.label=Allow
+webextPerms.optionalPermsDeny.label=Deny
+
 webextPerms.description.bookmarks=Read and modify bookmarks
 webextPerms.description.browserSettings=Read and modify browser settings
 webextPerms.description.browsingData=Clear recent browsing history, cookies, and related data
 webextPerms.description.clipboardRead=Get data from the clipboard
 webextPerms.description.clipboardWrite=Input data to the clipboard
 webextPerms.description.devtools=Extend developer tools to access your data in open tabs
 webextPerms.description.downloads=Download files and read and modify the browser’s download history
 webextPerms.description.downloads.open=Open files downloaded to your computer