Bug 1350522: Part 5 - Remove registerSchemaAPI(). r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 25 Mar 2017 13:59:14 -0700
changeset 551553 3f146583e90c815198dfe522d4a9a7b76bf5d8db
parent 551552 18aabb5231deeccbe5e9643317be124056a1f944
child 551554 4dd4e9b3a12ff695f5a10f6674d99d56331eec10
push id51079
push usermaglione.k@gmail.com
push dateMon, 27 Mar 2017 01:43:58 +0000
reviewersaswan
bugs1350522
milestone55.0a1
Bug 1350522: Part 5 - Remove registerSchemaAPI(). r?aswan MozReview-Commit-ID: 5yK2wUms86G
toolkit/components/extensions/ExtensionChild.jsm
toolkit/components/extensions/ExtensionCommon.jsm
toolkit/components/extensions/ExtensionContent.jsm
toolkit/components/extensions/ExtensionParent.jsm
toolkit/components/extensions/ProxyScriptContext.jsm
toolkit/components/extensions/test/xpcshell/test_ext_schemas_api_injection.js
toolkit/components/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -464,53 +464,39 @@ class Messenger {
 }
 
 var apiManager = new class extends SchemaAPIManager {
   constructor() {
     super("addon");
     this.initialized = false;
   }
 
-  generateAPIs(...args) {
+  lazyInit() {
     if (!this.initialized) {
       this.initialized = true;
       for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS_ADDON)) {
         this.loadScript(value);
       }
     }
-    return super.generateAPIs(...args);
-  }
-
-  registerSchemaAPI(namespace, envType, getAPI) {
-    if (envType == "addon_child") {
-      super.registerSchemaAPI(namespace, envType, getAPI);
-    }
   }
 }();
 
 var devtoolsAPIManager = new class extends SchemaAPIManager {
   constructor() {
     super("devtools");
     this.initialized = false;
   }
 
-  generateAPIs(...args) {
+  lazyInit() {
     if (!this.initialized) {
       this.initialized = true;
       for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS_DEVTOOLS)) {
         this.loadScript(value);
       }
     }
-    return super.generateAPIs(...args);
-  }
-
-  registerSchemaAPI(namespace, envType, getAPI) {
-    if (envType == "devtools_child") {
-      super.registerSchemaAPI(namespace, envType, getAPI);
-    }
   }
 }();
 
 /**
  * An object that runs an remote implementation of an API.
  */
 class ProxyAPIImplementation extends SchemaAPIInterface {
   /**
@@ -912,19 +898,20 @@ class ExtensionPageContextChild extends 
 
   unload() {
     super.unload();
     this.extension.views.delete(this);
   }
 }
 
 defineLazyGetter(ExtensionPageContextChild.prototype, "childManager", function() {
+  apiManager.lazyInit();
+
   let localApis = {};
   let can = new CanOfAPIs(this, apiManager, localApis);
-  apiManager.generateAPIs(this, localApis);
 
   let childManager = new ChildAPIManager(this, this.messageManager, can, {
     envType: "addon_parent",
     viewType: this.viewType,
     url: this.uri.spec,
     incognito: this.incognito,
   });
 
@@ -960,19 +947,20 @@ class DevToolsContextChild extends Exten
 
   unload() {
     super.unload();
     this.extension.devtoolsViews.delete(this);
   }
 }
 
 defineLazyGetter(DevToolsContextChild.prototype, "childManager", function() {
+  devtoolsAPIManager.lazyInit();
+
   let localApis = {};
   let can = new CanOfAPIs(this, apiManager, localApis);
-  devtoolsAPIManager.generateAPIs(this, localApis);
 
   let childManager = new ChildAPIManager(this, this.messageManager, can, {
     envType: "devtools_parent",
     viewType: this.viewType,
     url: this.uri.spec,
     incognito: this.incognito,
   });
 
--- a/toolkit/components/extensions/ExtensionCommon.jsm
+++ b/toolkit/components/extensions/ExtensionCommon.jsm
@@ -783,25 +783,16 @@ class SchemaAPIManager extends EventEmit
     this.manifestKeys = new Map();
     this.eventModules = new DefaultMap(() => new Set());
 
     this.schemaURLs = new Set();
 
     this.apis = new DefaultWeakMap(() => new Map());
 
     this._scriptScopes = [];
-    this._schemaApis = {
-      addon_parent: [],
-      addon_child: [],
-      content_parent: [],
-      content_child: [],
-      devtools_parent: [],
-      devtools_child: [],
-      proxy_script: [],
-    };
   }
 
   /**
    * Registers a set of ExtensionAPI modules to be lazily loaded and
    * managed by this manager.
    *
    * @param {object} obj
    *        An object containing property for eacy API module to be
@@ -1102,62 +1093,16 @@ class SchemaAPIManager extends EventEmit
 
     Services.scriptloader.loadSubScript(scriptUrl, scope, "UTF-8");
 
     // Save the scope to avoid it being garbage collected.
     this._scriptScopes.push(scope);
   }
 
   /**
-   * Called by an ext-*.js script to register an API.
-   *
-   * @param {string} namespace The API namespace.
-   *     Intended to match the namespace of the generated API, but not used at
-   *     the moment - see bugzil.la/1295774.
-   * @param {string} envType Restricts the API to contexts that run in the
-   *    given environment. Must be one of the following:
-   *     - "addon_parent" - addon APIs that run in the main process.
-   *     - "addon_child" - addon APIs that run in an addon process.
-   *     - "content_parent" - content script APIs that run in the main process.
-   *     - "content_child" - content script APIs that run in a content process.
-   *     - "devtools_parent" - devtools APIs that run in the main process.
-   *     - "devtools_child" - devtools APIs that run in a devtools process.
-   *     - "proxy_script" - proxy script APIs that run in the main process.
-   * @param {function(BaseContext)} getAPI A function that returns an object
-   *     that will be merged with |chrome| and |browser|. The next example adds
-   *     the create, update and remove methods to the tabs API.
-   *
-   *     registerSchemaAPI("tabs", "addon_parent", (context) => ({
-   *       tabs: { create, update },
-   *     }));
-   *     registerSchemaAPI("tabs", "addon_parent", (context) => ({
-   *       tabs: { remove },
-   *     }));
-   */
-  registerSchemaAPI(namespace, envType, getAPI) {
-    this._schemaApis[envType].push({namespace, getAPI});
-  }
-
-  /**
-   * Exports all registered scripts to `obj`.
-   *
-   * @param {BaseContext} context The context for which the API bindings are
-   *     generated.
-   * @param {object} obj The destination of the API.
-   */
-  generateAPIs(context, obj) {
-    let apis = this._schemaApis[context.envType];
-    if (!apis) {
-      Cu.reportError(`No APIs have been registered for ${context.envType}`);
-      return;
-    }
-    SchemaAPIManager.generateAPIs(context, apis, obj);
-  }
-
-  /**
    * Mash together all the APIs from `apis` into `obj`.
    *
    * @param {BaseContext} context The context for which the API bindings are
    *     generated.
    * @param {Array} apis A list of objects, see `registerSchemaAPI`.
    * @param {object} obj The destination of the API.
    */
   static generateAPIs(context, apis, obj) {
--- a/toolkit/components/extensions/ExtensionContent.jsm
+++ b/toolkit/components/extensions/ExtensionContent.jsm
@@ -90,30 +90,23 @@ function isWhenBeforeOrSame(when1, when2
 }
 
 var apiManager = new class extends SchemaAPIManager {
   constructor() {
     super("content");
     this.initialized = false;
   }
 
-  generateAPIs(...args) {
+  lazyInit() {
     if (!this.initialized) {
       this.initialized = true;
       for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS_CONTENT)) {
         this.loadScript(value);
       }
     }
-    return super.generateAPIs(...args);
-  }
-
-  registerSchemaAPI(namespace, envType, getAPI) {
-    if (envType == "content_child") {
-      super.registerSchemaAPI(namespace, envType, getAPI);
-    }
   }
 }();
 
 const SCRIPT_EXPIRY_TIMEOUT_MS = 5 * 60 * 1000;
 const SCRIPT_CLEAR_TIMEOUT_MS = 5 * 1000;
 
 const CSS_EXPIRY_TIMEOUT_MS = 30 * 60 * 1000;
 
@@ -620,19 +613,20 @@ defineLazyGetter(ContentScriptContextChi
   let sender = {id: this.extension.id, frameId: this.frameId, url: this.url};
   let filter = {extensionId: this.extension.id};
   let optionalFilter = {frameId: this.frameId};
 
   return new Messenger(this, [this.messageManager], sender, filter, optionalFilter);
 });
 
 defineLazyGetter(ContentScriptContextChild.prototype, "childManager", function() {
+  apiManager.lazyInit();
+
   let localApis = {};
   let can = new CanOfAPIs(this, apiManager, localApis);
-  apiManager.generateAPIs(this, localApis);
 
   let childManager = new ChildAPIManager(this, this.messageManager, can, {
     envType: "content_parent",
     url: this.url,
   });
 
   this.callOnClose(childManager);
 
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -138,23 +138,16 @@ let apiManager = new class extends Schem
       if (result.tabId) {
         if (sync) {
           return result;
         }
         target.messageManager.sendAsyncMessage("Extension:SetTabAndWindowId", result);
       }
     }
   }
