Back out a08d28e8a86b (bug 768868), 9b96029a9cf0 and 010b5cb3576d (bug 781620) for test failures and leaks
authorPhil Ringnalda <philringnalda@gmail.com>
Mon, 27 Aug 2012 21:34:53 -0700
changeset 105673 118cc431d56f94bf10245958248f1f5aa14d3b72
parent 105672 a3c81ae4cabb56bff12c65d3667c33691c9b53e2
child 105674 271ca35d7645edcd3df21e350e044c4e00cce171
child 105681 08e41d18e1f8448b08c9b3be9d0a2d0abb7aa139
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
bugs768868, 781620
milestone18.0a1
backs outa08d28e8a86b66f90f61bb684b33ba12d2c262ab
Back out a08d28e8a86b (bug 768868), 9b96029a9cf0 and 010b5cb3576d (bug 781620) for test failures and leaks
caps/src/nsPrincipal.cpp
dom/apps/src/AppsService.js
dom/apps/src/AppsServiceChild.jsm
dom/apps/src/AppsUtils.jsm
dom/apps/src/Makefile.in
dom/apps/src/Webapps.js
dom/apps/src/Webapps.jsm
dom/interfaces/apps/mozIApplication.idl
modules/libpref/src/init/all.js
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -25,19 +25,16 @@
 #include "nsContentUtils.h"
 #include "jswrapper.h"
 
 #include "nsPrincipal.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/HashFunctions.h"
 
