Bug 835013 - AppProtocolHandler.js and related code taking ~50ms on the critical startup path. r=cjones, a=tef+
authorFabrice Desré <fabrice@mozilla.com>
Thu, 31 Jan 2013 13:35:13 -0800
changeset 118389 62f5f431675e076469b0808e3fc2135d45ca4415
parent 118388 6153fb8e61b625c145928fd323633a0cf73fa6f1
child 118390 afff6ff7d5cd572fc08137395eff2e405f5c7844
push id18
push userryanvm@gmail.com
push dateFri, 01 Feb 2013 23:13:14 +0000
reviewerscjones, tef
bugs835013
milestone18.0
Bug 835013 - AppProtocolHandler.js and related code taking ~50ms on the critical startup path. r=cjones, a=tef+
dom/apps/src/AppsService.js
dom/apps/src/AppsServiceChild.jsm
dom/apps/src/Webapps.jsm
dom/interfaces/apps/nsIAppsService.idl
netwerk/protocol/app/AppProtocolHandler.js
--- a/dom/apps/src/AppsService.js
+++ b/dom/apps/src/AppsService.js
@@ -63,13 +63,18 @@ AppsService.prototype = {
     return DOMApplicationRegistry.getCoreAppsBasePath();
   },
 
   getWebAppsBasePath: function getWebAppsBasePath() {
     debug("getWebAppsBasePath()");
     return DOMApplicationRegistry.getWebAppsBasePath();
   },
 
