Bug 1350151 Part 3: Use requireUserInput for downloads.open() draft
authorAndrew Swan <aswan@mozilla.com>
Tue, 25 Jul 2017 23:01:05 -0700
changeset 618763 932f631f6b8fd319b11b85b3a842408ce5018780
parent 618762 8211c210e4e9b7182c70c7130e25510bd3580490
child 640172 c4d582076ff9e0f9ae739a6180351d50faced7a3
push id71443
push useraswan@mozilla.com
push dateTue, 01 Aug 2017 02:18:17 +0000
bugs1350151
milestone56.0a1
Bug 1350151 Part 3: Use requireUserInput for downloads.open() MozReview-Commit-ID: GhXBZ5sWlRt
toolkit/components/extensions/ext-c-downloads.js
toolkit/components/extensions/ext-c-toolkit.js
toolkit/components/extensions/ext-downloads.js
toolkit/components/extensions/jar.mn
toolkit/components/extensions/schemas/downloads.json
toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_open.html
deleted file mode 100644
--- a/toolkit/components/extensions/ext-c-downloads.js
+++ /dev/null
@@ -1,22 +0,0 @@
-"use strict";
-
-var {
-  ExtensionError,
-} = ExtensionUtils;
-
-this.downloads = class extends ExtensionAPI {
-  getAPI(context) {
-    return {
-      downloads: {
-        open(downloadId) {
-          let winUtils = context.contentWindow.getInterface(Ci.nsIDOMWindowUtils);
-          if (!winUtils.isHandlingUserInput) {
-            throw new ExtensionError("May only open downloads from a user input handler");
-          }
-
-          return context.childManager.callParentAsyncFunction("downloads.open_parent", [downloadId]);
-        },
-      },
-    };
-  }
-};
--- a/toolkit/components/extensions/ext-c-toolkit.js
+++ b/toolkit/components/extensions/ext-c-toolkit.js
@@ -36,23 +36,16 @@ extensions.registerModules({
     url: "chrome://extensions/content/ext-c-backgroundPage.js",
     scopes: ["addon_child"],
     manifest: ["background"],
     paths: [
       ["extension", "getBackgroundPage"],
       ["runtime", "getBackgroundPage"],
     ],
   },
-  downloads: {
-    url: "chrome://extensions/content/ext-c-downloads.js",
-    scopes: ["addon_child"],
-    paths: [
-      ["downloads"],
-    ],
-  },
   extension: {
     url: "chrome://extensions/content/ext-c-extension.js",
     scopes: ["addon_child", "content_child", "devtools_child", "proxy_script"],
     paths: [
       ["extension"],
     ],
   },
   i18n: {
--- a/toolkit/components/extensions/ext-downloads.js
+++ b/toolkit/components/extensions/ext-downloads.js
@@ -640,17 +640,17 @@ this.downloads = class extends Extension
             for (let item of items) {
               promises.push(DownloadMap.erase(item));
               results.push(item.id);
             }
             return Promise.all(promises).then(() => results);
           });
         },
 
-        open_parent(downloadId) {
+        open(downloadId) {
           return DownloadMap.lazyInit().then(() => {
             let download = DownloadMap.fromId(downloadId).download;
             if (download.succeeded) {
               return download.launch();
             }
             return Promise.reject({message: "Download has not completed."});
           }).catch((error) => {
             return Promise.reject({message: error.message});
--- a/toolkit/components/extensions/jar.mn
+++ b/toolkit/components/extensions/jar.mn
@@ -27,17 +27,16 @@ toolkit.jar:
     content/extensions/ext-theme.js
     content/extensions/ext-toolkit.js
     content/extensions/ext-topSites.js
     content/extensions/ext-webRequest.js
     content/extensions/ext-webNavigation.js
     # Below is a separate group using the naming convention ext-c-*.js that run
     # in the child process.
     content/extensions/ext-c-backgroundPage.js
-    content/extensions/ext-c-downloads.js
     content/extensions/ext-c-extension.js
 #ifndef ANDROID
     content/extensions/ext-c-identity.js
 #endif
     content/extensions/ext-c-runtime.js
     content/extensions/ext-c-storage.js
     content/extensions/ext-c-test.js
     content/extensions/ext-c-toolkit.js
--- a/toolkit/components/extensions/schemas/downloads.json
+++ b/toolkit/components/extensions/schemas/downloads.json
@@ -552,16 +552,17 @@
             "type": "function"
           }
         ]
       },
       {
         "name": "open",
         "type": "function",
         "async": "callback",
+        "requireUserInput": true,
         "description": "Open the downloaded file.",
         "permissions": ["downloads.open"],
         "parameters": [
           {
             "name": "downloadId",
             "type": "integer"
           },
           {
--- a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_open.html
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_open.html
@@ -31,17 +31,17 @@ add_task(async function test_downloads_o
   await extension.awaitFinish("downloads tests");
   await extension.unload();
 });
 
 add_task(async function test_downloads_open_requires_user_interaction() {
   async function backgroundScript() {
     await browser.test.assertRejects(
       browser.downloads.open(10),
-      "May only open downloads from a user input handler",
+      "downloads.open may only be called from a user input handler",
       "The error is informative.");
 
     browser.test.notifyPass("downloads tests");
   }
 
   let extensionData = {
     background: backgroundScript,
     manifest: {