-#include "nsIAppsService.h"
-#include "mozIApplication.h"
-
 using namespace mozilla;
 
 static bool gCodeBasePrincipalSupport = false;
 static bool gIsObservingCodeBasePrincipalSupport = false;
 
 static bool URIIsImmutable(nsIURI* aURI)
 {
   nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
@@ -1297,55 +1294,20 @@ nsPrincipal::Write(nsIObjectOutputStream
 
 uint16_t
 nsPrincipal::GetAppStatus()
 {
   MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
 
   // Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
   // and they are not inside a mozbrowser.
-  if (mAppId == nsIScriptSecurityManager::NO_APP_ID ||
-      mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID || mInMozBrowser) {
-    return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
-  }
-
-  nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
-  NS_ENSURE_TRUE(appsService, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
-
-  nsCOMPtr<mozIDOMApplication> domApp;
-  appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
-  nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
-  NS_ENSURE_TRUE(app, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
-
-  uint16_t status = nsIPrincipal::APP_STATUS_INSTALLED;
-  NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
-                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
-
-  nsCAutoString origin;
-  NS_ENSURE_SUCCESS(GetOrigin(getter_Copies(origin)),
-                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
-  nsString appOrigin;
-  NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
-                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
-
-  // We go from string -> nsIURI -> origin to be sure we
-  // compare two punny-encoded origins.
-  nsCOMPtr<nsIURI> appURI;
-  NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
-                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
-
-  nsCAutoString appOriginPunned;
-  NS_ENSURE_SUCCESS(GetOriginForURI(appURI, getter_Copies(appOriginPunned)),
-                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
-
-  if (!appOriginPunned.Equals(origin)) {
-    return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
-  }
-
-  return status;
+  return mAppId != nsIScriptSecurityManager::NO_APP_ID &&
+         mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID && !mInMozBrowser
+          ? nsIPrincipal::APP_STATUS_INSTALLED
+          : nsIPrincipal::APP_STATUS_NOT_INSTALLED;
 }
 
 /************************************************************************************************************************/
 
 static const char EXPANDED_PRINCIPAL_SPEC[] = "[Expanded Principal]";
 
 NS_IMPL_CLASSINFO(nsExpandedPrincipal, NULL, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_EXPANDEDPRINCIPAL_CID)
--- a/dom/apps/src/AppsService.js
+++ b/dom/apps/src/AppsService.js
@@ -1,54 +1,79 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict"
 
 function debug(s) {
-  //dump("-*- AppsService.js: " + s + "\n");
+  //dump("-*- AppsService: " + s + "\n");
 }
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}");
 
 function AppsService()
 {
   debug("AppsService Constructor");
-  let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
-                   .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-  debug("inParent: " + inParent);
-  Cu.import(inParent ? "resource://gre/modules/Webapps.jsm" :
-                       "resource://gre/modules/AppsServiceChild.jsm");
+  this.inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
+                  .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+  debug("inParent: " + this.inParent);
+  if (this.inParent) {
+    Cu.import("resource://gre/modules/Webapps.jsm");
+  } else {
+    this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
+                .getService(Ci.nsISyncMessageSender);
+  }
 }
 
 AppsService.prototype = {
   getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
     debug("GetAppByManifestURL( " + aManifestURL + " )");
-    return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
+    if (this.inParent) {
+      return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
+    } else {
+      return this.cpmm.sendSyncMessage("WebApps:GetAppByManifestURL",
+                                       { url: aManifestURL })[0];
+    }
   },
 
   getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aManifestURL) {
     debug("getAppLocalIdByManifestURL( " + aManifestURL + " )");
-    return DOMApplicationRegistry.getAppLocalIdByManifestURL(aManifestURL);
+    if (this.inParent) {
+      return DOMApplicationRegistry.getAppLocalIdByManifestURL(aManifestURL);
+    } else {
+      let res = this.cpmm.sendSyncMessage("WebApps:GetAppLocalIdByManifestURL",
+                                          { url: aManifestURL })[0];
+      return res.id;
+    }
   },
 
   getAppByLocalId: function getAppByLocalId(aLocalId) {
     debug("getAppByLocalId( " + aLocalId + " )");
-    return DOMApplicationRegistry.getAppByLocalId(aLocalId);
+    if (this.inParent) {
+      return DOMApplicationRegistry.getAppByLocalId(aLocalId);
+    } else {
+      return this.cpmm.sendSyncMessage("WebApps:GetAppByLocalId",
+                                       { id: aLocalId })[0];
+    }
   },
 
   getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
     debug("getManifestURLByLocalId( " + aLocalId + " )");
-    return DOMApplicationRegistry.getManifestURLByLocalId(aLocalId);
+    if (this.inParent) {
+      return DOMApplicationRegistry.getManifestURLByLocalId(aLocalId);
+    } else {
+      return this.cpmm.sendSyncMessage("WebApps:GetManifestURLByLocalId",
+                                       { id: aLocalId })[0];
+    }
   },
 
   classID : APPS_SERVICE_CID,
   QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService])
 }
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([AppsService])
deleted file mode 100644
--- a/dom/apps/src/AppsServiceChild.jsm
+++ /dev/null
@@ -1,71 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-// This module exposes a subset of the functionnalities of the parent DOM
-// Registry to content processes, to be be used from the AppsService component.
-
-let EXPORTED_SYMBOLS = ["DOMApplicationRegistry"];
-
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-
-function debug(s) {
-  //dump("-*- AppsServiceChild.jsm: " + s + "\n");
-}
-
-let DOMApplicationRegistry = {
-  init: function init() {
-    debug("init");
-    this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-                  .getService(Ci.nsISyncMessageSender);
-
-    ["Webapps:AddApp", "Webapps:RemoveApp"].forEach((function(aMsgName) {
-      this.cpmm.addMessageListener(aMsgName, this);
-    }).bind(this));
-
-    // We need to prime the cache with the list of apps.
-    // XXX shoud we do this async and block callers if it's not yet there?
-    this.webapps = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
-  },
-
-  receiveMessage: function receiveMessage(aMessage) {
-    debug("Received " + aMessage.name + " message.");
-    let msg = aMessage.json;
-    switch (aMessage.name) {
-      case "Webapps:AddApp":
-        this.webapps[msg.id] = msg.app;
-        break;
-      case "Webapps:RemoveApp":
-        delete this.webapps[msg.id];
-        break;
-    }
-  },
-
-  getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
-    debug("getAppByManifestURL " + aManifestURL);
-    return AppsUtils.getAppByManifestURL(this.webapps, aManifestURL);
-  },
-
-  getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aManifestURL) {
-    debug("getAppLocalIdByManifestURL " + aManifestURL);
-    return AppsUtils.getAppLocalIdByManifestURL(this.webapps, aManifestURL);
-  },
-
-  getAppByLocalId: function getAppByLocalId(aLocalId) {
-    debug("getAppByLocalId " + aLocalId);
-    return AppsUtils.getAppByLocalId(this.webapps, aLocalId);
-  },
-
-  getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
-    debug("getManifestURLByLocalId " + aLocalId);
-    return AppsUtils.getManifestURLByLocalId(this.webapps, aLocalId);
-  }
-}
-
-DOMApplicationRegistry.init();
deleted file mode 100644
--- a/dom/apps/src/AppsUtils.jsm
+++ /dev/null
@@ -1,108 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-// Shared code for AppsServiceChild.jsm and Webapps.jsm
-
-let EXPORTED_SYMBOLS = ["AppsUtils"];
-
-function debug(s) {
-  //dump("-*- AppsUtils.jsm: " + s + "\n");
-}
-
-let AppsUtils = {
-  // Clones a app, without the manifest.
-  cloneAppObject: function cloneAppObject(aApp) {
-    return {
-      installOrigin: aApp.installOrigin,
-      origin: aApp.origin,
-      receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
-      installTime: aApp.installTime,
-      manifestURL: aApp.manifestURL,
-      appStatus: aApp.appStatus,
-      localId: aApp.localId,
-      progress: aApp.progress || 0.0,
-      status: aApp.status || "installed"
-    };
-  },
-
-  cloneAsMozIApplication: function cloneAsMozIApplication(aApp) {
-    let res = this.cloneAppObject(aApp);
-    res.hasPermission = function(aPermission) {
-      let uri = Services.io.newURI(this.origin, null, null);
-      let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
-                     .getService(Ci.nsIScriptSecurityManager);
-      // This helper checks an URI inside |aApp|'s origin and part of |aApp| has a
-      // specific permission. It is not checking if browsers inside |aApp| have such
-      // permission.
-      let principal = secMan.getAppCodebasePrincipal(uri, aApp.localId,
-                                                     /*mozbrowser*/false);
-      let perm = Services.perms.testExactPermissionFromPrincipal(principal,
-                                                                 aPermission);
-      return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
-    };
-    res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
-                                                Ci.mozIApplication]);
-    return res;
-  },
-
-  getAppByManifestURL: function getAppByManifestURL(aApps, aManifestURL) {
-    debug("getAppByManifestURL " + aManifestURL);
-    // This could be O(1) if |webapps| was a dictionary indexed on manifestURL
-    // which should be the unique app identifier.
-    // It's currently O(n).
-    for (let id in aApps) {
-      let app = aApps[id];
-      if (app.manifestURL == aManifestURL) {
-        return this.cloneAsMozIApplication(app);
-      }
-    }
-
-    return null;
-  },
-
-  getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aApps, aManifestURL) {
-    debug("getAppLocalIdByManifestURL " + aManifestURL);
-    for (let id in aApps) {
-      if (aApps[id].manifestURL == aManifestURL) {
-        return aApps[id].localId;
-      }
-    }
-
-    return Ci.nsIScriptSecurityManager.NO_APP_ID;
-  },
-
-  getAppByLocalId: function getAppByLocalId(aApps, aLocalId) {
-    debug("getAppByLocalId " + aLocalId);
-    for (let id in aApps) {
-      let app = aApps[id];
-      if (app.localId == aLocalId) {
-        return this.cloneAsMozIApplication(app);
-      }
-    }
-
-    return null;
-  },
-
-  getManifestURLByLocalId: function getManifestURLByLocalId(aApps, aLocalId) {
-    debug("getManifestURLByLocalId " + aLocalId);
-    for (let id in aApps) {
-      let app = aApps[id];
-      if (app.localId == aLocalId) {
-        return app.manifestURL;
-      }
-    }
-
-    return "";
-  }
-}
--- a/dom/apps/src/Makefile.in
+++ b/dom/apps/src/Makefile.in
@@ -13,13 +13,11 @@ EXTRA_COMPONENTS = \
   AppsService.js \
   AppsService.manifest \
   Webapps.js \
   Webapps.manifest \
   $(NULL)
 
 EXTRA_PP_JS_MODULES += \
   Webapps.jsm \
