Bug 1323845: Part 2a - Support separate API managers for each extension. r?aswan
MozReview-Commit-ID: 5gGsMm1ahd
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1019,16 +1019,18 @@ class LangpackBootstrapScope {
}
// We create one instance of this class per extension. |addonData|
// comes directly from bootstrap.js when initializing.
this.Extension = class extends ExtensionData {
constructor(addonData, startupReason) {
super(addonData.resourceURI);
+ this.apiManager = Management;
+
this.uuid = UUIDMap.get(addonData.id);
this.instanceId = getUniqueId();
this.MESSAGE_EMIT_EVENT = `Extension:EmitEvent:${this.instanceId}`;
Services.ppmm.addMessageListener(this.MESSAGE_EMIT_EVENT, this);
if (addonData.cleanupFile) {
Services.obs.addObserver(this, "xpcom-shutdown");
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -26,16 +26,17 @@ Cu.import("resource://gre/modules/Servic
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "finalizationService",
"@mozilla.org/toolkit/finalizationwitness;1",
"nsIFinalizationWitnessService");
XPCOMUtils.defineLazyModuleGetters(this, {
ExtensionContent: "resource://gre/modules/ExtensionContent.jsm",
+ ExtensionPageChild: "resource://gre/modules/ExtensionPageChild.jsm",
MessageChannel: "resource://gre/modules/MessageChannel.jsm",
NativeApp: "resource://gre/modules/NativeMessaging.jsm",
PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
});
Cu.import("resource://gre/modules/ExtensionCommon.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
@@ -567,16 +568,18 @@ class BrowserExtensionContent extends Ev
});
this.webAccessibleResources = data.webAccessibleResources.map(res => new MatchGlob(res));
this.whiteListedHosts = new MatchPatternSet(data.whiteListedHosts, {ignorePath: true});
this.permissions = data.permissions;
this.optionalPermissions = data.optionalPermissions;
this.principal = data.principal;
+ this.apiManager = ExtensionPageChild.apiManager;
+
this.localeData = new LocaleData(data.localeData);
this.manifest = data.manifest;
this.baseURL = data.baseURL;
this.baseURI = Services.io.newURI(data.baseURL);
// Only used in addon processes.
this.views = new Set();
--- a/toolkit/components/extensions/ExtensionCommon.jsm
+++ b/toolkit/components/extensions/ExtensionCommon.jsm
@@ -955,16 +955,29 @@ class SchemaAPIManager extends EventEmit
this.schemaURLs = new Map();
this.apis = new DefaultWeakMap(() => new Map());
this._scriptScopes = [];
}
+ onStartup(extension) {
+ let promises = [];
+ for (let apiName of this.eventModules.get("startup")) {
+ promises.push(this.asyncGetAPI(apiName, extension).then(api => {
+ if (api) {
+ api.onStartup();
+ }
+ }));
+ }
+
+ return Promise.all(promises);
+ }
+
async loadModuleJSON(urls) {
function fetchJSON(url) {
return fetch(url).then(resp => resp.json());
}
for (let json of await Promise.all(urls.map(fetchJSON))) {
this.registerModules(json);
}
--- a/toolkit/components/extensions/ExtensionPageChild.jsm
+++ b/toolkit/components/extensions/ExtensionPageChild.jsm
@@ -233,20 +233,20 @@ class ExtensionPageContextChild extends
unload() {
super.unload();
this.extension.views.delete(this);
}
}
defineLazyGetter(ExtensionPageContextChild.prototype, "childManager", function() {
- apiManager.lazyInit();
+ this.extension.apiManager.lazyInit();
let localApis = {};
- let can = new CanOfAPIs(this, apiManager, localApis);
+ let can = new CanOfAPIs(this, this.extension.apiManager, localApis);
let childManager = new ChildAPIManager(this, this.messageManager, can, {
envType: "addon_parent",
viewType: this.viewType,
url: this.uri.spec,
incognito: this.incognito,
});
@@ -307,16 +307,18 @@ defineLazyGetter(DevToolsContextChild.pr
});
ExtensionPageChild = {
// Map<innerWindowId, ExtensionPageContextChild>
extensionContexts: new Map(),
initialized: false,
+ apiManager,
+
_init() {
if (this.initialized) {
return;
}
this.initialized = true;
Services.obs.addObserver(this, "inner-window-destroyed"); // eslint-ignore-line mozilla/balanced-listeners
},
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -77,26 +77,17 @@ const global = this;
// This object loads the ext-*.js scripts that define the extension API.
let apiManager = new class extends SchemaAPIManager {
constructor() {
super("main");
this.initialized = null;
/* eslint-disable mozilla/balanced-listeners */
this.on("startup", (e, extension) => {
- let promises = [];
- for (let apiName of this.eventModules.get("startup")) {
- promises.push(this.asyncGetAPI(apiName, extension).then(api => {
- if (api) {
- api.onStartup();
- }
- }));
- }
-
- return Promise.all(promises);
+ return extension.apiManager.onStartup(extension);
});
this.on("update", async (e, {id, resourceURI}) => {
let modules = this.eventModules.get("update");
if (modules.size == 0) {
return;
}
@@ -470,17 +461,17 @@ class ProxyContextParent extends BaseCon
this.messageManagerProxy.dispose();
super.unload();
apiManager.emit("proxy-context-unload", this);
}
}
defineLazyGetter(ProxyContextParent.prototype, "apiCan", function() {
let obj = {};
- let can = new CanOfAPIs(this, apiManager, obj);
+ let can = new CanOfAPIs(this, this.extension.apiManager, obj);
GlobalManager.injectInObject(this, false, obj);
return can;
});
defineLazyGetter(ProxyContextParent.prototype, "apiObj", function() {
return this.apiCan.root;
});