-
-  registerSchemaAPI(namespace, envType, getAPI) {
-    if (envType == "addon_parent" || envType == "content_parent" ||
-        envType == "devtools_parent") {
-      super.registerSchemaAPI(namespace, envType, getAPI);
-    }
-  }
 }();
 
 // Subscribes to messages related to the extension messaging API and forwards it
 // to the relevant message manager. The "sender" field for the `onMessage` and
 // `onConnect` events are updated if needed.
 ProxyMessenger = {
   _initialized: false,
 
@@ -291,17 +284,16 @@ GlobalManager = {
     }
   },
 
   getExtension(extensionId) {
     return this.extensionMap.get(extensionId);
   },
 
   injectInObject(context, isChromeCompat, dest) {
-    apiManager.generateAPIs(context, dest);
     SchemaAPIManager.generateAPIs(context, context.extension.apis, dest);
   },
 };
 
 /**
  * The proxied parent side of a context in ExtensionChild.jsm, for the
  * parent side of a proxied API.
  */
--- a/toolkit/components/extensions/ProxyScriptContext.jsm
+++ b/toolkit/components/extensions/ProxyScriptContext.jsm
@@ -224,31 +224,24 @@ class ProxyScriptContext extends BaseCon
 }
 
 class ProxyScriptAPIManager extends SchemaAPIManager {
   constructor() {
     super("proxy");
     this.initialized = false;
   }
 
-  generateAPIs(...args) {
+  lazyInit() {
     if (!this.initialized) {
       for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(
           CATEGORY_EXTENSION_SCRIPTS_CONTENT)) {
         this.loadScript(value);
       }
       this.initialized = true;
     }
-    return super.generateAPIs(...args);
-  }
-
-  registerSchemaAPI(namespace, envType, getAPI) {
-    if (envType == "proxy_script") {
-      super.registerSchemaAPI(namespace, envType, getAPI);
-    }
   }
 }
 
 class ProxyScriptInjectionContext {
   constructor(context, apiCan) {
     this.context = context;
     this.localAPIs = apiCan.root;
     this.apiCan = apiCan;
@@ -286,16 +279,16 @@ defineLazyGetter(ProxyScriptContext.prot
   let filter = {extensionId: this.extension.id, toProxyScript: true};
   return new Messenger(this, [this.messageManager], sender, filter);
 });
 
 let proxyScriptAPIManager = new ProxyScriptAPIManager();
 
 defineLazyGetter(ProxyScriptContext.prototype, "browserObj", function() {
   let localAPIs = {};
-  proxyScriptAPIManager.generateAPIs(this, localAPIs);
   let can = new CanOfAPIs(this, proxyScriptAPIManager, localAPIs);
+  proxyScriptAPIManager.lazyInit();
 
   let browserObj = Cu.createObjectIn(this.sandbox);
   let injectionContext = new ProxyScriptInjectionContext(this, can);
   Schemas.inject(browserObj, injectionContext);
   return browserObj;
 });
deleted file mode 100644
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_api_injection.js
+++ /dev/null
@@ -1,102 +0,0 @@
-"use strict";
-
-Components.utils.import("resource://gre/modules/ExtensionCommon.jsm");
-Components.utils.import("resource://gre/modules/Schemas.jsm");
-
-let {
-  BaseContext,
-  SchemaAPIManager,
-} = ExtensionCommon;
-
-let nestedNamespaceJson = [
-  {
-    "namespace": "backgroundAPI.testnamespace",
-    "functions": [
-      {
-        "name": "create",
-        "type": "function",
-        "parameters": [
-          {
-            "name": "title",
-            "type": "string",
-          },
-        ],
-        "returns": {
-          "type": "string",
-        },
-      },
-    ],
-  },
-  {
-    "namespace": "noBackgroundAPI.testnamespace",
-    "functions": [
-      {
-        "name": "create",
-        "type": "function",
-        "parameters": [
-          {
-            "name": "title",
-            "type": "string",
-          },
-        ],
-      },
-    ],
-  },
-];
-
-let global = this;
-class StubContext extends BaseContext {
-  constructor() {
-    let fakeExtension = {id: "test@web.extension"};
-    super("addon_child", fakeExtension);
-    this.sandbox = Cu.Sandbox(global);
-    this.viewType = "background";
-  }
-
-  get cloneScope() {
-    return this.sandbox;
-  }
-}
-
-add_task(function* testSchemaAPIInjection() {
-  let url = "data:," + JSON.stringify(nestedNamespaceJson);
-
-  // Load the schema of the fake APIs.
-  yield Schemas.load(url);
-
-  let apiManager = new SchemaAPIManager("addon");
-
-  // Register an API that will skip the background page.
-  apiManager.registerSchemaAPI("noBackgroundAPI.testnamespace", "addon_child", context => {
-    // This API should not be available in this context, return null so that
-    // the schema wrapper is removed as well.
-    return null;
-  });
-
-  // Register an API that will skip any but the background page.
-  apiManager.registerSchemaAPI("backgroundAPI.testnamespace", "addon_child", context => {
-    if (context.viewType === "background") {
-      return {
-        backgroundAPI: {
-          testnamespace: {
-            create(title) {
-              return title;
-            },
-          },
-        },
-      };
-    }
-
-    // This API should not be available in this context, return null so that
-    // the schema wrapper is removed as well.
-    return null;
-  });
-
-  let context = new StubContext();
-  let browserObj = {};
-  apiManager.generateAPIs(context, browserObj);
-
-  do_check_eq(browserObj.noBackgroundAPI, undefined);
-  const res = browserObj.backgroundAPI.testnamespace.create("param-value");
-  do_check_eq(res, "param-value");
-});
--- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini
@@ -58,17 +58,16 @@ skip-if = true # This test no longer tes
 [test_ext_runtime_getBrowserInfo.js]
 [test_ext_runtime_getPlatformInfo.js]
 [test_ext_runtime_onInstalled_and_onStartup.js]
 [test_ext_runtime_sendMessage.js]
 [test_ext_runtime_sendMessage_errors.js]
 [test_ext_runtime_sendMessage_no_receiver.js]
 [test_ext_runtime_sendMessage_self.js]
 [test_ext_schemas.js]
-[test_ext_schemas_api_injection.js]
 [test_ext_schemas_async.js]
 [test_ext_schemas_allowed_contexts.js]
 [test_ext_schemas_revoke.js]
 [test_ext_shutdown_cleanup.js]
 [test_ext_simple.js]
 [test_ext_startup_cache.js]
 [test_ext_storage.js]
 [test_ext_storage_sync.js]