-  AppsServiceChild.jsm \
-  AppsUtils.jsm \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -15,17 +15,17 @@ Cu.import("resource://gre/modules/Object
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsIMessageSender");
 
 function convertAppsArray(aApps, aWindow) {
   let apps = Cu.createArrayIn(aWindow);
   for (let i = 0; i < aApps.length; i++) {
     let app = aApps[i];
-    apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
+    apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL, 
                                       app.receipts, app.installOrigin, app.installTime));
   }
 
   return apps;
 }
 
 function WebappsRegistry() {
 }
@@ -50,24 +50,16 @@ WebappsRegistry.prototype = {
     if (aManifest.installs_allowed_from) {
       return aManifest.installs_allowed_from.some(function(aOrigin) {
         return aOrigin == "*" || aOrigin == aInstallOrigin;
       });
     }
     return true;
   },
 
-  // Hosted apps can't be trusted or certified, so just check that the
-  // manifest doesn't ask for those.
-  checkAppStatus: function(aManifest) {
-    let manifestStatus = aManifest.type || "web";
-    return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") ||
-            manifestStatus === "web");
-  },
-
   receiveMessage: function(aMessage) {
     let msg = aMessage.json;
     if (msg.oid != this._id)
       return
     let req = this.getRequest(msg.requestID);
     if (!req)
       return;
     let app = msg.app;
@@ -95,60 +87,56 @@ WebappsRegistry.prototype = {
         Services.DOMRequest.fireError(req, "ERROR");
         break;
     }
     this.removeRequest(msg.requestID);
   },
 
   _getOrigin: function(aURL) {
     let uri = Services.io.newURI(aURL, null, null);
-    return uri.prePath;
+    return uri.prePath; 
   },
 
   // mozIDOMApplicationRegistry implementation
