Bug 1323845: Part 2a - Support separate API managers for each extension. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 16 Dec 2017 15:33:23 -0600
changeset 718297 fb1aa3bbf66d6d6c4f0897977caf76cca2ce0c71
parent 718296 9dcd2ff1c93e41eb9771068e65aad350d295ba18
child 718298 3036170b873d6edbd4d270f5b2c75279688fb4b1
push id94869
push usermaglione.k@gmail.com
push dateWed, 10 Jan 2018 01:49:31 +0000
reviewersaswan
bugs1323845
milestone59.0a1
Bug 1323845: Part 2a - Support separate API managers for each extension. r?aswan MozReview-Commit-ID: 5gGsMm1ahd
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionChild.jsm
toolkit/components/extensions/ExtensionCommon.jsm
toolkit/components/extensions/ExtensionPageChild.jsm
toolkit/components/extensions/ExtensionParent.jsm
--- 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;
 });