+  getAppInfo: function getAppInfo(aAppId) {
+    debug("getAppInfo()");
+    return DOMApplicationRegistry.getAppInfo(aAppId);
+  },
+
   classID : APPS_SERVICE_CID,
   QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService])
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AppsService])
--- a/dom/apps/src/AppsServiceChild.jsm
+++ b/dom/apps/src/AppsServiceChild.jsm
@@ -106,12 +106,21 @@ this.DOMApplicationRegistry = {
   getCoreAppsBasePath: function getCoreAppsBasePath() {
     debug("getCoreAppsBasePath() not yet supported on child!");
     return null;
   },
 
   getWebAppsBasePath: function getWebAppsBasePath() {
     debug("getWebAppsBasePath() not yet supported on child!");
     return null;
-  }
+  },
+
+  getAppInfo: function getAppInfo(aAppId) {
+    if (!this.webapps[aAppId]) {
+      debug("No webapp for " + aAppId);
+      return null;
+    }
+    return { "basePath":  this.webapps[aAppId].basePath + "/",
+             "isCoreApp": !this.webapps[aAppId].removable };
+  },
 }
 
 DOMApplicationRegistry.init();
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -70,17 +70,17 @@ this.DOMApplicationRegistry = {
   children: [ ],
   allAppsLaunchable: false,
 
   init: function() {
     this.messages = ["Webapps:Install", "Webapps:Uninstall",
                      "Webapps:GetSelf", "Webapps:CheckInstalled",
                      "Webapps:GetInstalled", "Webapps:GetNotInstalled",
                      "Webapps:Launch", "Webapps:GetAll",
-                     "Webapps:InstallPackage", "Webapps:GetAppInfo",
+                     "Webapps:InstallPackage",
                      "Webapps:GetList", "Webapps:RegisterForMessages",
                      "Webapps:UnregisterForMessages",
                      "Webapps:CancelDownload", "Webapps:CheckForUpdate",
                      "Webapps:Download", "Webapps:ApplyDownload",
                      "child-process-shutdown"];
 
     this.frameMessages = ["Webapps:ClearBrowserData"];
 
@@ -793,24 +793,16 @@ this.DOMApplicationRegistry = {
         this.getNotInstalled(msg, mm);
         break;
       case "Webapps:GetAll":
         this.getAll(msg, mm);
         break;
       case "Webapps:InstallPackage":
         this.doInstallPackage(msg, mm);
         break;
-      case "Webapps:GetAppInfo":
-        if (!this.webapps[msg.id]) {
-          debug("No webapp for " + msg.id);
-          return null;
-        }
-        return { "basePath":  this.webapps[msg.id].basePath + "/",
-                 "isCoreApp": !this.webapps[msg.id].removable };
-        break;
       case "Webapps:RegisterForMessages":
         this.addMessageListener(msg, mm);
         break;
       case "Webapps:UnregisterForMessages":
         this.removeMessageListener(msg, mm);
         break;
       case "child-process-shutdown":
         this.removeMessageListener(["Webapps:Internal:AllMessages"], mm);
@@ -831,16 +823,25 @@ this.DOMApplicationRegistry = {
         this.applyDownload(msg.manifestURL);
         break;
       case "Activities:Register:OK":
         this.notifyAppsRegistryReady();
         break;
     }
   },
 
+  getAppInfo: function getAppInfo(aAppId) {
+    if (!this.webapps[aAppId]) {
+      debug("No webapp for " + aAppId);
+      return null;
+    }
+    return { "basePath":  this.webapps[aAppId].basePath + "/",
+             "isCoreApp": !this.webapps[aAppId].removable };
+  },
+
   // Some messages can be listened by several content processes:
   // Webapps:AddApp
   // Webapps:RemoveApp
   // Webapps:Install:Return:OK
   // Webapps:Uninstall:Return:OK
   // Webapps:Uninstall:Broadcast:Return:OK
   // Webapps:OfflineCache
   // Webapps:checkForUpdate:Return:OK
--- a/dom/interfaces/apps/nsIAppsService.idl
+++ b/dom/interfaces/apps/nsIAppsService.idl
@@ -11,17 +11,17 @@ interface mozIApplication;
 #define APPS_SERVICE_CID { 0x05072afa, 0x92fe, 0x45bf, { 0xae, 0x22, 0x39, 0xb6, 0x9c, 0x11, 0x70, 0x58 } }
 #define APPS_SERVICE_CONTRACTID "@mozilla.org/AppsService;1"
 %}
 
 /*
  * This service allows accessing some DOMApplicationRegistry methods from
  * non-javascript code.
  */
-[scriptable, uuid(e65f9397-e191-4273-aa5f-f13c185ce63b)]
+[scriptable, uuid(4ac27836-4d79-4d35-b105-d6fb7f4f8e41)]
 interface nsIAppsService : nsISupports
 {
   mozIDOMApplication getAppByManifestURL(in DOMString manifestURL);
 
   /**
    * Returns the |localId| of the app associated with the |manifestURL| passed
    * in parameter.
    * Returns nsIScriptSecurityManager::NO_APP_ID if |manifestURL| isn't a valid
@@ -55,9 +55,11 @@ interface nsIAppsService : nsISupports
    * Returns the basepath for core apps
    */
   DOMString getCoreAppsBasePath();
 
   /**
    * Returns the basepath for regular packaged apps
    */
   DOMString getWebAppsBasePath();
+
+  jsval getAppInfo(in DOMString appId);
 };
--- a/netwerk/protocol/app/AppProtocolHandler.js
+++ b/netwerk/protocol/app/AppProtocolHandler.js
@@ -6,19 +6,19 @@
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsISyncMessageSender");
+XPCOMUtils.defineLazyServiceGetter(this, "appsService",
+                                   "@mozilla.org/AppsService;1",
+                                   "nsIAppsService");
 
 function AppProtocolHandler() {
   this._appInfo = [];
   this._runningInParent = Cc["@mozilla.org/xre/runtime;1"]
                             .getService(Ci.nsIXULRuntime)
                             .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
 }
 
@@ -31,18 +31,17 @@ AppProtocolHandler.prototype = {
   // Don't allow loading from other protocols, and only from app:// if webapps is granted
   protocolFlags: Ci.nsIProtocolHandler.URI_NOAUTH |
                  Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
                  Ci.nsIProtocolHandler.URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM,
 
   getAppInfo: function app_phGetAppInfo(aId) {
 
     if (!this._appInfo[aId]) {
-      let reply = cpmm.sendSyncMessage("Webapps:GetAppInfo", { id: aId });
-      this._appInfo[aId] = reply[0];
+      this._appInfo[aId] = appsService.getAppInfo(aId);
     }
     return this._appInfo[aId];
   },
 
   newURI: function app_phNewURI(aSpec, aOriginCharset, aBaseURI) {
     let uri = Cc["@mozilla.org/network/standard-url;1"]
               .createInstance(Ci.nsIStandardURL);
     uri.init(Ci.nsIStandardURL.URLTYPE_STANDARD, -1, aSpec, aOriginCharset,