-
+  
   install: function(aURL, aParams) {
     let installURL = this._window.location.href;
     let installOrigin = this._getOrigin(installURL);
     let request = this.createRequest();
     let requestID = this.getRequestId(request);
     let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
     xhr.open("GET", aURL, true);
     xhr.channel.loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS;
 
     xhr.addEventListener("load", (function() {
       if (xhr.status == 200) {
         try {
           let manifest = JSON.parse(xhr.responseText, installOrigin);
           if (!this.checkManifest(manifest, installOrigin)) {
             Services.DOMRequest.fireError(request, "INVALID_MANIFEST");
           } else {
-            if (!this.checkAppStatus(manifest)) {
-              Services.DOMRequest.fireError(request, "INVALID_SECURITY_LEVEL");
-            } else {
-              let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
-              let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : [];
-              cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
-                                                                origin: this._getOrigin(aURL),
-                                                                manifestURL: aURL,
-                                                                manifest: manifest,
-                                                                receipts: receipts,
-                                                                categories: categories },
-                                                                from: installURL,
-                                                                oid: this._id,
-                                                                requestID: requestID });
-            }
+            let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
+            let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : [];
+            cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
+                                                              origin: this._getOrigin(aURL),
+                                                              manifestURL: aURL,
+                                                              manifest: manifest,
+                                                              receipts: receipts,
+                                                              categories: categories },
+                                                              from: installURL,
+                                                              oid: this._id,
+                                                              requestID: requestID });
           }
         } catch(e) {
           Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR");
         }
       }
       else {
         Services.DOMRequest.fireError(request, "MANIFEST_URL_ERROR");
-      }
+      }      
     }).bind(this), false);
 
     xhr.addEventListener("error", (function() {
       Services.DOMRequest.fireError(request, "NETWORK_ERROR");
     }).bind(this), false);
 
     xhr.send(null);
     return request;
@@ -202,21 +190,21 @@ WebappsRegistry.prototype = {
   init: function(aWindow) {
     this.initHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
                               "Webapps:GetInstalled:Return:OK",
                               "Webapps:GetSelf:Return:OK", "Webapps:GetSelf:Return:KO"]);
 
     let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
     this._id = util.outerWindowID;
   },
-
+  
   classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry, Ci.nsIDOMGlobalPropertyInitializer]),
