--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -445,17 +445,16 @@
#ifndef DISABLE_MOZ_RIL_GEOLOC
#endif
#endif // MOZ_WIDGET_GONK && MOZ_B2G_RIL
#ifndef MOZ_WIDGET_GONK
@RESPATH@/components/addonManager.js
@RESPATH@/components/amContentHandler.js
@RESPATH@/components/amInstallTrigger.js
-@RESPATH@/components/amWebInstallListener.js
@RESPATH@/components/OopCommandLine.js
@RESPATH@/components/CommandLine.js
#endif
@RESPATH@/components/extensions.manifest
@RESPATH@/components/nsBlocklistService.js
@RESPATH@/components/BootstrapCommandLine.js
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -210,17 +210,17 @@ const gXPInstallObserver = {
Services.telemetry
.getHistogramById("SECURITY_UI")
.add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL);
},
observe(aSubject, aTopic, aData) {
var brandBundle = document.getElementById("bundle_brand");
- var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo);
+ var installInfo = aSubject.wrappedJSObject;
var browser = installInfo.browser;
// Make sure the browser is still alive.
if (!browser || gBrowser.browsers.indexOf(browser) == -1)
return;
const anchorID = "addons-notification-icon";
var messageString, action;
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -408,17 +408,16 @@
@RESPATH@/components/NetworkGeolocationProvider.js
@RESPATH@/components/extensions.manifest
@RESPATH@/components/EditorUtils.manifest
@RESPATH@/components/EditorUtils.js
@RESPATH@/components/addonManager.js
@RESPATH@/components/amContentHandler.js
@RESPATH@/components/amInstallTrigger.js
@RESPATH@/components/amWebAPI.js
-@RESPATH@/components/amWebInstallListener.js
@RESPATH@/components/nsBlocklistService.js
@RESPATH@/components/nsBlocklistServiceContent.js
#ifdef MOZ_UPDATER
@RESPATH@/components/nsUpdateService.manifest
@RESPATH@/components/nsUpdateService.js
@RESPATH@/components/nsUpdateServiceStub.js
#endif
@RESPATH@/components/nsUpdateTimerManager.manifest
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -299,17 +299,16 @@
@BINPATH@/components/EditorUtils.js
@BINPATH@/components/extensions.manifest
@BINPATH@/components/utils.manifest
@BINPATH@/components/simpleServices.js
@BINPATH@/components/addonManager.js
@BINPATH@/components/amContentHandler.js
@BINPATH@/components/amInstallTrigger.js
@BINPATH@/components/amWebAPI.js
-@BINPATH@/components/amWebInstallListener.js
@BINPATH@/components/nsBlocklistService.js
#ifndef RELEASE_OR_BETA
@BINPATH@/components/TabSource.js
#endif
@BINPATH@/components/webvtt.xpt
@BINPATH@/components/WebVTT.manifest
@BINPATH@/components/WebVTTParserWrapper.js
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -84,16 +84,20 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
"resource://gre/modules/addons/AddonRepository.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Extension",
"resource://gre/modules/Extension.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PromptUtils",
+ "resource://gre/modules/SharedPromptUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "CertUtils", function() {
let certUtils = {};
Components.utils.import("resource://gre/modules/CertUtils.jsm", certUtils);
return certUtils;
});
const INTEGER = /^[1-9]\d*$/;
@@ -439,16 +443,267 @@ BrowserListener.prototype = {
this.unregister();
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
Ci.nsIWebProgressListener,
Ci.nsIObserver])
};
+function installNotifyObservers(aTopic, aBrowser, aUri, aInstalls, aInstallFn) {
+ let info = {
+ wrappedJSObject: {
+ browser: aBrowser,
+ originatingURI: aUri,
+ installs: aInstalls,
+ install: aInstallFn,
+ },
+ };
+ Services.obs.notifyObservers(info, aTopic, null);
+}
+
+/**
+ * Creates a new installer to monitor downloads and prompt to install when
+ * ready
+ *
+ * @param aBrowser
+ * The browser that started the installations
+ * @param aUrl
+ * The URL that started the installations
+ * @param aInstalls
+ * An array of AddonInstalls
+ */
+function Installer(aBrowser, aUrl, aInstalls) {
+ this.browser = aBrowser;
+ this.url = aUrl;
+ this.downloads = aInstalls;
+ this.installed = [];
+
+ installNotifyObservers("addon-install-started", aBrowser, aUrl, aInstalls);
+
+ const READY_STATES = [
+ AddonManager.STATE_AVAILABLE,
+ AddonManager.STATE_DOWNLOAD_FAILED,
+ AddonManager.STATE_INSTALL_FAILED,
+ AddonManager.STATE_CANCELLED,
+ ];
+ for (let install of aInstalls) {
+ install.addListener(this);
+
+ // Start downloading if it hasn't already begun
+ if (READY_STATES.indexOf(install.state) != -1)
+ install.install();
+ }
+
+ this.checkAllDownloaded();
+}
+
+Installer.prototype = {
+ URI_XPINSTALL_DIALOG: "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul",
+ browser: null,
+ downloads: null,
+ installed: null,
+ isDownloading: true,
+
+ /**
+ * Checks if all downloads are now complete and if so prompts to install.
+ */
+ checkAllDownloaded: function() {
+ // Prevent re-entrancy caused by the confirmation dialog cancelling unwanted
+ // installs.
+ if (!this.isDownloading)
+ return;
+
+ var failed = [];
+ var installs = [];
+
+ for (let install of this.downloads) {
+ switch (install.state) {
+ case AddonManager.STATE_AVAILABLE:
+ case AddonManager.STATE_DOWNLOADING:
+ // Exit early if any add-ons haven't started downloading yet or are
+ // still downloading
+ return;
+ case AddonManager.STATE_DOWNLOAD_FAILED:
+ failed.push(install);
+ break;
+ case AddonManager.STATE_DOWNLOADED:
+ // App disabled items are not compatible and so fail to install
+ if (install.addon.appDisabled)
+ failed.push(install);
+ else
+ installs.push(install);
+ break;
+ case AddonManager.STATE_CANCELLED:
+ // Just ignore cancelled downloads
+ break;
+ default:
+ logger.warn("Download of " + install.sourceURI.spec + " in unexpected state " +
+ install.state);
+ }
+ }
+
+ this.isDownloading = false;
+ this.downloads = installs;
+
+ if (failed.length > 0) {
+ // Stop listening and cancel any installs that are failed because of
+ // compatibility reasons.
+ for (let install of failed) {
+ if (install.state == AddonManager.STATE_DOWNLOADED) {
+ install.removeListener(this);
+ install.cancel();
+ }
+ }
+ installNotifyObservers("addon-install-failed", this.browser, this.url, failed);
+ }
+
+ // If none of the downloads were successful then exit early
+ if (this.downloads.length == 0)
+ return;
+
+ // Check for a custom installation prompt that may be provided by the
+ // applicaton
+ if ("@mozilla.org/addons/web-install-prompt;1" in Cc) {
+ try {
+ let prompt = Cc["@mozilla.org/addons/web-install-prompt;1"].
+ getService(Ci.amIWebInstallPrompt);
+ prompt.confirm(this.browser, this.url, this.downloads, this.downloads.length);
+ return;
+ } catch (e) {}
+ }
+
+ if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+ installNotifyObservers("addon-install-confirmation", this.browser, this.url, this.downloads);
+ return;
+ }
+
+ let args = {};
+ args.url = this.url;
+ args.installs = this.downloads;
+ args.wrappedJSObject = args;
+
+ try {
+ Cc["@mozilla.org/base/telemetry;1"].
+ getService(Ci.nsITelemetry).
+ getHistogramById("SECURITY_UI").
+ add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL);
+ let parentWindow = null;
+ if (this.browser) {
+ parentWindow = this.browser.ownerDocument.defaultView;
+ PromptUtils.fireDialogEvent(parentWindow, "DOMWillOpenModalDialog", this.browser);
+ }
+ Services.ww.openWindow(parentWindow, this.URI_XPINSTALL_DIALOG,
+ null, "chrome,modal,centerscreen", args);
+ } catch (e) {
+ logger.warn("Exception showing install confirmation dialog", e);
+ for (let install of this.downloads) {
+ install.removeListener(this);
+ // Cancel the installs, as currently there is no way to make them fail
+ // from here.
+ install.cancel();
+ }
+ installNotifyObservers("addon-install-cancelled", this.browser, this.url,
+ this.downloads);
+ }
+ },
+
+ /**
+ * Checks if all installs are now complete and if so notifies observers.
+ */
+ checkAllInstalled: function() {
+ var failed = [];
+
+ for (let install of this.downloads) {
+ switch (install.state) {
+ case AddonManager.STATE_DOWNLOADED:
+ case AddonManager.STATE_INSTALLING:
+ // Exit early if any add-ons haven't started installing yet or are
+ // still installing
+ return;
+ case AddonManager.STATE_INSTALL_FAILED:
+ failed.push(install);
+ break;
+ }
+ }
+
+ this.downloads = null;
+
+ if (failed.length > 0)
+ installNotifyObservers("addon-install-failed", this.browser, this.url, failed);
+
+ if (this.installed.length > 0)
+ installNotifyObservers("addon-install-complete", this.browser, this.url, this.installed);
+ this.installed = null;
+ },
+
+ onDownloadCancelled: function(aInstall) {
+ aInstall.removeListener(this);
+ this.checkAllDownloaded();
+ },
+
+ onDownloadFailed: function(aInstall) {
+ aInstall.removeListener(this);
+ this.checkAllDownloaded();
+ },
+
+ onDownloadEnded: function(aInstall) {
+ this.checkAllDownloaded();
+ return false;
+ },
+
+ onInstallCancelled: function(aInstall) {
+ aInstall.removeListener(this);
+ this.checkAllInstalled();
+ },
+
+ onInstallFailed: function(aInstall) {
+ aInstall.removeListener(this);
+ this.checkAllInstalled();
+ },
+
+ onInstallEnded: function(aInstall) {
+ aInstall.removeListener(this);
+ this.installed.push(aInstall);
+
+ // If installing a theme that is disabled and can be enabled then enable it
+ if (aInstall.addon.type == "theme" &&
+ aInstall.addon.userDisabled == true &&
+ aInstall.addon.appDisabled == false) {
+ aInstall.addon.userDisabled = false;
+ }
+
+ this.checkAllInstalled();
+ }
+};
+
+const weblistener = {
+ onWebInstallDisabled: function(aBrowser, aUri, aInstalls) {
+ installNotifyObservers("addon-install-disabled", aBrowser, aUri, aInstalls);
+ },
+
+ onWebInstallOriginBlocked: function(aBrowser, aUri, aInstalls) {
+ installNotifyObservers("addon-install-origin-blocked", aBrowser, aUri, aInstalls);
+ return false;
+ },
+
+ onWebInstallBlocked: function(aBrowser, aUri, aInstalls) {
+ installNotifyObservers("addon-install-blocked", aBrowser, aUri, aInstalls,
+ function() { new Installer(this.browser, this.originatingURI, this.installs); });
+ return false;
+ },
+
+ onWebInstallRequested: function(aBrowser, aUri, aInstalls) {
+ new Installer(aBrowser, aUri, aInstalls);
+
+ // We start the installs ourself
+ return false;
+ },
+};
+
/**
* This represents an author of an add-on (e.g. creator or developer)
*
* @param aName
* The name of the author
* @param aURL
* The URL of the author's profile page
*/
@@ -2040,52 +2295,41 @@ var AddonManagerInternal = {
if (aBrowser && !(aBrowser instanceof Ci.nsIDOMElement))
throw Components.Exception("aSource must be a nsIDOMElement, or null",
Cr.NS_ERROR_INVALID_ARG);
if (!aInstallingPrincipal || !(aInstallingPrincipal instanceof Ci.nsIPrincipal))
throw Components.Exception("aInstallingPrincipal must be a nsIPrincipal",
Cr.NS_ERROR_INVALID_ARG);
- if (!("@mozilla.org/addons/web-install-listener;1" in Cc)) {
- logger.warn("No web installer available, cancelling install");
- aInstall.cancel();
- return;
- }
-
// When a chrome in-content UI has loaded a <browser> inside to host a
// website we want to do our security checks on the inner-browser but
// notify front-end that install events came from the outer-browser (the
// main tab's browser). Check this by seeing if the browser we've been
// passed is in a content type docshell and if so get the outer-browser.
let topBrowser = aBrowser;
let docShell = aBrowser.ownerDocument.defaultView
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIDocShellTreeItem);
if (docShell.itemType == Ci.nsIDocShellTreeItem.typeContent)
topBrowser = docShell.chromeEventHandler;
try {
- let weblistener = Cc["@mozilla.org/addons/web-install-listener;1"].
- getService(Ci.amIWebInstallListener);
-
if (!this.isInstallEnabled(aMimetype)) {
aInstall.cancel();
weblistener.onWebInstallDisabled(topBrowser, aInstallingPrincipal.URI,
[aInstall], 1);
return;
} else if (!aBrowser.contentPrincipal || !aInstallingPrincipal.subsumes(aBrowser.contentPrincipal)) {
aInstall.cancel();
- if (weblistener instanceof Ci.amIWebInstallListener2) {
- weblistener.onWebInstallOriginBlocked(topBrowser, aInstallingPrincipal.URI,
- [aInstall], 1);
- }
+ weblistener.onWebInstallOriginBlocked(topBrowser, aInstallingPrincipal.URI,
+ [aInstall], 1);
return;
}
// The install may start now depending on the web install listener,
// listen for the browser navigating to a new origin and cancel the
// install in that case.
new BrowserListener(aBrowser, aInstallingPrincipal, aInstall);
@@ -2103,16 +2347,35 @@ var AddonManagerInternal = {
// calling onWebInstallBlocked or onWebInstallRequested the
// install should get cancelled.
logger.warn("Failure calling web installer", e);
aInstall.cancel();
}
},
/**
+ * Starts installation of an AddonInstall created from add-ons manager
+ * front-end code (e.g., drag-and-drop of xpis or "Install Add-on from File"
+ *
+ * @param browser
+ * The browser element where the installation was initiated
+ * @param uri
+ * The URI of the page where the installation was initiated
+ * @param install
+ * The AddonInstall to be installed
+ */
+ installAddonFromAOM(browser, uri, install) {
+ if (!gStarted)
+ throw Components.Exception("AddonManager is not initialized",
+ Cr.NS_ERROR_NOT_INITIALIZED);
+
+ weblistener.onWebInstallRequested(browser, uri, [install]);
+ },
+
+ /**
* Adds a new InstallListener if the listener is not already registered.
*
* @param aListener
* The InstallListener to add
*/
addInstallListener(aListener) {
if (!aListener || typeof aListener != "object")
throw Components.Exception("aListener must be a InstallListener object",
@@ -3404,16 +3667,20 @@ this.AddonManager = {
},
installAddonFromWebpage(aType, aBrowser, aInstallingPrincipal, aInstall) {
AddonManagerInternal.installAddonFromWebpage(aType, aBrowser,
aInstallingPrincipal,
aInstall);
},
+ installAddonFromAOM(aBrowser, aUri, aInstall) {
+ AddonManagerInternal.installAddonFromAOM(aBrowser, aUri, aInstall);
+ },
+
installTemporaryAddon(aDirectory) {
return AddonManagerInternal.installTemporaryAddon(aDirectory);
},
installAddonFromSources(aDirectory) {
return AddonManagerInternal.installAddonFromSources(aDirectory);
},
rename from toolkit/mozapps/extensions/amIWebInstallListener.idl
rename to toolkit/mozapps/extensions/amIWebInstallPrompt.idl
--- a/toolkit/mozapps/extensions/amIWebInstallListener.idl
+++ b/toolkit/mozapps/extensions/amIWebInstallPrompt.idl
@@ -4,116 +4,16 @@
#include "nsISupports.idl"
interface nsIDOMElement;
interface nsIURI;
interface nsIVariant;
/**
- * amIWebInstallInfo is used by the default implementation of
- * amIWebInstallListener to communicate with the running application and allow
- * it to warn the user about blocked installs and start the installs running.
- */
-[scriptable, uuid(fa0b47a3-f819-47ac-bc66-4bd1d7f67b1d)]
-interface amIWebInstallInfo : nsISupports
-{
- readonly attribute nsIDOMElement browser;
- readonly attribute nsIURI originatingURI;
- readonly attribute nsIVariant installs;
-
- /**
- * Starts all installs.
- */
- void install();
-};
-
-/**
- * The registered amIWebInstallListener is used to notify about new installs
- * triggered by websites. The default implementation displays a confirmation
- * dialog when add-ons are ready to install and uses the observer service to
- * notify when installations are blocked.
- */
-[scriptable, uuid(d9240d4b-6b3a-4cad-b402-de6c93337e0c)]
-interface amIWebInstallListener : nsISupports
-{
- /**
- * Called when installation by websites is currently disabled.
- *
- * @param aBrowser
- * The browser that triggered the installs
- * @param aUri
- * The URI of the site that triggered the installs
- * @param aInstalls
- * The AddonInstalls that were blocked
- * @param aCount
- * The number of AddonInstalls
- */
- void onWebInstallDisabled(in nsIDOMElement aBrowser, in nsIURI aUri,
- [array, size_is(aCount)] in nsIVariant aInstalls,
- [optional] in uint32_t aCount);
-
- /**
- * Called when the website is not allowed to directly prompt the user to
- * install add-ons.
- *
- * @param aBrowser
- * The browser that triggered the installs
- * @param aUri
- * The URI of the site that triggered the installs
- * @param aInstalls
- * The AddonInstalls that were blocked
- * @param aCount
- * The number of AddonInstalls
- * @return true if the caller should start the installs
- */
- boolean onWebInstallBlocked(in nsIDOMElement aBrowser, in nsIURI aUri,
- [array, size_is(aCount)] in nsIVariant aInstalls,
- [optional] in uint32_t aCount);
-
- /**
- * Called when a website wants to ask the user to install add-ons.
- *
- * @param aBrowser
- * The browser that triggered the installs
- * @param aUri
- * The URI of the site that triggered the installs
- * @param aInstalls
- * The AddonInstalls that were requested
- * @param aCount
- * The number of AddonInstalls
- * @return true if the caller should start the installs
- */
- boolean onWebInstallRequested(in nsIDOMElement aBrowser, in nsIURI aUri,
- [array, size_is(aCount)] in nsIVariant aInstalls,
- [optional] in uint32_t aCount);
-};
-
-[scriptable, uuid(a80b89ad-bb1a-4c43-9cb7-3ae656556f78)]
-interface amIWebInstallListener2 : nsISupports
-{
- /**
- * Called when a non-same-origin resource attempted to initiate an install.
- * Installs will have already been cancelled and cannot be restarted.
- *
- * @param aBrowser
- * The browser that triggered the installs
- * @param aUri
- * The URI of the site that triggered the installs
- * @param aInstalls
- * The AddonInstalls that were blocked
- * @param aCount
- * The number of AddonInstalls
- */
- boolean onWebInstallOriginBlocked(in nsIDOMElement aBrowser, in nsIURI aUri,
- [array, size_is(aCount)] in nsIVariant aInstalls,
- [optional] in uint32_t aCount);
-};
-
-/**
* amIWebInstallPrompt is used, if available, by the default implementation of
* amIWebInstallInfo to display a confirmation UI to the user before running
* installs.
*/
[scriptable, uuid(386906f1-4d18-45bf-bc81-5dcd68e42c3b)]
interface amIWebInstallPrompt : nsISupports
{
/**
deleted file mode 100644
--- a/toolkit/mozapps/extensions/amWebInstallListener.js
+++ /dev/null
@@ -1,336 +0,0 @@
-/* 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/. */
-
-/**
- * This is a default implementation of amIWebInstallListener that should work
- * for most applications but can be overriden. It notifies the observer service
- * about blocked installs. For normal installs it pops up an install
- * confirmation when all the add-ons have been downloaded.
- */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/AddonManager.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PromptUtils", "resource://gre/modules/SharedPromptUtils.jsm");
-
-const URI_XPINSTALL_DIALOG = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
-
-// Installation can begin from any of these states
-const READY_STATES = [
- AddonManager.STATE_AVAILABLE,
- AddonManager.STATE_DOWNLOAD_FAILED,
- AddonManager.STATE_INSTALL_FAILED,
- AddonManager.STATE_CANCELLED
-];
-
-Cu.import("resource://gre/modules/Log.jsm");
-const LOGGER_ID = "addons.weblistener";
-
-// Create a new logger for use by the Addons Web Listener
-// (Requires AddonManager.jsm)
-var logger = Log.repository.getLogger(LOGGER_ID);
-
-function notifyObservers(aTopic, aBrowser, aUri, aInstalls) {
- let info = {
- browser: aBrowser,
- originatingURI: aUri,
- installs: aInstalls,
-
- QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo])
- };
- Services.obs.notifyObservers(info, aTopic, null);
-}
-
-/**
- * Creates a new installer to monitor downloads and prompt to install when
- * ready
- *
- * @param aBrowser
- * The browser that started the installations
- * @param aUrl
- * The URL that started the installations
- * @param aInstalls
- * An array of AddonInstalls
- */
-function Installer(aBrowser, aUrl, aInstalls) {
- this.browser = aBrowser;
- this.url = aUrl;
- this.downloads = aInstalls;
- this.installed = [];
-
- notifyObservers("addon-install-started", aBrowser, aUrl, aInstalls);
-
- for (let install of aInstalls) {
- install.addListener(this);
-
- // Start downloading if it hasn't already begun
- if (READY_STATES.indexOf(install.state) != -1)
- install.install();
- }
-
- this.checkAllDownloaded();
-}
-
-Installer.prototype = {
- browser: null,
- downloads: null,
- installed: null,
- isDownloading: true,
-
- /**
- * Checks if all downloads are now complete and if so prompts to install.
- */
- checkAllDownloaded() {
- // Prevent re-entrancy caused by the confirmation dialog cancelling unwanted
- // installs.
- if (!this.isDownloading)
- return;
-
- var failed = [];
- var installs = [];
-
- for (let install of this.downloads) {
- switch (install.state) {
- case AddonManager.STATE_AVAILABLE:
- case AddonManager.STATE_DOWNLOADING:
- // Exit early if any add-ons haven't started downloading yet or are
- // still downloading
- return;
- case AddonManager.STATE_DOWNLOAD_FAILED:
- failed.push(install);
- break;
- case AddonManager.STATE_DOWNLOADED:
- // App disabled items are not compatible and so fail to install
- if (install.addon.appDisabled)
- failed.push(install);
- else
- installs.push(install);
- break;
- case AddonManager.STATE_CANCELLED:
- // Just ignore cancelled downloads
- break;
- default:
- logger.warn("Download of " + install.sourceURI.spec + " in unexpected state " +
- install.state);
- }
- }
-
- this.isDownloading = false;
- this.downloads = installs;
-
- if (failed.length > 0) {
- // Stop listening and cancel any installs that are failed because of
- // compatibility reasons.
- for (let install of failed) {
- if (install.state == AddonManager.STATE_DOWNLOADED) {
- install.removeListener(this);
- install.cancel();
- }
- }
- notifyObservers("addon-install-failed", this.browser, this.url, failed);
- }
-
- // If none of the downloads were successful then exit early
- if (this.downloads.length == 0)
- return;
-
- // Check for a custom installation prompt that may be provided by the
- // applicaton
- if ("@mozilla.org/addons/web-install-prompt;1" in Cc) {
- try {
- let prompt = Cc["@mozilla.org/addons/web-install-prompt;1"].
- getService(Ci.amIWebInstallPrompt);
- prompt.confirm(this.browser, this.url, this.downloads, this.downloads.length);
- return;
- } catch (e) {}
- }
-
- if (Preferences.get("xpinstall.customConfirmationUI", false)) {
- notifyObservers("addon-install-confirmation", this.browser, this.url, this.downloads);
- return;
- }
-
- let args = {};
- args.url = this.url;
- args.installs = this.downloads;
- args.wrappedJSObject = args;
-
- try {
- Cc["@mozilla.org/base/telemetry;1"].
- getService(Ci.nsITelemetry).
- getHistogramById("SECURITY_UI").
- add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL);
- let parentWindow = null;
- if (this.browser) {
- parentWindow = this.browser.ownerDocument.defaultView;
- PromptUtils.fireDialogEvent(parentWindow, "DOMWillOpenModalDialog", this.browser);
- }
- Services.ww.openWindow(parentWindow, URI_XPINSTALL_DIALOG,
- null, "chrome,modal,centerscreen", args);
- } catch (e) {
- logger.warn("Exception showing install confirmation dialog", e);
- for (let install of this.downloads) {
- install.removeListener(this);
- // Cancel the installs, as currently there is no way to make them fail
- // from here.
- install.cancel();
- }
- notifyObservers("addon-install-cancelled", this.browser, this.url,
- this.downloads);
- }
- },
-
- /**
- * Checks if all installs are now complete and if so notifies observers.
- */
- checkAllInstalled() {
- var failed = [];
-
- for (let install of this.downloads) {
- switch (install.state) {
- case AddonManager.STATE_DOWNLOADED:
- case AddonManager.STATE_INSTALLING:
- // Exit early if any add-ons haven't started installing yet or are
- // still installing
- return;
- case AddonManager.STATE_INSTALL_FAILED:
- failed.push(install);
- break;
- }
- }
-
- this.downloads = null;
-
- if (failed.length > 0)
- notifyObservers("addon-install-failed", this.browser, this.url, failed);
-
- if (this.installed.length > 0)
- notifyObservers("addon-install-complete", this.browser, this.url, this.installed);
- this.installed = null;
- },
-
- onDownloadCancelled(aInstall) {
- aInstall.removeListener(this);
- this.checkAllDownloaded();
- },
-
- onDownloadFailed(aInstall) {
- aInstall.removeListener(this);
- this.checkAllDownloaded();
- },
-
- onDownloadEnded(aInstall) {
- this.checkAllDownloaded();
- return false;
- },
-
- onInstallCancelled(aInstall) {
- aInstall.removeListener(this);
- this.checkAllInstalled();
- },
-
- onInstallFailed(aInstall) {
- aInstall.removeListener(this);
- this.checkAllInstalled();
- },
-
- onInstallEnded(aInstall) {
- aInstall.removeListener(this);
- this.installed.push(aInstall);
-
- // If installing a theme that is disabled and can be enabled then enable it
- if (aInstall.addon.type == "theme" &&
- aInstall.addon.userDisabled == true &&
- aInstall.addon.appDisabled == false) {
- aInstall.addon.userDisabled = false;
- }
-
- this.checkAllInstalled();
- }
-};
-
-function extWebInstallListener() {
-}
-
-extWebInstallListener.prototype = {
- /**
- * @see amIWebInstallListener.idl
- */
- onWebInstallDisabled(aBrowser, aUri, aInstalls) {
- let info = {
- browser: aBrowser,
- originatingURI: aUri,
- installs: aInstalls,
-
- QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo])
- };
- Services.obs.notifyObservers(info, "addon-install-disabled", null);
- },
-
- /**
- * @see amIWebInstallListener.idl
- */
- onWebInstallOriginBlocked(aBrowser, aUri, aInstalls) {
- let info = {
- browser: aBrowser,
- originatingURI: aUri,
- installs: aInstalls,
-
- install() {
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo])
- };
- Services.obs.notifyObservers(info, "addon-install-origin-blocked", null);
-
- return false;
- },
-
- /**
- * @see amIWebInstallListener.idl
- */
- onWebInstallBlocked(aBrowser, aUri, aInstalls) {
- let info = {
- browser: aBrowser,
- originatingURI: aUri,
- installs: aInstalls,
-
- install() {
- new Installer(this.browser, this.originatingURI, this.installs);
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo])
- };
- Services.obs.notifyObservers(info, "addon-install-blocked", null);
-
- return false;
- },
-
- /**
- * @see amIWebInstallListener.idl
- */
- onWebInstallRequested(aBrowser, aUri, aInstalls) {
- new Installer(aBrowser, aUri, aInstalls);
-
- // We start the installs ourself
- return false;
- },
-
- classDescription: "XPI Install Handler",
- contractID: "@mozilla.org/addons/web-install-listener;1",
- classID: Components.ID("{0f38e086-89a3-40a5-8ffc-9b694de1d04a}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallListener,
- Ci.amIWebInstallListener2])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([extWebInstallListener]);
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -1340,40 +1340,24 @@ var gViewController = {
fp.appendFilter(gStrings.ext.GetStringFromName("installFromFile.filterName"),
"*.xpi;*.jar");
fp.appendFilters(nsIFilePicker.filterAll);
} catch (e) { }
if (fp.show() != nsIFilePicker.returnOK)
return;
- var files = fp.files;
- var installs = [];
-
- function buildNextInstall() {
- if (!files.hasMoreElements()) {
- if (installs.length > 0) {
- // Display the normal install confirmation for the installs
- let webInstaller = Cc["@mozilla.org/addons/web-install-listener;1"].
- getService(Ci.amIWebInstallListener);
- webInstaller.onWebInstallRequested(getBrowserElement(),
- document.documentURIObject,
- installs);
- }
- return;
- }
-
- var file = files.getNext();
- AddonManager.getInstallForFile(file, function(aInstall) {
- installs.push(aInstall);
- buildNextInstall();
+ let browser = getBrowserElement();
+ let files = fp.files;
+ while (files.hasMoreElements()) {
+ let file = files.getNext();
+ AddonManager.getInstallForFile(file, install => {
+ AddonManager.installAddonFromAOM(browser, document.documentURI, install);
});
}
-
- buildNextInstall();
}
},
cmd_debugAddons: {
isEnabled() {
return true;
},
doCommand() {
@@ -3884,59 +3868,36 @@ var gDragDrop = {
var types = aEvent.dataTransfer.types;
if (types.includes("text/uri-list") ||
types.includes("text/x-moz-url") ||
types.includes("application/x-moz-file"))
aEvent.preventDefault();
},
onDrop(aEvent) {
- var dataTransfer = aEvent.dataTransfer;
- var urls = [];
-
- // Convert every dropped item into a url
+ let dataTransfer = aEvent.dataTransfer;
+ let browser = getBrowserElement();
+
+ // Convert every dropped item into a url and install it
for (var i = 0; i < dataTransfer.mozItemCount; i++) {
- var url = dataTransfer.mozGetDataAt("text/uri-list", i);
- if (url) {
- urls.push(url);
- continue;
+ let url = dataTransfer.mozGetDataAt("text/uri-list", i);
+ if (!url) {
+ url = dataTransfer.mozGetDataAt("text/x-moz-url", i);
}
-
- url = dataTransfer.mozGetDataAt("text/x-moz-url", i);
if (url) {
- urls.push(url.split("\n")[0]);
- continue;
+ url = url.split("\n")[0];
+ } else {
+ let file = dataTransfer.mozGetDataAt("application/x-moz-file", i);
+ if (file) {
+ url = Services.io.newFileURI(file).spec;
+ }
}
- var file = dataTransfer.mozGetDataAt("application/x-moz-file", i);
- if (file) {
- urls.push(Services.io.newFileURI(file).spec);
- continue;
+ if (url) {
+ AddonManager.getInstallForURL(url, install => {
+ AddonManager.installAddonFromAOM(browser, document.documentURI, install);
+ }, "application/x-xpinstall");
}
}
- var pos = 0;
- var installs = [];
-
- function buildNextInstall() {
- if (pos == urls.length) {
- if (installs.length > 0) {
- // Display the normal install confirmation for the installs
- let webInstaller = Cc["@mozilla.org/addons/web-install-listener;1"].
- getService(Ci.amIWebInstallListener);
- webInstaller.onWebInstallRequested(getBrowserElement(),
- document.documentURIObject,
- installs);
- }
- return;
- }
-
- AddonManager.getInstallForURL(urls[pos++], function(aInstall) {
- installs.push(aInstall);
- buildNextInstall();
- }, "application/x-xpinstall");
- }
-
- buildNextInstall();
-
aEvent.preventDefault();
}
};
--- a/toolkit/mozapps/extensions/extensions.manifest
+++ b/toolkit/mozapps/extensions/extensions.manifest
@@ -8,18 +8,16 @@ category update-timer nsBlocklistService
#ifndef MOZ_WIDGET_GONK
component {4399533d-08d1-458c-a87a-235f74451cfa} addonManager.js
contract @mozilla.org/addons/integration;1 {4399533d-08d1-458c-a87a-235f74451cfa}
#ifndef MOZ_WIDGET_ANDROID
category update-timer addonManager @mozilla.org/addons/integration;1,getService,addon-background-update-timer,extensions.update.interval,86400
#endif
component {7beb3ba8-6ec3-41b4-b67c-da89b8518922} amContentHandler.js
contract @mozilla.org/uriloader/content-handler;1?type=application/x-xpinstall {7beb3ba8-6ec3-41b4-b67c-da89b8518922}
-component {0f38e086-89a3-40a5-8ffc-9b694de1d04a} amWebInstallListener.js
-contract @mozilla.org/addons/web-install-listener;1 {0f38e086-89a3-40a5-8ffc-9b694de1d04a}
component {9df8ef2b-94da-45c9-ab9f-132eb55fddf1} amInstallTrigger.js
contract @mozilla.org/addons/installtrigger;1 {9df8ef2b-94da-45c9-ab9f-132eb55fddf1}
category JavaScript-global-property InstallTrigger @mozilla.org/addons/installtrigger;1
#ifndef MOZ_WIDGET_ANDROID
category addon-provider-module PluginProvider resource://gre/modules/addons/PluginProvider.jsm
#endif
category addon-provider-module GMPProvider resource://gre/modules/addons/GMPProvider.jsm
#endif
--- a/toolkit/mozapps/extensions/moz.build
+++ b/toolkit/mozapps/extensions/moz.build
@@ -10,27 +10,26 @@ if CONFIG['MOZ_BUILD_APP'] == 'mobile/an
DEFINES['MOZ_FENNEC'] = True
DIRS += ['internal']
TEST_DIRS += ['test']
XPIDL_SOURCES += [
'amIAddonManager.idl',
'amIAddonPathService.idl',
- 'amIWebInstallListener.idl',
+ 'amIWebInstallPrompt.idl',
]
XPIDL_MODULE = 'extensions'
EXTRA_COMPONENTS += [
'addonManager.js',
'amContentHandler.js',
'amInstallTrigger.js',
'amWebAPI.js',
- 'amWebInstallListener.js',
'nsBlocklistService.js',
'nsBlocklistServiceContent.js',
]
EXTRA_PP_COMPONENTS += [
'extensions.manifest',
]
--- a/toolkit/mozapps/extensions/test/browser/browser_bug567127.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug567127.js
@@ -3,134 +3,104 @@
*/
// Tests bug 567127 - Add install button to the add-ons manager
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
var gManagerWindow;
-var gSawInstallNotification = false;
-// This listens for the next opened window and checks it is of the right url.
-// opencallback is called when the new window is fully loaded
-// closecallback is called when the window is closed
-function WindowOpenListener(url, opencallback, closecallback) {
- this.url = url;
- this.opencallback = opencallback;
- this.closecallback = closecallback;
-
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- wm.addListener(this);
-}
-
-WindowOpenListener.prototype = {
- url: null,
- opencallback: null,
- closecallback: null,
- window: null,
- domwindow: null,
+function checkInstallConfirmation(...urls) {
+ return new Promise(resolve => {
+ let nurls = urls.length;
- handleEvent(event) {
- is(this.domwindow.document.location.href, this.url, "Should have opened the correct window");
+ let notificationCount = 0;
+ let observer = {
+ observe: function(aSubject, aTopic, aData) {
+ var installInfo = aSubject.wrappedJSObject;
+ if (gTestInWindow)
+ is(installInfo.browser, null, "Notification should have a null browser");
+ else
+ isnot(installInfo.browser, null, "Notification should have non-null browser");
+ notificationCount++;
+ }
+ };
+ Services.obs.addObserver(observer, "addon-install-started", false);
- this.domwindow.removeEventListener("load", this, false);
- // Allow any other load handlers to execute
- var self = this;
- executeSoon(function() { self.opencallback(self.domwindow); } );
- },
+ let windows = new Set();
- onWindowTitleChange(window, title) {
- },
+ function handleDialog(window) {
+ let list = window.document.getElementById("itemList");
+ is(list.childNodes.length, 1, "Should be 1 install");
+ let idx = urls.indexOf(list.children[0].url);
+ isnot(idx, -1, "Install target is an expected url");
+ urls.splice(idx, 1);
- onOpenWindow(window) {
- if (this.window)
- return;
+ window.document.documentElement.cancelDialog();
+ }
- this.window = window;
- this.domwindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindow);
- this.domwindow.addEventListener("load", this, false);
- },
+ let listener = {
+ handleEvent(event) {
+ let window = event.currentTarget;
+ is(window.document.location.href, INSTALL_URI, "Should have opened the correct window");
- onCloseWindow(window) {
- if (this.window != window)
- return;
+ executeSoon(() => handleDialog(window));
+ },
+
+ onWindowTitleChange() { },
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- wm.removeListener(this);
- this.opencallback = null;
- this.window = null;
- this.domwindow = null;
+ onOpenWindow(window) {
+ windows.add(window);
+ let domwindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow);
+ domwindow.addEventListener("load", this, false, {once: true});
+ },
- // Let the window close complete
- executeSoon(this.closecallback);
- this.closecallback = null;
- }
-};
-
+ onCloseWindow(window) {
+ if (!windows.has(window)) {
+ return;
+ }
+ windows.delete(window);
-var gInstallNotificationObserver = {
- observe(aSubject, aTopic, aData) {
- var installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
- if (gTestInWindow)
- is(installInfo.browser, null, "Notification should have a null browser");
- else
- isnot(installInfo.browser, null, "Notification should have non-null browser");
- gSawInstallNotification = true;
- Services.obs.removeObserver(this, "addon-install-started");
- }
-};
+ if (windows.size > 0) {
+ return;
+ }
+ is(urls.length, 0, "Saw install dialogs for all expected urls");
+
+ let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Ci.nsIWindowMediator);
+ wm.removeListener(listener);
-function test_confirmation(aWindow, aExpectedURLs) {
- var list = aWindow.document.getElementById("itemList");
- is(list.childNodes.length, aExpectedURLs.length, "Should be the right number of installs");
+ is(notificationCount, nurls, `Saw ${nurls} addon-install-started notifications`);
+ Services.obs.removeObserver(observer, "addon-install-started");
- for (let url of aExpectedURLs) {
- let found = false;
- for (let node of list.children) {
- if (node.url == url) {
- found = true;
- break;
+ resolve();
}
- }
- ok(found, "Should have seen " + url + " in the list");
- }
+ };
- aWindow.document.documentElement.cancelDialog();
+ let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Ci.nsIWindowMediator);
+ wm.addListener(listener);
+ });
}
add_task(function* test_install_from_file() {
gManagerWindow = yield open_manager("addons://list/extension");
var filePaths = [
get_addon_file_url("browser_bug567127_1.xpi"),
get_addon_file_url("browser_bug567127_2.xpi")
];
MockFilePicker.returnFiles = filePaths.map(aPath => aPath.file);
- Services.obs.addObserver(gInstallNotificationObserver,
- "addon-install-started", false);
-
// Set handler that executes the core test after the window opens,
// and resolves the promise when the window closes
- let pInstallURIClosed = new Promise((resolve, reject) => {
- new WindowOpenListener(INSTALL_URI, function(aWindow) {
- try {
- test_confirmation(aWindow, filePaths.map(aPath => aPath.spec));
- } catch (e) {
- reject(e);
- }
- }, resolve);
- });
+ let pInstallURIClosed = checkInstallConfirmation(...filePaths.map(path => path.spec));
gManagerWindow.gViewController.doCommand("cmd_installFromFile");
yield pInstallURIClosed;
- is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
-
MockFilePicker.cleanup();
yield close_manager(gManagerWindow);
});
--- a/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js
@@ -11,224 +11,166 @@
// Instead of loading EventUtils.js into the test scope in browser-test.js for all tests,
// we only need EventUtils.js for a few files which is why we are using loadSubScript.
var gManagerWindow;
var EventUtils = {};
this._scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-// This listens for the next opened window and checks it is of the right url.
-// opencallback is called when the new window is fully loaded
-// closecallback is called when the window is closed
-function WindowOpenListener(url, opencallback, closecallback) {
- this.url = url;
- this.opencallback = opencallback;
- this.closecallback = closecallback;
+function checkInstallConfirmation(...urls) {
+ let nurls = urls.length;
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- wm.addListener(this);
-}
+ let notificationCount = 0;
+ let observer = {
+ observe: function(aSubject, aTopic, aData) {
+ var installInfo = aSubject.wrappedJSObject;
+ if (gTestInWindow)
+ is(installInfo.browser, null, "Notification should have a null browser");
+ else
+ isnot(installInfo.browser, null, "Notification should have non-null browser");
+ notificationCount++;
+ }
+ };
+ Services.obs.addObserver(observer, "addon-install-started", false);
+
+ let windows = new Set();
-WindowOpenListener.prototype = {
- url: null,
- opencallback: null,
- closecallback: null,
- window: null,
- domwindow: null,
-
- handleEvent(event) {
- is(this.domwindow.document.location.href, this.url, "Should have opened the correct window");
+ function handleDialog(window) {
+ let list = window.document.getElementById("itemList");
+ is(list.childNodes.length, 1, "Should be 1 install");
+ let idx = urls.indexOf(list.children[0].url);
+ isnot(idx, -1, "Install target is an expected url");
+ urls.splice(idx, 1);
- this.domwindow.removeEventListener("load", this, false);
- // Allow any other load handlers to execute
- var self = this;
- executeSoon(function() { self.opencallback(self.domwindow); } );
- },
+ window.document.documentElement.cancelDialog();
+ }
- onWindowTitleChange(window, title) {
- },
+ let listener = {
+ handleEvent(event) {
+ let window = event.currentTarget;
+ is(window.document.location.href, INSTALL_URI, "Should have opened the correct window");
- onOpenWindow(window) {
- if (this.window)
- return;
+ executeSoon(() => handleDialog(window));
+ },
- this.window = window;
- this.domwindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindow);
- this.domwindow.addEventListener("load", this, false);
- },
+ onWindowTitleChange() { },
- onCloseWindow(window) {
- if (this.window != window)
- return;
+ onOpenWindow(window) {
+ windows.add(window);
+ let domwindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow);
+ domwindow.addEventListener("load", this, false, {once: true});
+ },
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- wm.removeListener(this);
- this.opencallback = null;
- this.window = null;
- this.domwindow = null;
+ onCloseWindow(window) {
+ if (!windows.has(window)) {
+ return;
+ }
+ windows.delete(window);
- // Let the window close complete
- executeSoon(this.closecallback);
- this.closecallback = null;
- }
-};
+ if (windows.size > 0) {
+ return;
+ }
+
+ is(urls.length, 0, "Saw install dialogs for all expected urls");
+
+ let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Ci.nsIWindowMediator);
+ wm.removeListener(listener);
-var gSawInstallNotification = false;
-var gInstallNotificationObserver = {
- observe(aSubject, aTopic, aData) {
- var installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
- if (gTestInWindow)
- is(installInfo.browser, null, "Notification should have a null browser");
- else
- isnot(installInfo.browser, null, "Notification should have non-null browser");
- gSawInstallNotification = true;
- Services.obs.removeObserver(this, "addon-install-started");
- }
-};
+ is(notificationCount, nurls, `Saw ${nurls} addon-install-started notifications`);
+ Services.obs.removeObserver(observer, "addon-install-started");
+ executeSoon(run_next_test);
+ }
+ };
+
+ let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Ci.nsIWindowMediator);
+ wm.addListener(listener);
+}
function test() {
waitForExplicitFinish();
open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow;
run_next_test();
});
}
function end_test() {
close_manager(gManagerWindow, function() {
finish();
});
}
-function test_confirmation(aWindow, aExpectedURLs) {
- var list = aWindow.document.getElementById("itemList");
- is(list.childNodes.length, aExpectedURLs.length, "Should be the right number of installs");
-
- for (let url of aExpectedURLs) {
- let found = false;
- for (let node of list.children) {
- if (node.url == url) {
- found = true;
- break;
- }
- }
- ok(found, "Should have seen " + url + " in the list");
- }
-
- aWindow.document.documentElement.cancelDialog();
-}
-
// Simulates dropping a URL onto the manager
add_test(function() {
var url = TESTROOT + "addons/browser_dragdrop1.xpi";
- Services.obs.addObserver(gInstallNotificationObserver,
- "addon-install-started", false);
-
- new WindowOpenListener(INSTALL_URI, function(aWindow) {
- test_confirmation(aWindow, [url]);
- }, function() {
- is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
- run_next_test();
- });
+ checkInstallConfirmation(url);
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "text/x-moz-url", data: url}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping a file onto the manager
add_test(function() {
var fileurl = get_addon_file_url("browser_dragdrop1.xpi");
- Services.obs.addObserver(gInstallNotificationObserver,
- "addon-install-started", false);
-
- new WindowOpenListener(INSTALL_URI, function(aWindow) {
- test_confirmation(aWindow, [fileurl.spec]);
- }, function() {
- is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
- run_next_test();
- });
+ checkInstallConfirmation(fileurl.spec);
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "application/x-moz-file", data: fileurl.file}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping two urls onto the manager
add_test(function() {
var url1 = TESTROOT + "addons/browser_dragdrop1.xpi";
var url2 = TESTROOT2 + "addons/browser_dragdrop2.xpi";
- Services.obs.addObserver(gInstallNotificationObserver,
- "addon-install-started", false);
-
- new WindowOpenListener(INSTALL_URI, function(aWindow) {
- test_confirmation(aWindow, [url1, url2]);
- }, function() {
- is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
- run_next_test();
- });
+ checkInstallConfirmation(url1, url2);
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "text/x-moz-url", data: url1}],
[{type: "text/x-moz-url", data: url2}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping two files onto the manager
add_test(function() {
var fileurl1 = get_addon_file_url("browser_dragdrop1.xpi");
var fileurl2 = get_addon_file_url("browser_dragdrop2.xpi");
- Services.obs.addObserver(gInstallNotificationObserver,
- "addon-install-started", false);
-
- new WindowOpenListener(INSTALL_URI, function(aWindow) {
- test_confirmation(aWindow, [fileurl1.spec, fileurl2.spec]);
- }, function() {
- is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
- run_next_test();
- });
+ checkInstallConfirmation(fileurl1.spec, fileurl2.spec);
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "application/x-moz-file", data: fileurl1.file}],
[{type: "application/x-moz-file", data: fileurl2.file}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping a file and a url onto the manager (weird, but should still work)
add_test(function() {
var url = TESTROOT + "addons/browser_dragdrop1.xpi";
var fileurl = get_addon_file_url("browser_dragdrop2.xpi");
- Services.obs.addObserver(gInstallNotificationObserver,
- "addon-install-started", false);
-
- new WindowOpenListener(INSTALL_URI, function(aWindow) {
- test_confirmation(aWindow, [url, fileurl.spec]);
- }, function() {
- is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
- run_next_test();
- });
+ checkInstallConfirmation(url, fileurl.spec);
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "text/x-moz-url", data: url}],
[{type: "application/x-moz-file", data: fileurl.file}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
--- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js
@@ -469,24 +469,20 @@ function Pmanual_update(aVersion) {
let completePromises = [];
for (let install of installs) {
completePromises.push(new Promise(resolve => {
install.addListener({
onDownloadCancelled: resolve,
onInstallEnded: resolve
})
}));
+
+ AddonManager.installAddonFromAOM(null, null, install);
}
- // Use the default web installer to cancel/allow installs based on whether
- // the add-on is valid or not.
- let webInstaller = Cc["@mozilla.org/addons/web-install-listener;1"]
- .getService(Ci.amIWebInstallListener);
- webInstaller.onWebInstallRequested(null, null, installs);
-
return Promise.all(completePromises);
});
}
// Checks that an add-ons properties match expected values
function check_addon(aAddon, aExpectedVersion, aExpectedUserDisabled,
aExpectedSoftDisabled, aExpectedState) {
do_check_neq(aAddon, null);
--- a/toolkit/mozapps/extensions/test/xpinstall/head.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/head.js
@@ -370,17 +370,17 @@ var Harness = {
checkTestEnded() {
if (--this.pendingCount == 0 && !this.waitingForEvent)
this.endTest();
},
// nsIObserver
observe(subject, topic, data) {
- var installInfo = subject.QueryInterface(Components.interfaces.amIWebInstallInfo);
+ var installInfo = subject.wrappedJSObject;
switch (topic) {
case "addon-install-started":
is(this.runningInstalls.length, installInfo.installs.length,
"Should have seen the expected number of installs started");
break;
case "addon-install-disabled":
this.installDisabled(installInfo);
break;