Merge mozilla-inbound to mozilla-central. a=merge
authorAndreea Pavel <apavel@mozilla.com>
Sun, 14 Apr 2019 00:45:44 +0300
changeset 469419 0cf7ad6c1a23ea598cf72c00d06daeb2607ae039
parent 469418 2c3837b46068b53cabeb3a1a3222f04eb8132b55 (current diff)
parent 469332 b7e2018b550c9e0cb80644b23791e673d152ac3f (diff)
child 469422 334cb98220b1762a2a985cb8bae12aac8232c9cd
push id112787
push userapavel@mozilla.com
push dateSat, 13 Apr 2019 21:53:37 +0000
treeherdermozilla-inbound@0cf7ad6c1a23 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone68.0a1
first release with
nightly linux32
0cf7ad6c1a23 / 68.0a1 / 20190413214623 / files
nightly linux64
0cf7ad6c1a23 / 68.0a1 / 20190413214623 / files
nightly mac
0cf7ad6c1a23 / 68.0a1 / 20190413214623 / files
nightly win32
0cf7ad6c1a23 / 68.0a1 / 20190413214623 / files
nightly win64
0cf7ad6c1a23 / 68.0a1 / 20190413214623 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central. a=merge
--- a/mobile/android/tests/browser/robocop/testThemeInstall.js
+++ b/mobile/android/tests/browser/robocop/testThemeInstall.js
@@ -1,16 +1,17 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {EventDispatcher} = ChromeUtils.import("resource://gre/modules/Messaging.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 // The chrome window and friends.
 let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
 let BrowserApp = chromeWin.BrowserApp;
 
 const BASE = "https://example.com:443/tests/robocop/";
 const XPI = BASE + "browser_theme_image_file.xpi";
 const PAGE = BASE + "robocop_blank_04.html";
@@ -20,17 +21,35 @@ let tabTest;
 
 function cleanupTabs() {
   if (tabTest) {
     BrowserApp.closeTab(tabTest);
     tabTest = null;
   }
 }
 
+// A user prompt is displayed during theme installation and responding to
+// the prompt from test code is tricky.  Instead, just override the prompt
+// implementation and let installation proceed.
+const PROMPT_CLASSID = Components.ID("{85325f87-03f8-d142-b3a0-d2a0b8f2d4e0}");
+const PROMPT_CONTRACTID = "@mozilla.org/addons/web-install-prompt;1";
+function NullPrompt() {}
+NullPrompt.prototype = {
+  QueryInterface: ChromeUtils.generateQI([Ci.amIWebInstallPrompt]),
+  confirm(browser, url, installs) {
+    installs[0].install();
+  },
+};
+
 add_task(async function testThemeInstall() {
+  let factory = XPCOMUtils.generateSingletonFactory(NullPrompt);
+  let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+  let originalCID = registrar.contractIDToCID(PROMPT_CONTRACTID);
+  registrar.registerFactory(PROMPT_CLASSID, "", PROMPT_CONTRACTID, factory);
+
   await SpecialPowers.pushPrefEnv({
     set: [["extensions.webapi.testing", true],
           ["extensions.install.requireBuiltInCerts", false]],
   });
 
   tabTest = BrowserApp.addTab(PAGE);
   let browser = tabTest.browser;
   let content = browser.contentWindow;
@@ -56,11 +75,14 @@ add_task(async function testThemeInstall
      "headerURL references resource inside extension file");
 
   await EventDispatcher.instance.sendRequestForResult({
     type: "Robocop:WaitOnUI",
   });
 
   Services.obs.removeObserver(observer, "lightweight-theme-styling-update");
   cleanupTabs();
+
+  registrar.unregisterFactory(PROMPT_CLASSID, factory);
+  registrar.registerFactory(originalCID, "", PROMPT_CONTRACTID, null);
 });
 
 run_next_test();
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -2535,17 +2535,17 @@ var AddonManagerInternal = {
 
       // All installs end up in this callback when the add-on is available
       // for installation.  There are numerous different things that can
       // happen from here though.  For webextensions, if the application
       // implements webextension permission prompts, those always take
       // precedence.
       // If this add-on is not a webextension or if the application does not
       // implement permission prompts, no confirmation is displayed for
-      // installs created with mozAddonManager (in which case requireConfirm
+      // installs created from about:addons (in which case requireConfirm
       // is false).
       // In the remaining cases, a confirmation prompt is displayed but the
       // application may override it either by implementing the
       // "@mozilla.org/addons/web-install-prompt;1" contract or by setting
       // the customConfirmationUI preference and responding to the
       // "addon-install-confirmation" notification.  If the application
       // does not implement its own prompt, use the built-in xul dialog.
       if (info.addon.userPermissions && WEBEXT_PERMISSION_PROMPTS) {
@@ -2700,17 +2700,22 @@ var AddonManagerInternal = {
         browser: target,
         triggeringPrincipal: options.triggeringPrincipal,
         hash: options.hash,
         telemetryInfo: {
           source: AddonManager.getInstallSourceFromHost(options.sourceHost),
           method: "amWebAPI",
         },
       }).then(install => {
-        AddonManagerInternal.setupPromptHandler(target, null, install, false, "AMO");
+        let requireConfirm = true;
+        if (target.contentDocument &&
+            target.contentDocument.nodePrincipal.isSystemPrincipal) {
+          requireConfirm = false;
+        }
+        AddonManagerInternal.setupPromptHandler(target, null, install, requireConfirm, "AMO");
 
         let id = this.nextInstall++;
         let {listener, installPromise} = makeListener(id, target.messageManager);
         install.addListener(listener);
 
         this.installs.set(id, {install, target, listener, installPromise});
 
         let result = {id};
--- a/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js
@@ -16,24 +16,31 @@ add_task(async function test_theme_insta
     function observer(subject, topic, data) {
       updates.push(JSON.stringify(subject.wrappedJSObject));
     }
     Services.obs.addObserver(observer, "lightweight-theme-styling-update");
     registerCleanupFunction(() => {
       Services.obs.removeObserver(observer, "lightweight-theme-styling-update");
     });
 
+    let sawConfirm = false;
+    promisePopupNotificationShown("addon-install-confirmation").then(panel => {
+      sawConfirm = true;
+      panel.button.click();
+    });
 
     let prompt1 = waitAppMenuNotificationShown("addon-installed", "theme@tests.mozilla.org", false);
     let installPromise = ContentTask.spawn(browser, URL, async (url) => {
       let install = await content.navigator.mozAddonManager.createInstall({url});
       return install.install();
     });
     await prompt1;
 
+    ok(sawConfirm, "Confirm notification was displayed before installation");
+
     // Open a new window and test the app menu panel from there.  This verifies the
     // incognito checkbox as well as finishing install in this case.
     let newWin = await BrowserTestUtils.openNewBrowserWindow();
     await waitAppMenuNotificationShown("addon-installed", "theme@tests.mozilla.org", true, newWin);
     await installPromise;
     ok(true, "Theme install completed");
 
     await BrowserTestUtils.closeWindow(newWin);