-
+  
   classInfo: XPCOMUtils.generateCI({classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
                                     contractID: "@mozilla.org/webapps;1",
                                     interfaces: [Ci.mozIDOMApplicationRegistry],
                                     flags: Ci.nsIClassInfo.DOM_OBJECT,
                                     classDescription: "Webapps Registry"})
 }
 
 /**
@@ -301,17 +289,17 @@ WebappsApplication.prototype = {
         Services.DOMRequest.fireSuccess(req, msg.origin);
         break;
       case "Webapps:Uninstall:Return:KO":
         Services.DOMRequest.fireError(req, "NOT_INSTALLED");
         break;
       case "Webapps:OfflineCache":
         if (msg.manifest != this.manifestURL)
           return;
-
+        
         this.status = msg.status;
         if (this._onprogress) {
           let event = new this._window.MozApplicationEvent("applicationinstall", { application: this });
           this._onprogress.handleEvent(event);
         }
         break;
     }
   },
@@ -400,41 +388,41 @@ WebappsApplicationMgmt.prototype = {
       throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
   },
 
   receiveMessage: function(aMessage) {
     var msg = aMessage.json;
     let req = this.getRequest(msg.requestID);
     // We want Webapps:Install:Return:OK and Webapps:Uninstall:Return:OK to be boradcasted
     // to all instances of mozApps.mgmt
-    if (!((msg.oid == this._id && req)
+    if (!((msg.oid == this._id && req) 
        || aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
       return;
     switch (aMessage.name) {
       case "Webapps:GetAll:Return:OK":
         Services.DOMRequest.fireSuccess(req, convertAppsArray(msg.apps, this._window));
         break;
       case "Webapps:GetAll:Return:KO":
         Services.DOMRequest.fireError(req, "DENIED");
         break;
       case "Webapps:GetNotInstalled:Return:OK":
         Services.DOMRequest.fireSuccess(req, convertAppsArray(msg.apps, this._window));
         break;
       case "Webapps:Install:Return:OK":
         if (this._oninstall) {
           let app = msg.app;
-          let event = new this._window.MozApplicationEvent("applicationinstall",
+          let event = new this._window.MozApplicationEvent("applicationinstall", 
                            { application : createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
                                                                   app.installOrigin, app.installTime) });
           this._oninstall.handleEvent(event);
         }
         break;
       case "Webapps:Uninstall:Return:OK":
         if (this._onuninstall) {
-          let event = new this._window.MozApplicationEvent("applicationuninstall",
+          let event = new this._window.MozApplicationEvent("applicationuninstall", 
                            { application : createApplicationObject(this._window, msg.origin, null, null, null, null, 0) });
           this._onuninstall.handleEvent(event);
         }
         break;
     }
     this.removeRequest(msg.requestID);
   },
 
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -10,17 +10,16 @@ const Ci = Components.interfaces;
 const Cr = Components.results;
 
 let EXPORTED_SYMBOLS = ["DOMApplicationRegistry", "DOMApplicationManifest"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
-Cu.import("resource://gre/modules/AppsUtils.jsm");
 
 const WEBAPP_RUNTIME = Services.appinfo.ID == "webapprt@mozilla.org";
 
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
@@ -46,26 +45,26 @@ XPCOMUtils.defineLazyGetter(this, "msgmg
   // are in a different directory (currently the Firefox profile that installed
   // the webapp); otherwise, they're in the current profile.
   const DIRECTORY_NAME = WEBAPP_RUNTIME ? "WebappRegD" : "ProfD";
 #endif
 
 let DOMApplicationRegistry = {
   appsFile: null,
   webapps: { },
-  children: [ ],
   allAppsLaunchable: false,
 
   init: function() {
     this.messages = ["Webapps:Install", "Webapps:Uninstall",
-                     "Webapps:GetSelf",
-                     "Webapps:GetInstalled", "Webapps:GetNotInstalled",
-                     "Webapps:Launch", "Webapps:GetAll",
-                     "Webapps:InstallPackage", "Webapps:GetBasePath",
-                     "Webapps:GetList"];
+                    "Webapps:GetSelf",
+                    "Webapps:GetInstalled", "Webapps:GetNotInstalled",
+                    "Webapps:Launch", "Webapps:GetAll",
+                    "Webapps:InstallPackage", "Webapps:GetBasePath",
+                    "WebApps:GetAppByManifestURL", "WebApps:GetAppLocalIdByManifestURL",
+                    "WebApps:GetAppByLocalId", "WebApps:GetManifestURLByLocalId"];
 
     this.messages.forEach((function(msgName) {
       ppmm.addMessageListener(msgName, this);
     }).bind(this));
 
     Services.obs.addObserver(this, "xpcom-shutdown", false);
 
     this.appsFile = FileUtils.getFile(DIRECTORY_NAME,
@@ -76,21 +75,16 @@ let DOMApplicationRegistry = {
         this.webapps = aData;
         for (let id in this.webapps) {
 #ifdef MOZ_SYS_MSG
           this._processManifestForId(id);
 #endif
           if (!this.webapps[id].localId) {
             this.webapps[id].localId = this._nextLocalId();
           }
-
-          // Default to a non privileged status.
-          if (this.webapps[id].appStatus === undefined) {
-            this.webapps[id].appStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
-          }
         };
       }).bind(this));
     }
 
     try {
       let hosts = Services.prefs.getCharPref("dom.mozApps.whitelist");
       hosts.split(",").forEach(function(aHost) {
         Services.perms.add(Services.io.newURI(aHost, null, null),
@@ -251,19 +245,28 @@ let DOMApplicationRegistry = {
           ppmm.broadcastAsyncMessage("Webapps:GetAll:Return:KO", msg);
         break;
       case "Webapps:InstallPackage":
         this.installPackage(msg);
         break;
       case "Webapps:GetBasePath":
         return FileUtils.getFile(DIRECTORY_NAME, ["webapps"], true).path;
         break;
-      case "Webapps:GetList":
-        this.children.push(aMessage.target);
-        return this.webapps;
+      case "WebApps:GetAppByManifestURL":
+        return this.getAppByManifestURL(msg.url);
+        break;
+      case "WebApps:GetAppLocalIdByManifestURL":
+        return { id: this.getAppLocalIdByManifestURL(msg.url) };
+        break;
+      case "WebApps:GetAppByLocalId":
+        return this.getAppByLocalId(msg.id);
+        break;
+      case "WebApps:GetManifestURLByLocalId":
+        return this.getManifestURLByLocalId(msg.id);
+        break;
     }
   },
 
   _writeFile: function ss_writeFile(aFile, aData, aCallbak) {
     // Initialize the file output stream.
     let ostream = FileUtils.openSafeFileOutputStream(aFile);
 
     // Obtain a converter to convert our data to a UTF-8 encoded input stream.
@@ -274,16 +277,30 @@ let DOMApplicationRegistry = {
     // Asynchronously copy the data to the file.
     let istream = converter.convertToInputStream(aData);
     NetUtil.asyncCopy(istream, ostream, function(rc) {
       if (aCallbak)
         aCallbak();
     });
   },
 
+  // clones a app object, without the manifest
+  _cloneAppObject: function(aApp) {
+    let clone = {
+      installOrigin: aApp.installOrigin,
+      origin: aApp.origin,
+      receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
+      installTime: aApp.installTime,
+      manifestURL: aApp.manifestURL,
+      progress: aApp.progress || 0.0,
+      status: aApp.status || "installed"
+    };
+    return clone;
+  },
+
   denyInstall: function(aData) {
     let packageId = aData.app.packageId;
     if (packageId) {
       let dir = FileUtils.getDir("TmpD", ["webapps", packageId],
                                  true, true);
       try {
         dir.remove(true);
       } catch(e) {
@@ -309,55 +326,51 @@ let DOMApplicationRegistry = {
       localId = this._nextLocalId();
     }
 
     if (app.packageId) {
       // Override the origin with the correct id.
       app.origin = "app://" + id;
     }
 
-    let appObject = AppsUtils.cloneAppObject(app);
-    appObject.appStatus = app.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
+    let appObject = this._cloneAppObject(app);
     appObject.installTime = app.installTime = Date.now();
     let appNote = JSON.stringify(appObject);
     appNote.id = id;
 
     appObject.localId = localId;
 
     let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
     let manFile = dir.clone();
     manFile.append("manifest.webapp");
     this._writeFile(manFile, JSON.stringify(app.manifest), function() {
       // If this a packaged app, move the zip file from the temp directory,
       // and delete the temp directory.
       if (app.packageId) {
-        let appFile = FileUtils.getFile("TmpD", ["webapps", app.packageId, "application.zip"],
+        let appFile = FileUtils.getFile("TmpD", ["webapps", app.packageId, "application.zip"], 
                                         true, true);
         appFile.moveTo(dir, "application.zip");
-        let tmpDir = FileUtils.getDir("TmpD", ["webapps", app.packageId],
+        let tmpDir = FileUtils.getDir("TmpD", ["webapps", app.packageId], 
                                         true, true);
         try {
           tmpDir.remove(true);
         } catch(e) {
         }
       }
     });
     this.webapps[id] = appObject;
 
     appObject.status = "installed";
-
+    
     let manifest = new DOMApplicationManifest(app.manifest, app.origin);
 
     if (!aFromSync)
       this._saveApps((function() {
         ppmm.broadcastAsyncMessage("Webapps:Install:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
-        this.children.forEach(function(aMsgMgr) {
-          aMsgMgr.broadcastAsyncMessage("Webapps:AddApp", { id: id, app: appObject });
-        });
       }).bind(this));
 
 #ifdef MOZ_SYS_MSG
     this._registerSystemMessages(id, app);
 #endif
 
     // if the manifest has an appcache_path property, use it to populate the appcache
     if (manifest.appcache_path) {
@@ -479,57 +492,16 @@ let DOMApplicationRegistry = {
         dir.remove(true);
       } catch (e) { }
       ppmm.broadcastAsyncMessage("Webapps:Install:Return:KO",
                             { oid: aData.oid,
                               requestID: aData.requestID,
                               error: aError });
     }
 
-    function getInferedStatus() {
-      // XXX Update once we have digital signatures (bug 772365)
-      return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
-    }
-
-    function getAppManifestStatus(aManifest) {
-      let type = aManifest.type || "web";
-      let manifestStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
-
-      switch(type) {
-        case "web":
-          manifestStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
-          break;
-        case "privileged":
-          manifestStatus = Ci.nsIPrincipal.APP_STATUS_PRIVILEGED;
-          break
-        case "certified":
-          manifestStatus = Ci.nsIPrincipal.APP_STATUS_CERTIFIED;
-          break;
-      }
-
-      return manifestStatus;
-    }
-
-    function getAppStatus(aManifest) {
-      let manifestStatus = getAppManifestStatus(aManifest);
-      let inferedStatus = getInferedStatus();
-
-      return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") ? manifestStatus
-                                                                : inferedStatus);
-    }
-    // Returns true if the privilege level from the manifest
-    // is lower or equal to the one we infered for the app.
-    function checkAppStatus(aManifest) {
-      if (Services.prefs.getBoolPref("dom.mozApps.dev_mode")) {
-        return true;
-      }
-
-      return (getAppManifestStatus(aManifest) <= getInferedStatus());
-    }
-
     NetUtil.asyncFetch(aData.url, function(aInput, aResult, aRequest) {
       if (!Components.isSuccessCode(aResult)) {
         // We failed to fetch the zip.
         cleanup("NETWORK_ERROR");
         return;
       }
       // Copy the zip on disk.
       let zipFile = FileUtils.getFile("TmpD",
@@ -565,46 +537,41 @@ let DOMApplicationRegistry = {
           if (!zipReader.hasEntry("manifest.webapp")) {
             throw "No manifest.webapp found.";
           }
 
           let istream = zipReader.getInputStream("manifest.webapp");
           msg.app.manifest = JSON.parse(NetUtil.readInputStreamToString(istream,
                                         istream.available()) || "");
           if (!checkManifest(msg.app.manifest)) {
-            throw "INVALID_MANIFEST";
+            throw "Invalid manifest";
           }
 
-          if (!checkAppStatus(msg.app.manifest)) {
-            throw "INVALID_SECURITY_LEVEL";
-          }
-
-          msg.appStatus = getAppStatus(msg.app.manifest);
           Services.obs.notifyObservers(this, "webapps-ask-install",
                                              JSON.stringify(msg));
         } catch (e) {
           // XXX we may need new error messages.
-          cleanup(e);
+          cleanup("INVALID_MANIFEST");
         } finally {
           zipReader.close();
         }
       });
     });
   },
 
   uninstall: function(aData) {
     let found = false;
     for (let id in this.webapps) {
       let app = this.webapps[id];
       if (app.origin != aData.origin) {
         continue;
       }
 
       found = true;
-      let appNote = JSON.stringify(AppsUtils.cloneAppObject(app));
+      let appNote = JSON.stringify(this._cloneAppObject(app));
       appNote.id = id;
 
       this._readManifests([{ id: id }], (function unregisterManifest(aResult) {
 #ifdef MOZ_SYS_MSG
         this._unregisterActivities(aResult[0].manifest, app);
 #endif
       }).bind(this));
 
@@ -613,34 +580,31 @@ let DOMApplicationRegistry = {
         dir.remove(true);
       } catch (e) {}
 
       delete this.webapps[id];
 
       this._saveApps((function() {
         ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
-        this.children.forEach(function(aMsgMgr) {
-          aMsgMgr.broadcastAsyncMessage("Webapps:RemoveApp", { id: id });
-        });
       }).bind(this));
     }
 
     if (!found) {
       ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:KO", aData);
     }
   },
 
   getSelf: function(aData) {
     aData.apps = [];
     let tmp = [];
     let id = this._appId(aData.origin);
 
     if (id && this._isLaunchable(this.webapps[id].origin)) {
-      let app = AppsUtils.cloneAppObject(this.webapps[id]);
+      let app = this._cloneAppObject(this.webapps[id]);
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
       ppmm.broadcastAsyncMessage("Webapps:GetSelf:Return:OK", aData);
@@ -649,17 +613,17 @@ let DOMApplicationRegistry = {
 
   getInstalled: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
       if (this.webapps[id].installOrigin == aData.origin &&
           this._isLaunchable(this.webapps[id].origin)) {
-        aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
+        aData.apps.push(this._cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
       ppmm.broadcastAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
@@ -667,34 +631,34 @@ let DOMApplicationRegistry = {
   },
 
   getNotInstalled: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
       if (!this._isLaunchable(this.webapps[id].origin)) {
-        aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
+        aData.apps.push(this._cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
       ppmm.broadcastAsyncMessage("Webapps:GetNotInstalled:Return:OK", aData);
     }).bind(this));
   },
 
   getAll: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
-      let app = AppsUtils.cloneAppObject(this.webapps[id]);
+      let app = this._cloneAppObject(this.webapps[id]);
       if (!this._isLaunchable(app.origin))
         continue;
 
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
@@ -723,40 +687,88 @@ let DOMApplicationRegistry = {
   itemExists: function(aId) {
     return !!this.webapps[aId];
   },
 
   getAppById: function(aId) {
     if (!this.webapps[aId])
       return null;
 
-    let app = AppsUtils.cloneAppObject(this.webapps[aId]);
+    let app = this._cloneAppObject(this.webapps[aId]);
     return app;
   },
 
   getAppByManifestURL: function(aManifestURL) {
-    return AppsUtils.getAppByManifestURL(this.webapps, aManifestURL);
+    // This could be O(1) if |webapps| was a dictionary indexed on manifestURL
+    // which should be the unique app identifier.
+    // It's currently O(n).
+    for (let id in this.webapps) {
+      let app = this.webapps[id];
+      if (app.manifestURL == aManifestURL) {
+        let res = this._cloneAppObject(app);
+        res.hasPermission = function(permission) {
+          let localId = DOMApplicationRegistry.getAppLocalIdByManifestURL(
+            this.manifestURL);
+          let uri = Services.io.newURI(this.manifestURL, null, null);
+          let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
+                       .getService(Ci.nsIScriptSecurityManager);
+          // XXX for the purposes of permissions checking, this helper
+          // should always be called on !isBrowser frames, so we
+          // assume false here.
+          let principal = secMan.getAppCodebasePrincipal(uri, localId,
+                                                         /*mozbrowser*/false);
+          let perm = Services.perms.testExactPermissionFromPrincipal(principal,
+                                                                     permission);
+          return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
+        };
+        res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
+                                                    Ci.mozIApplication]);
+        return res;
+      }
+    }
+
+    return null;
   },
 
   getAppByLocalId: function(aLocalId) {
-    return AppsUtils.getAppByLocalId(this.webapps, aLocalId);
+    for (let id in this.webapps) {
+      let app = this.webapps[id];
+      if (app.localId == aLocalId) {
+        return this._cloneAppObject(app);
+      }
+    }
+
+    return null;
   },
 
   getManifestURLByLocalId: function(aLocalId) {
-    return AppsUtils.getManifestURLByLocalId(this.webapps, aLocalId);
+    for (let id in this.webapps) {
+      let app = this.webapps[id];
+      if (app.localId == aLocalId) {
+        return app.manifestURL;
+      }
+    }
+
+    return null;
   },
 
   getAppLocalIdByManifestURL: function(aManifestURL) {
-    return AppsUtils.getAppLocalIdByManifestURL(this.webapps, aManifestURL);
+    for (let id in this.webapps) {
+      if (this.webapps[id].manifestURL == aManifestURL) {
+        return this.webapps[id].localId;
+      }
+    }
+
+    return Ci.nsIScriptSecurityManager.NO_APP_ID;
   },
 
   getAllWithoutManifests: function(aCallback) {
     let result = {};
     for (let id in this.webapps) {
-      let app = AppsUtils.cloneAppObject(this.webapps[id]);
+      let app = this._cloneAppObject(this.webapps[id]);
       result[id] = app;
     }
     aCallback(result);
   },
 
   updateApps: function(aRecords, aCallback) {
     for (let i = 0; i < aRecords.length; i++) {
       let record = aRecords[i];
--- a/dom/interfaces/apps/mozIApplication.idl
+++ b/dom/interfaces/apps/mozIApplication.idl
@@ -6,17 +6,14 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMApplicationRegistry.idl"
 
 /**
  * We expose Gecko-internal helpers related to "web apps" through this
  * sub-interface.
  */
-[scriptable, uuid(acf46a46-729a-4ab4-9da3-8d59ecfd103d)]
+[scriptable, uuid(8de25e36-b4cb-4e89-9310-a199dce4e5f4)]
 interface mozIApplication: mozIDOMApplication
 {
   /* Return true if this app has |permission|. */
   boolean hasPermission(in string permission);
-
-  /* Application status as defined in nsIPrincipal. */
-  readonly attribute unsigned short appStatus;
 };
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -3684,12 +3684,8 @@ pref("memory.low_memory_notification_int
 // window to be collected via the GC/CC.
 pref("memory.ghost_window_timeout_seconds", 60);
 
 pref("social.enabled", false);
 
 // Disable idle observer fuzz, because only privileged content can access idle
 // observers (bug 780507).
 pref("dom.idle-observers-api.fuzz_time.disabled", true);
-
-// Setting that to true grant elevated privileges to apps that ask
-// for them in their manifest.
-pref("dom.mozApps.dev_mode", false);