--- a/toolkit/mozapps/extensions/addonManager.js
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -68,17 +68,17 @@ amManager.prototype = {
observe: function(aSubject, aTopic, aData) {
switch (aTopic) {
case "addons-startup":
AddonManagerPrivate.startup();
break;
case "message-manager-close":
case "message-manager-disconnect":
- AddonManager.webAPI.clearInstallsFrom(aSubject);
+ this.childClosed(aSubject);
break;
}
},
/**
* @see amIAddonManager.idl
*/
mapURIToAddonID: function(uri, id) {
@@ -159,17 +159,47 @@ amManager.prototype = {
return retval;
},
notify: function(aTimer) {
AddonManagerPrivate.backgroundUpdateTimerHandler();
},
- addonListener: null,
+ // Maps message manager instances for content processes to the associated
+ // AddonListener instances.
+ addonListeners: new Map(),
+
+ _addAddonListener(target) {
+ if (!this.addonListeners.has(target)) {
+ let handler = (event, id, needsRestart) => {
+ target.sendAsyncMessage(MSG_ADDON_EVENT, {event, id, needsRestart});
+ };
+ let listener = {
+ onEnabling: (addon, needsRestart) => handler("onEnabling", addon.id, needsRestart),
+ onEnabled: (addon) => handler("onEnabled", addon.id, false),
+ onDisabling: (addon, needsRestart) => handler("onDisabling", addon.id, needsRestart),
+ onDisabled: (addon) => handler("onDisabled", addon.id, false),
+ onInstalling: (addon, needsRestart) => handler("onInstalling", addon.id, needsRestart),
+ onInstalled: (addon) => handler("onInstalled", addon.id, false),
+ onUninstalling: (addon, needsRestart) => handler("onUninstalling", addon.id, needsRestart),
+ onUninstalled: (addon) => handler("onUninstalled", addon.id, false),
+ onOperationCancelled: (addon) => handler("onOperationCancelled", addon.id, false),
+ };
+ this.addonListeners.set(target, listener);
+ AddonManager.addAddonListener(listener);
+ }
+ },
+
+ _removeAddonListener(target) {
+ if (this.addonListeners.has(target)) {
+ AddonManager.removeAddonListener(this.addonListeners.get(target));
+ this.addonListeners.delete(target);
+ }
+ },
/**
* messageManager callback function.
*
* Listens to requests from child processes for InstallTrigger
* activity, and sends back callbacks.
*/
receiveMessage: function(aMessage) {
@@ -223,45 +253,32 @@ amManager.prototype = {
}
case MSG_INSTALL_CLEANUP: {
AddonManager.webAPI.clearInstalls(payload.ids);
break;
}
case MSG_ADDON_EVENT_REQ: {
+ let target = aMessage.target;
if (payload.enabled) {
- if (!this.addonListener) {
- let target = aMessage.target;
- let handler = (event, id, needsRestart) => {
- target.sendAsyncMessage(MSG_ADDON_EVENT, {event, id, needsRestart});
- };
- this.addonListener = {
- onEnabling: (addon, needsRestart) => handler("onEnabling", addon.id, needsRestart),
- onEnabled: (addon) => handler("onEnabled", addon.id, false),
- onDisabling: (addon, needsRestart) => handler("onDisabling", addon.id, needsRestart),
- onDisabled: (addon) => handler("onDisabled", addon.id, false),
- onInstalling: (addon, needsRestart) => handler("onInstalling", addon.id, needsRestart),
- onInstalled: (addon) => handler("onInstalled", addon.id, false),
- onUninstalling: (addon, needsRestart) => handler("onUninstalling", addon.id, needsRestart),
- onUninstalled: (addon) => handler("onUninstalled", addon.id, false),
- onOperationCancelled: (addon) => handler("onOperationCancelled", addon.id, false),
- };
- }
- AddonManager.addAddonListener(this.addonListener);
+ this._addAddonListener(target);
} else {
- if (this.addonListener) {
- AddonManager.removeAddonListener(this.addonListener);
- }
+ this._removeAddonListener(target);
}
}
}
return undefined;
},
+ childClosed(target) {
+ AddonManager.webAPI.clearInstallsFrom(target);
+ this._removeAddonListener(target);
+ },
+
sendEvent(target, data) {
target.sendAsyncMessage(MSG_INSTALL_EVENT, data);
},
classID: Components.ID("{4399533d-08d1-458c-a87a-235f74451cfa}"),
_xpcom_factory: {
createInstance: function(aOuter, aIid) {
if (aOuter != null)