mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 10:08:41 +00:00
Bug 1084558: Switch the web installer interfaces to use browsers instead of DOM windows. r=Unfocused
This commit is contained in:
parent
292b0666f0
commit
a7d0217d78
@ -32,20 +32,9 @@ const gXPInstallObserver = {
|
||||
{
|
||||
var brandBundle = document.getElementById("bundle_brand");
|
||||
var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo);
|
||||
var winOrBrowser = installInfo.originator;
|
||||
var browser = installInfo.browser;
|
||||
|
||||
var browser;
|
||||
try {
|
||||
var shell = winOrBrowser.QueryInterface(Components.interfaces.nsIDOMWindow)
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShell);
|
||||
browser = this._getBrowser(shell);
|
||||
} catch (e) {
|
||||
browser = winOrBrowser;
|
||||
}
|
||||
// Note that the above try/catch will pass through dead object proxies and
|
||||
// other degenerate objects. Make sure the browser is bonafide.
|
||||
// Make sure the browser is still alive.
|
||||
if (!browser || gBrowser.browsers.indexOf(browser) == -1)
|
||||
return;
|
||||
|
||||
|
@ -1180,7 +1180,6 @@
|
||||
// Cache these as cancelling the installs will remove this
|
||||
// notification which will drop these references
|
||||
let browser = this.notification.browser;
|
||||
let contentWindow = this.notification.options.contentWindow;
|
||||
let sourceURI = this.notification.options.sourceURI;
|
||||
|
||||
let installs = this.notification.options.installs;
|
||||
@ -1206,7 +1205,7 @@
|
||||
callback: function() {
|
||||
let weblistener = Cc["@mozilla.org/addons/web-install-listener;1"].
|
||||
getService(Ci.amIWebInstallListener);
|
||||
if (weblistener.onWebInstallRequested(contentWindow, sourceURI,
|
||||
if (weblistener.onWebInstallRequested(browser, sourceURI,
|
||||
installs, installs.length)) {
|
||||
installs.forEach(function(aInstall) {
|
||||
aInstall.install();
|
||||
|
@ -6020,8 +6020,7 @@ var XPInstallObserver = {
|
||||
break;
|
||||
case "addon-install-blocked":
|
||||
let installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
|
||||
let win = installInfo.originator;
|
||||
let tab = BrowserApp.getTabForWindow(win.top);
|
||||
let tab = BrowserApp.getTabForBrowser(installInfo.browser);
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
|
@ -18,7 +18,7 @@ WebInstallPrompt.prototype = {
|
||||
classID: Components.ID("{c1242012-27d8-477e-a0f1-0b098ffc329b}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallPrompt]),
|
||||
|
||||
confirm: function(aWindow, aURL, aInstalls) {
|
||||
confirm: function(aBrowser, aURL, aInstalls) {
|
||||
let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
|
||||
|
||||
let prompt = Services.prompt;
|
||||
@ -27,7 +27,7 @@ WebInstallPrompt.prototype = {
|
||||
let button = bundle.GetStringFromName("addonsConfirmInstall.install");
|
||||
|
||||
aInstalls.forEach(function(install) {
|
||||
let result = (prompt.confirmEx(aWindow, title, install.name, flags, button, null, null, null, {value: false}) == 0);
|
||||
let result = (prompt.confirmEx(aBrowser.contentWindow, title, install.name, flags, button, null, null, null, {value: false}) == 0);
|
||||
if (result)
|
||||
install.install();
|
||||
else
|
||||
|
@ -1628,7 +1628,7 @@ var AddonManagerInternal = {
|
||||
*/
|
||||
getInstallForURL: function AMI_getInstallForURL(aUrl, aCallback, aMimetype,
|
||||
aHash, aName, aIcons,
|
||||
aVersion, aLoadGroup) {
|
||||
aVersion, aBrowser) {
|
||||
if (!gStarted)
|
||||
throw Components.Exception("AddonManager is not initialized",
|
||||
Cr.NS_ERROR_NOT_INITIALIZED);
|
||||
@ -1667,15 +1667,15 @@ var AddonManagerInternal = {
|
||||
throw Components.Exception("aVersion must be a string or null",
|
||||
Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (aLoadGroup && (!(aLoadGroup instanceof Ci.nsILoadGroup)))
|
||||
throw Components.Exception("aLoadGroup must be a nsILoadGroup or null",
|
||||
if (aBrowser && (!(aBrowser instanceof Ci.nsIDOMElement)))
|
||||
throw Components.Exception("aBrowser must be a nsIDOMElement or null",
|
||||
Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
let providers = this.providers.slice(0);
|
||||
for (let provider of providers) {
|
||||
if (callProvider(provider, "supportsMimetype", false, aMimetype)) {
|
||||
callProviderAsync(provider, "getInstallForURL",
|
||||
aUrl, aHash, aName, aIcons, aVersion, aLoadGroup,
|
||||
aUrl, aHash, aName, aIcons, aVersion, aBrowser,
|
||||
function getInstallForURL_safeCall(aInstall) {
|
||||
safeCall(aCallback, aInstall);
|
||||
});
|
||||
@ -1878,15 +1878,15 @@ var AddonManagerInternal = {
|
||||
*
|
||||
* @param aMimetype
|
||||
* The mimetype of add-ons being installed
|
||||
* @param aSource
|
||||
* The optional nsIDOMWindow that started the installs
|
||||
* @param aBrowser
|
||||
* The optional browser element that started the installs
|
||||
* @param aURI
|
||||
* The optional nsIURI that started the installs
|
||||
* @param aInstalls
|
||||
* The array of AddonInstalls to be installed
|
||||
*/
|
||||
installAddonsFromWebpage: function AMI_installAddonsFromWebpage(aMimetype,
|
||||
aSource,
|
||||
aBrowser,
|
||||
aURI,
|
||||
aInstalls) {
|
||||
if (!gStarted)
|
||||
@ -1897,8 +1897,8 @@ var AddonManagerInternal = {
|
||||
throw Components.Exception("aMimetype must be a non-empty string",
|
||||
Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (aSource && !(aSource instanceof Ci.nsIDOMWindow) && !(aSource instanceof Ci.nsIDOMNode))
|
||||
throw Components.Exception("aSource must be a nsIDOMWindow, a XUL element, or null",
|
||||
if (aBrowser && !(aBrowser instanceof Ci.nsIDOMElement))
|
||||
throw Components.Exception("aSource must be a nsIDOMElement, or null",
|
||||
Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (aURI && !(aURI instanceof Ci.nsIURI))
|
||||
@ -1922,18 +1922,18 @@ var AddonManagerInternal = {
|
||||
getService(Ci.amIWebInstallListener);
|
||||
|
||||
if (!this.isInstallEnabled(aMimetype, aURI)) {
|
||||
weblistener.onWebInstallDisabled(aSource, aURI, aInstalls,
|
||||
weblistener.onWebInstallDisabled(aBrowser, aURI, aInstalls,
|
||||
aInstalls.length);
|
||||
}
|
||||
else if (!this.isInstallAllowed(aMimetype, aURI)) {
|
||||
if (weblistener.onWebInstallBlocked(aSource, aURI, aInstalls,
|
||||
if (weblistener.onWebInstallBlocked(aBrowser, aURI, aInstalls,
|
||||
aInstalls.length)) {
|
||||
aInstalls.forEach(function(aInstall) {
|
||||
aInstall.install();
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (weblistener.onWebInstallRequested(aSource, aURI, aInstalls,
|
||||
else if (weblistener.onWebInstallRequested(aBrowser, aURI, aInstalls,
|
||||
aInstalls.length)) {
|
||||
aInstalls.forEach(function(aInstall) {
|
||||
aInstall.install();
|
||||
@ -2720,9 +2720,9 @@ this.AddonManager = {
|
||||
|
||||
getInstallForURL: function AM_getInstallForURL(aUrl, aCallback, aMimetype,
|
||||
aHash, aName, aIcons,
|
||||
aVersion, aLoadGroup) {
|
||||
aVersion, aBrowser) {
|
||||
AddonManagerInternal.getInstallForURL(aUrl, aCallback, aMimetype, aHash,
|
||||
aName, aIcons, aVersion, aLoadGroup);
|
||||
aName, aIcons, aVersion, aBrowser);
|
||||
},
|
||||
|
||||
getInstallForFile: function AM_getInstallForFile(aFile, aCallback, aMimetype) {
|
||||
@ -2787,9 +2787,9 @@ this.AddonManager = {
|
||||
return AddonManagerInternal.isInstallAllowed(aType, aUri);
|
||||
},
|
||||
|
||||
installAddonsFromWebpage: function AM_installAddonsFromWebpage(aType, aSource,
|
||||
installAddonsFromWebpage: function AM_installAddonsFromWebpage(aType, aBrowser,
|
||||
aUri, aInstalls) {
|
||||
AddonManagerInternal.installAddonsFromWebpage(aType, aSource, aUri, aInstalls);
|
||||
AddonManagerInternal.installAddonsFromWebpage(aType, aBrowser, aUri, aInstalls);
|
||||
},
|
||||
|
||||
addManagerListener: function AM_addManagerListener(aListener) {
|
||||
|
@ -74,7 +74,7 @@ amManager.prototype = {
|
||||
* @see amIWebInstaller.idl
|
||||
*/
|
||||
installAddonsFromWebpage: function AMC_installAddonsFromWebpage(aMimetype,
|
||||
aOriginator,
|
||||
aBrowser,
|
||||
aReferer, aUris,
|
||||
aHashes, aNames,
|
||||
aIcons, aCallback) {
|
||||
@ -87,21 +87,10 @@ amManager.prototype = {
|
||||
retval = false;
|
||||
}
|
||||
|
||||
let loadGroup = null;
|
||||
|
||||
try {
|
||||
loadGroup = aOriginator.QueryInterface(Ci.nsIDOMWindow)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocumentLoader).loadGroup;
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
|
||||
let installs = [];
|
||||
function buildNextInstall() {
|
||||
if (aUris.length == 0) {
|
||||
AddonManager.installAddonsFromWebpage(aMimetype, aOriginator, aReferer, installs);
|
||||
AddonManager.installAddonsFromWebpage(aMimetype, aBrowser, aReferer, installs);
|
||||
return;
|
||||
}
|
||||
let uri = aUris.shift();
|
||||
@ -144,7 +133,7 @@ amManager.prototype = {
|
||||
aCallback.onInstallEnded(uri, UNSUPPORTED_TYPE);
|
||||
}
|
||||
buildNextInstall();
|
||||
}, aMimetype, aHashes.shift(), aNames.shift(), aIcons.shift(), null, loadGroup);
|
||||
}, aMimetype, aHashes.shift(), aNames.shift(), aIcons.shift(), null, aBrowser);
|
||||
}
|
||||
buildNextInstall();
|
||||
|
||||
@ -183,12 +172,8 @@ amManager.prototype = {
|
||||
};
|
||||
}
|
||||
|
||||
// If aMessage.objects.window exists, then we're same-process and we
|
||||
// can target any modal prompts more correctly. Otherwise, we use the
|
||||
// browser element for the remote browser as the best bet.
|
||||
let originator = aMessage.objects.window || aMessage.target;
|
||||
return this.installAddonsFromWebpage(payload.mimetype,
|
||||
originator, referer, payload.uris, payload.hashes,
|
||||
aMessage.target, referer, payload.uris, payload.hashes,
|
||||
payload.names, payload.icons, callback);
|
||||
}
|
||||
}
|
||||
|
@ -66,9 +66,12 @@ amContentHandler.prototype = {
|
||||
Ci.nsIURI);
|
||||
}
|
||||
|
||||
let browser = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
let manager = Cc["@mozilla.org/addons/integration;1"].
|
||||
getService(Ci.amIWebInstaller);
|
||||
manager.installAddonsFromWebpage(aMimetype, window, referer, [uri.spec],
|
||||
manager.installAddonsFromWebpage(aMimetype, browser, referer, [uri.spec],
|
||||
[null], [null], [null], null, 1);
|
||||
}
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
interface nsIDOMElement;
|
||||
interface nsIURI;
|
||||
interface nsIVariant;
|
||||
|
||||
@ -13,10 +13,10 @@ interface nsIVariant;
|
||||
* amIWebInstallListener to communicate with the running application and allow
|
||||
* it to warn the user about blocked installs and start the installs running.
|
||||
*/
|
||||
[scriptable, uuid(502f206a-c6b4-4e98-b442-e335792e2594)]
|
||||
[scriptable, uuid(fa0b47a3-f819-47ac-bc66-4bd1d7f67b1d)]
|
||||
interface amIWebInstallInfo : nsISupports
|
||||
{
|
||||
readonly attribute nsISupports originator;
|
||||
readonly attribute nsIDOMElement browser;
|
||||
readonly attribute nsIURI originatingURI;
|
||||
readonly attribute nsIVariant installs;
|
||||
|
||||
@ -32,14 +32,14 @@ interface amIWebInstallInfo : nsISupports
|
||||
* dialog when add-ons are ready to install and uses the observer service to
|
||||
* notify when installations are blocked.
|
||||
*/
|
||||
[scriptable, uuid(a5503979-89c8-441e-9e4a-321df379c172)]
|
||||
[scriptable, uuid(d9240d4b-6b3a-4cad-b402-de6c93337e0c)]
|
||||
interface amIWebInstallListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called when installation by websites is currently disabled.
|
||||
*
|
||||
* @param aOriginator
|
||||
* The window or browser that triggered the installs
|
||||
* @param aBrowser
|
||||
* The browser that triggered the installs
|
||||
* @param aUri
|
||||
* The URI of the site that triggered the installs
|
||||
* @param aInstalls
|
||||
@ -47,7 +47,7 @@ interface amIWebInstallListener : nsISupports
|
||||
* @param aCount
|
||||
* The number of AddonInstalls
|
||||
*/
|
||||
void onWebInstallDisabled(in nsISupports aOriginator, in nsIURI aUri,
|
||||
void onWebInstallDisabled(in nsIDOMElement aBrowser, in nsIURI aUri,
|
||||
[array, size_is(aCount)] in nsIVariant aInstalls,
|
||||
[optional] in uint32_t aCount);
|
||||
|
||||
@ -55,8 +55,8 @@ interface amIWebInstallListener : nsISupports
|
||||
* Called when the website is not allowed to directly prompt the user to
|
||||
* install add-ons.
|
||||
*
|
||||
* @param aWindow
|
||||
* The window or browser that triggered the installs
|
||||
* @param aBrowser
|
||||
* The browser that triggered the installs
|
||||
* @param aUri
|
||||
* The URI of the site that triggered the installs
|
||||
* @param aInstalls
|
||||
@ -65,15 +65,15 @@ interface amIWebInstallListener : nsISupports
|
||||
* The number of AddonInstalls
|
||||
* @return true if the caller should start the installs
|
||||
*/
|
||||
boolean onWebInstallBlocked(in nsISupports aOriginator, in nsIURI aUri,
|
||||
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 aWindow
|
||||
* The window or browser that triggered the installs
|
||||
* @param aBrowser
|
||||
* The browser that triggered the installs
|
||||
* @param aUri
|
||||
* The URI of the site that triggered the installs
|
||||
* @param aInstalls
|
||||
@ -82,7 +82,7 @@ interface amIWebInstallListener : nsISupports
|
||||
* The number of AddonInstalls
|
||||
* @return true if the caller should start the installs
|
||||
*/
|
||||
boolean onWebInstallRequested(in nsISupports aOriginator, in nsIURI aUri,
|
||||
boolean onWebInstallRequested(in nsIDOMElement aBrowser, in nsIURI aUri,
|
||||
[array, size_is(aCount)] in nsIVariant aInstalls,
|
||||
[optional] in uint32_t aCount);
|
||||
};
|
||||
@ -92,14 +92,14 @@ interface amIWebInstallListener : nsISupports
|
||||
* amIWebInstallInfo to display a confirmation UI to the user before running
|
||||
* installs.
|
||||
*/
|
||||
[scriptable, uuid(c5529918-4291-4b56-bd46-e9268900f2a3)]
|
||||
[scriptable, uuid(386906f1-4d18-45bf-bc81-5dcd68e42c3b)]
|
||||
interface amIWebInstallPrompt : nsISupports
|
||||
{
|
||||
/**
|
||||
* Get a confirmation that the user wants to start the installs.
|
||||
*
|
||||
* @param aWindow
|
||||
* The window that triggered the installs
|
||||
* @param aBrowser
|
||||
* The browser that triggered the installs
|
||||
* @param aUri
|
||||
* The URI of the site that triggered the installs
|
||||
* @param aInstalls
|
||||
@ -107,7 +107,7 @@ interface amIWebInstallPrompt : nsISupports
|
||||
* @param aCount
|
||||
* The number of AddonInstalls
|
||||
*/
|
||||
void confirm(in nsIDOMWindow aWindow, in nsIURI aUri,
|
||||
void confirm(in nsIDOMElement aBrowser, in nsIURI aUri,
|
||||
[array, size_is(aCount)] in nsIVariant aInstalls,
|
||||
[optional] in uint32_t aCount);
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
interface nsIDOMElement;
|
||||
interface nsIVariant;
|
||||
interface nsIURI;
|
||||
|
||||
@ -32,7 +32,7 @@ interface amIInstallCallback : nsISupports
|
||||
/**
|
||||
* This interface is used to allow webpages to start installing add-ons.
|
||||
*/
|
||||
[scriptable, uuid(8565a9c7-daf9-4af5-aae0-b272afcbccaa)]
|
||||
[scriptable, uuid(658d6c09-15e0-4688-bee8-8551030472a9)]
|
||||
interface amIWebInstaller : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -51,9 +51,8 @@ interface amIWebInstaller : nsISupports
|
||||
*
|
||||
* @param aMimetype
|
||||
* The mimetype for the add-ons
|
||||
* @param aOriginator
|
||||
* If not e10s, the window installing the add-ons, otherwise the
|
||||
* browser installing the add-ons.
|
||||
* @param aBrowser
|
||||
* The browser installing the add-ons.
|
||||
* @param aReferer
|
||||
* The URI for the webpage installing the add-ons
|
||||
* @param aUris
|
||||
@ -72,7 +71,7 @@ interface amIWebInstaller : nsISupports
|
||||
* @return true if the installation was successfully started
|
||||
*/
|
||||
boolean installAddonsFromWebpage(in AString aMimetype,
|
||||
in nsISupports aOriginator,
|
||||
in nsIDOMElement aBrowser,
|
||||
in nsIURI aReferer,
|
||||
[array, size_is(aInstallCount)] in wstring aUris,
|
||||
[array, size_is(aInstallCount)] in wstring aHashes,
|
||||
|
@ -80,11 +80,7 @@ RemoteMediator.prototype = {
|
||||
installs.referer = referer;
|
||||
installs.callbackID = callbackID;
|
||||
|
||||
let objects = { window: null };
|
||||
if (Services.appinfo.processType === Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT)
|
||||
objects.window = window;
|
||||
|
||||
return messageManager.sendSyncMessage(MSG_INSTALL_ADDONS, installs, objects)[0];
|
||||
return messageManager.sendSyncMessage(MSG_INSTALL_ADDONS, installs)[0];
|
||||
},
|
||||
|
||||
_addCallback: function(callback, urls) {
|
||||
|
@ -20,6 +20,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||
Cu.import("resource://gre/modules/Services.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
|
||||
@ -37,9 +39,9 @@ const LOGGER_ID = "addons.weblistener";
|
||||
// (Requires AddonManager.jsm)
|
||||
let logger = Log.repository.getLogger(LOGGER_ID);
|
||||
|
||||
function notifyObservers(aTopic, aOriginator, aUri, aInstalls) {
|
||||
function notifyObservers(aTopic, aBrowser, aUri, aInstalls) {
|
||||
let info = {
|
||||
originator: aOriginator,
|
||||
browser: aBrowser,
|
||||
originatingURI: aUri,
|
||||
installs: aInstalls,
|
||||
|
||||
@ -52,20 +54,20 @@ function notifyObservers(aTopic, aOriginator, aUri, aInstalls) {
|
||||
* Creates a new installer to monitor downloads and prompt to install when
|
||||
* ready
|
||||
*
|
||||
* @param aOriginator
|
||||
* The window or browser that started the installations
|
||||
* @param aBrowser
|
||||
* The browser that started the installations
|
||||
* @param aUrl
|
||||
* The URL that started the installations
|
||||
* @param aInstalls
|
||||
* An array of AddonInstalls
|
||||
*/
|
||||
function Installer(aOriginator, aUrl, aInstalls) {
|
||||
this.originator = aOriginator;
|
||||
function Installer(aBrowser, aUrl, aInstalls) {
|
||||
this.browser = aBrowser;
|
||||
this.url = aUrl;
|
||||
this.downloads = aInstalls;
|
||||
this.installed = [];
|
||||
|
||||
notifyObservers("addon-install-started", aOriginator, aUrl, aInstalls);
|
||||
notifyObservers("addon-install-started", aBrowser, aUrl, aInstalls);
|
||||
|
||||
aInstalls.forEach(function(aInstall) {
|
||||
aInstall.addListener(this);
|
||||
@ -79,7 +81,7 @@ function Installer(aOriginator, aUrl, aInstalls) {
|
||||
}
|
||||
|
||||
Installer.prototype = {
|
||||
originator: null,
|
||||
browser: null,
|
||||
downloads: null,
|
||||
installed: null,
|
||||
isDownloading: true,
|
||||
@ -145,29 +147,20 @@ Installer.prototype = {
|
||||
aInstall.cancel();
|
||||
}
|
||||
}, this);
|
||||
notifyObservers("addon-install-failed", this.originator, this.url, failed);
|
||||
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;
|
||||
|
||||
let parentWindow = null;
|
||||
try {
|
||||
parentWindow = this.originator.QueryInterface(Ci.nsIDOMWindow);
|
||||
} catch (e) {
|
||||
// If we're remote, then originator will be a browser. In that case,
|
||||
// we're showing our dialog on behalf of a content process and passing
|
||||
// null is the best we can do for now.
|
||||
}
|
||||
|
||||
// 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(parentWindow, this.url, this.downloads, this.downloads.length);
|
||||
prompt.confirm(this.browser, this.url, this.downloads, this.downloads.length);
|
||||
return;
|
||||
}
|
||||
catch (e) {}
|
||||
@ -183,16 +176,22 @@ Installer.prototype = {
|
||||
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);
|
||||
this.downloads.forEach(function(aInstall) {
|
||||
aInstall.removeListener(this);
|
||||
// Cancel the installs, as currently there is no way to make them fail
|
||||
// from here.
|
||||
aInstall.cancel();
|
||||
}, this);
|
||||
notifyObservers("addon-install-cancelled", this.originator, this.url,
|
||||
notifyObservers("addon-install-cancelled", this.browser, this.url,
|
||||
this.downloads);
|
||||
}
|
||||
},
|
||||
@ -219,10 +218,10 @@ Installer.prototype = {
|
||||
this.downloads = null;
|
||||
|
||||
if (failed.length > 0)
|
||||
notifyObservers("addon-install-failed", this.originator, this.url, failed);
|
||||
notifyObservers("addon-install-failed", this.browser, this.url, failed);
|
||||
|
||||
if (this.installed.length > 0)
|
||||
notifyObservers("addon-install-complete", this.originator, this.url, this.installed);
|
||||
notifyObservers("addon-install-complete", this.browser, this.url, this.installed);
|
||||
this.installed = null;
|
||||
},
|
||||
|
||||
@ -273,9 +272,9 @@ extWebInstallListener.prototype = {
|
||||
/**
|
||||
* @see amIWebInstallListener.idl
|
||||
*/
|
||||
onWebInstallDisabled: function extWebInstallListener_onWebInstallDisabled(aOriginator, aUri, aInstalls) {
|
||||
onWebInstallDisabled: function extWebInstallListener_onWebInstallDisabled(aBrowser, aUri, aInstalls) {
|
||||
let info = {
|
||||
originator: aOriginator,
|
||||
browser: aBrowser,
|
||||
originatingURI: aUri,
|
||||
installs: aInstalls,
|
||||
|
||||
@ -287,14 +286,14 @@ extWebInstallListener.prototype = {
|
||||
/**
|
||||
* @see amIWebInstallListener.idl
|
||||
*/
|
||||
onWebInstallBlocked: function extWebInstallListener_onWebInstallBlocked(aOriginator, aUri, aInstalls) {
|
||||
onWebInstallBlocked: function extWebInstallListener_onWebInstallBlocked(aBrowser, aUri, aInstalls) {
|
||||
let info = {
|
||||
originator: aOriginator,
|
||||
browser: aBrowser,
|
||||
originatingURI: aUri,
|
||||
installs: aInstalls,
|
||||
|
||||
install: function onWebInstallBlocked_install() {
|
||||
new Installer(this.originator, this.originatingURI, this.installs);
|
||||
new Installer(this.browser, this.originatingURI, this.installs);
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo])
|
||||
@ -307,8 +306,8 @@ extWebInstallListener.prototype = {
|
||||
/**
|
||||
* @see amIWebInstallListener.idl
|
||||
*/
|
||||
onWebInstallRequested: function extWebInstallListener_onWebInstallRequested(aOriginator, aUri, aInstalls) {
|
||||
new Installer(aOriginator, aUri, aInstalls);
|
||||
onWebInstallRequested: function extWebInstallListener_onWebInstallRequested(aBrowser, aUri, aInstalls) {
|
||||
new Installer(aBrowser, aUri, aInstalls);
|
||||
|
||||
// We start the installs ourself
|
||||
return false;
|
||||
|
@ -243,6 +243,12 @@ function getMainWindow() {
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
}
|
||||
|
||||
function getBrowserElement() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the DOMWindow that can open a preferences pane.
|
||||
*
|
||||
@ -1215,7 +1221,7 @@ var gViewController = {
|
||||
if (installs.length > 0) {
|
||||
// Display the normal install confirmation for the installs
|
||||
AddonManager.installAddonsFromWebpage("application/x-xpinstall",
|
||||
window, null, installs);
|
||||
getBrowserElement(), null, installs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -3613,7 +3619,7 @@ var gDragDrop = {
|
||||
if (installs.length > 0) {
|
||||
// Display the normal install confirmation for the installs
|
||||
AddonManager.installAddonsFromWebpage("application/x-xpinstall",
|
||||
window, null, installs);
|
||||
getBrowserElement(), null, installs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3750,16 +3750,16 @@ this.XPIProvider = {
|
||||
* Icon URLs for the install
|
||||
* @param aVersion
|
||||
* A version for the install
|
||||
* @param aLoadGroup
|
||||
* An nsILoadGroup to associate requests with
|
||||
* @param aBrowser
|
||||
* The browser performing the install
|
||||
* @param aCallback
|
||||
* A callback to pass the AddonInstall to
|
||||
*/
|
||||
getInstallForURL: function XPI_getInstallForURL(aUrl, aHash, aName, aIcons,
|
||||
aVersion, aLoadGroup, aCallback) {
|
||||
aVersion, aBrowser, aCallback) {
|
||||
AddonInstall.createDownload(function getInstallForURL_createDownload(aInstall) {
|
||||
aCallback(aInstall.wrapper);
|
||||
}, aUrl, aHash, aName, aIcons, aVersion, aLoadGroup);
|
||||
}, aUrl, aHash, aName, aIcons, aVersion, aBrowser);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -4755,13 +4755,13 @@ function getHashStringForCrypto(aCrypto) {
|
||||
* An optional nsIURI of release notes for the add-on
|
||||
* @param aExistingAddon
|
||||
* The add-on this install will update if known
|
||||
* @param aLoadGroup
|
||||
* The nsILoadGroup to associate any requests with
|
||||
* @param aBrowser
|
||||
* The browser performing the install
|
||||
* @throws if the url is the url of a local file and the hash does not match
|
||||
* or the add-on does not contain an valid install manifest
|
||||
*/
|
||||
function AddonInstall(aInstallLocation, aUrl, aHash, aReleaseNotesURI,
|
||||
aExistingAddon, aLoadGroup) {
|
||||
aExistingAddon, aBrowser) {
|
||||
this.wrapper = new AddonInstallWrapper(this);
|
||||
this.installLocation = aInstallLocation;
|
||||
this.sourceURI = aUrl;
|
||||
@ -4774,16 +4774,12 @@ function AddonInstall(aInstallLocation, aUrl, aHash, aReleaseNotesURI,
|
||||
};
|
||||
}
|
||||
this.hash = this.originalHash;
|
||||
this.loadGroup = aLoadGroup;
|
||||
this.browser = aBrowser;
|
||||
this.listeners = [];
|
||||
this.icons = {};
|
||||
this.existingAddon = aExistingAddon;
|
||||
this.error = 0;
|
||||
if (aLoadGroup)
|
||||
this.window = aLoadGroup.notificationCallbacks
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
else
|
||||
this.window = null;
|
||||
this.window = aBrowser ? aBrowser.contentWindow : null;
|
||||
|
||||
// Giving each instance of AddonInstall a reference to the logger.
|
||||
this.logger = logger;
|
||||
@ -4796,7 +4792,7 @@ AddonInstall.prototype = {
|
||||
crypto: null,
|
||||
originalHash: null,
|
||||
hash: null,
|
||||
loadGroup: null,
|
||||
browser: null,
|
||||
badCertHandler: null,
|
||||
listeners: null,
|
||||
restartDownload: false,
|
||||
@ -5920,15 +5916,15 @@ AddonInstall.createInstall = function AI_createInstall(aCallback, aFile) {
|
||||
* An icon URLs for the add-on
|
||||
* @param aVersion
|
||||
* A version for the add-on
|
||||
* @param aLoadGroup
|
||||
* An nsILoadGroup to associate the download with
|
||||
* @param aBrowser
|
||||
* The browser performing the install
|
||||
*/
|
||||
AddonInstall.createDownload = function AI_createDownload(aCallback, aUri, aHash, aName, aIcons,
|
||||
aVersion, aLoadGroup) {
|
||||
aVersion, aBrowser) {
|
||||
let location = XPIProvider.installLocationsByName[KEY_APP_PROFILE];
|
||||
let url = NetUtil.newURI(aUri);
|
||||
|
||||
let install = new AddonInstall(location, url, aHash, null, null, aLoadGroup);
|
||||
let install = new AddonInstall(location, url, aHash, null, null, aBrowser);
|
||||
if (url instanceof Ci.nsIFileURL)
|
||||
install.initLocalInstall(aCallback);
|
||||
else
|
||||
|
@ -73,7 +73,10 @@ WindowOpenListener.prototype = {
|
||||
var gInstallNotificationObserver = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
var installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
|
||||
isnot(installInfo.originator, null, "Notification should have non-null originator");
|
||||
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");
|
||||
}
|
||||
|
@ -79,7 +79,10 @@ var gSawInstallNotification = false;
|
||||
var gInstallNotificationObserver = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
var installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
|
||||
isnot(installInfo.originator, null, "Notification should have non-null originator");
|
||||
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");
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ skip-if = true # Bug 1084646
|
||||
[browser_httphash4.js]
|
||||
[browser_httphash5.js]
|
||||
[browser_httphash6.js]
|
||||
skip-if = e10s # Bug 1084558
|
||||
[browser_installchrome.js]
|
||||
[browser_localfile.js]
|
||||
skip-if = e10s # Bug 1082764
|
||||
@ -86,6 +85,7 @@ skip-if = e10s # bug 1082764
|
||||
[browser_signed_url.js]
|
||||
skip-if = e10s # bug 1082764
|
||||
[browser_softwareupdate.js]
|
||||
[browser_switchtab.js]
|
||||
[browser_trigger_redirect.js]
|
||||
[browser_unsigned_trigger.js]
|
||||
[browser_unsigned_trigger_iframe.js]
|
||||
|
@ -16,11 +16,7 @@ function test() {
|
||||
}
|
||||
|
||||
function allow_blocked(installInfo) {
|
||||
// installInfo.originator is different depending on whether we are in e10s(!)
|
||||
if (gMultiProcessBrowser)
|
||||
is(installInfo.originator, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
else
|
||||
is(installInfo.originator, gBrowser.contentWindow, "Install should have been triggered by the right window");
|
||||
is(installInfo.browser, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
is(installInfo.originatingURI.spec, gBrowser.currentURI.spec, "Install should have been triggered by the right uri");
|
||||
return false;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ function finish_failed_download() {
|
||||
|
||||
// Restart the install as a regular webpage install so the harness tracks it
|
||||
AddonManager.installAddonsFromWebpage("application/x-xpinstall",
|
||||
gBrowser.contentWindow,
|
||||
gBrowser.selectedBrowser,
|
||||
gBrowser.currentURI, [gInstall]);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,49 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tests installing an unsigned add-on through an InstallTrigger call in web
|
||||
// content.
|
||||
let expectedTab = null;
|
||||
|
||||
function test() {
|
||||
Harness.installConfirmCallback = confirm_install;
|
||||
Harness.installEndedCallback = install_ended;
|
||||
Harness.installsCompletedCallback = finish_test;
|
||||
Harness.setup();
|
||||
|
||||
var pm = Services.perms;
|
||||
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
|
||||
|
||||
var triggers = encodeURIComponent(JSON.stringify({
|
||||
"Unsigned XPI": {
|
||||
URL: TESTROOT + "unsigned.xpi",
|
||||
IconURL: TESTROOT + "icon.png",
|
||||
toString: function() { return this.URL; }
|
||||
}
|
||||
}));
|
||||
expectedTab = gBrowser.addTab();
|
||||
expectedTab.linkedBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
|
||||
}
|
||||
|
||||
function confirm_install(window) {
|
||||
var items = window.document.getElementById("itemList").childNodes;
|
||||
is(items.length, 1, "Should only be 1 item listed in the confirmation dialog");
|
||||
is(items[0].name, "XPI Test", "Should have seen the name");
|
||||
is(items[0].url, TESTROOT + "unsigned.xpi", "Should have listed the correct url for the item");
|
||||
is(items[0].icon, TESTROOT + "icon.png", "Should have listed the correct icon for the item");
|
||||
is(items[0].signed, "false", "Should have listed the item as unsigned");
|
||||
|
||||
is(gBrowser.selectedTab, expectedTab, "Should have switched to the installing tab.");
|
||||
return true;
|
||||
}
|
||||
|
||||
function install_ended(install, addon) {
|
||||
install.cancel();
|
||||
}
|
||||
|
||||
function finish_test(count) {
|
||||
is(count, 1, "1 Add-on should have been successfully installed");
|
||||
|
||||
Services.perms.remove("example.com", "install");
|
||||
|
||||
gBrowser.removeTab(expectedTab);
|
||||
Harness.finish();
|
||||
}
|
@ -17,11 +17,7 @@ function test() {
|
||||
}
|
||||
|
||||
function allow_blocked(installInfo) {
|
||||
// installInfo.originator is different depending on whether we are in e10s(!)
|
||||
if (gMultiProcessBrowser)
|
||||
is(installInfo.originator, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
else
|
||||
is(installInfo.originator, gBrowser.contentWindow, "Install should have been triggered by the right window");
|
||||
is(installInfo.browser, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
is(installInfo.originatingURI.spec, gBrowser.currentURI.spec, "Install should have been triggered by the right uri");
|
||||
return true;
|
||||
}
|
||||
|
@ -18,11 +18,7 @@ function test() {
|
||||
}
|
||||
|
||||
function allow_blocked(installInfo) {
|
||||
// installInfo.originator is different depending on whether we are in e10s(!)
|
||||
if (gMultiProcessBrowser)
|
||||
is(installInfo.originator, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
else
|
||||
is(installInfo.originator, gBrowser.contentWindow, "Install should have been triggered by the right window");
|
||||
is(installInfo.browser, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
is(installInfo.originatingURI.spec, gBrowser.currentURI.spec, "Install should have been triggered by the right uri");
|
||||
return false;
|
||||
}
|
||||
|
@ -17,11 +17,7 @@ function test() {
|
||||
}
|
||||
|
||||
function allow_blocked(installInfo) {
|
||||
// installInfo.originator is different depending on whether we are in e10s(!)
|
||||
if (gMultiProcessBrowser)
|
||||
is(installInfo.originator, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
else
|
||||
is(installInfo.originator, gBrowser.contentWindow, "Install should have been triggered by the right window");
|
||||
is(installInfo.browser, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
is(installInfo.originatingURI.spec, TESTROOT2 + "test.html", "Install should have been triggered by the right uri");
|
||||
return false;
|
||||
}
|
||||
|
@ -12,11 +12,7 @@ function test() {
|
||||
}
|
||||
|
||||
function allow_blocked(installInfo) {
|
||||
// installInfo.originator is different depending on whether we are in e10s(!)
|
||||
if (gMultiProcessBrowser)
|
||||
is(installInfo.originator, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
else
|
||||
is(installInfo.originator, gBrowser.contentWindow, "Install should have been triggered by the right window");
|
||||
is(installInfo.browser, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
is(installInfo.originatingURI.spec, gBrowser.currentURI.spec, "Install should have been triggered by the right uri");
|
||||
return false;
|
||||
}
|
||||
|
@ -12,11 +12,7 @@ function test() {
|
||||
}
|
||||
|
||||
function allow_blocked(installInfo) {
|
||||
// installInfo.originator is different depending on whether we are in e10s(!)
|
||||
if (gMultiProcessBrowser)
|
||||
is(installInfo.originator, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
else
|
||||
is(installInfo.originator, gBrowser.contentWindow, "Install should have been triggered by the right window");
|
||||
is(installInfo.browser, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
|
||||
is(installInfo.originatingURI.spec, gBrowser.currentURI.spec, "Install should have been triggered by the right uri");
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user