Bug 1084558: Switch the web installer interfaces to use browsers instead of DOM windows. r=Unfocused

This commit is contained in:
Dave Townsend 2014-11-04 19:20:52 -08:00
parent 292b0666f0
commit a7d0217d78
24 changed files with 168 additions and 166 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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);
}
},

View File

@ -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);
};

View File

@ -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,

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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]

View File

@ -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;
}

View File

@ -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]);
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}