Back out bug 776649. r=bustage
authorChris Jones <jones.chris.g@gmail.com>
Wed, 08 Aug 2012 20:13:12 -0700
changeset 101916 1be3b987748af42d05372002c7940b3be7d7c346
parent 101914 8fc9f7605bb6b8b2440d2a0ef7d85c3b329ef651
child 101917 c2dfe04ba1cba41f4ce7879345665acf56c3e59d
push idunknown
push userunknown
push dateunknown
reviewersbustage
bugs776649
milestone17.0a1
Back out bug 776649. r=bustage
content/base/src/nsFrameLoader.cpp
dom/apps/src/Webapps.jsm
dom/interfaces/apps/Makefile.in
dom/interfaces/apps/mozIApplication.idl
dom/ipc/AppProcessPermissions.cpp
dom/ipc/AppProcessPermissions.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/Makefile.in
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -8,17 +8,16 @@
  * Class for managing loading of a subframe (creation of the docshell,
  * handling of loads in it, recursion-checking).
  */
 
 #include "base/basictypes.h"
 
 #include "prenv.h"
 
-#include "mozIApplication.h"
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMMozBrowserFrame.h"
 #include "nsIDOMWindow.h"
 #include "nsIPresShell.h"
 #include "nsIContent.h"
 #include "nsIContentViewer.h"
 #include "nsIDocument.h"
@@ -27,17 +26,16 @@
 #include "nsPIDOMWindow.h"
 #include "nsIWebNavigation.h"
 #include "nsIWebProgress.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocShellLoadInfo.h"
-#include "nsIDOMApplicationRegistry.h"
 #include "nsIBaseWindow.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsIJSContextStack.h"
 #include "nsUnicharUtils.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScrollable.h"
@@ -1970,60 +1968,64 @@ nsFrameLoader::TryRemoteBrowser()
   nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
   if (!window) {
     return false;
   }
   if (NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
     return false;
   }
 
+  PRUint32 appId = 0;
   bool isBrowserElement = false;
-  nsCOMPtr<mozIApplication> app;
+
   if (OwnerIsBrowserFrame()) {
     isBrowserElement = true;
 
     if (mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozapp)) {
       nsAutoString manifest;
       mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapp, manifest);
 
       nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
       if (!appsService) {
         NS_ERROR("Apps Service is not available!");
         return false;
       }
 
-      nsCOMPtr<mozIDOMApplication> domApp;
-      appsService->GetAppByManifestURL(manifest, getter_AddRefs(domApp));
-      // If the frame is actually an app, we should not mark it as a
-      // browser.  This is to identify the data store: since <app>s
-      // and <browser>s-within-<app>s have different stores, we want
-      // to ensure the <app> uses its store, not the one for its
-      // <browser>s.
-      app = do_QueryInterface(domApp);
-      if (app) {
+      appsService->GetAppLocalIdByManifestURL(manifest, &appId);
+
+      // If the frame is actually an app, we should not mark it as a browser.
+      if (appId != nsIScriptSecurityManager::NO_APP_ID) {
         isBrowserElement = false;
       }
     }
   }
 
-  if ((mRemoteBrowser = ContentParent::CreateBrowser(app, isBrowserElement))) {
+  // If our owner has no app manifest URL, then this is equivalent to
+  // ContentParent::GetNewOrUsed().
+  nsAutoString appManifest;
+  GetOwnerAppManifestURL(appManifest);
+  ContentParent* parent = ContentParent::GetForApp(appManifest);
+
+  NS_ASSERTION(parent->IsAlive(), "Process parent should be alive; something is very wrong!");
+  mRemoteBrowser = parent->CreateTab(chromeFlags, isBrowserElement, appId);
+  if (mRemoteBrowser) {
     nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
     mRemoteBrowser->SetOwnerElement(element);
 
     nsCOMPtr<nsIDocShellTreeItem> rootItem;
     parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem));
     nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
     nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
     NS_ABORT_IF_FALSE(rootChromeWin, "How did we not get a chrome window here?");
 
     nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
     rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
     mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
-
-    mChildHost = static_cast<ContentParent*>(mRemoteBrowser->Manager());
+    
+    mChildHost = parent;
   }
   return true;
 }
 
 mozilla::dom::PBrowserParent*
 nsFrameLoader::GetRemoteBrowser()
 {
   return mRemoteBrowser;
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -693,35 +693,17 @@ let DOMApplicationRegistry = {
 
   getAppByManifestURL: function(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 this._cloneAppObject(app);
       }
     }
 
     return null;
   },
 
   getAppByLocalId: function(aLocalId) {
     for (let id in this.webapps) {
--- a/dom/interfaces/apps/Makefile.in
+++ b/dom/interfaces/apps/Makefile.in
@@ -10,15 +10,14 @@ VPATH          = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = dom
 XPIDL_MODULE   = dom_apps
 GRE_MODULE     = 1
 
 XPIDLSRCS =                               \
-            mozIApplication.idl \
             nsIDOMApplicationRegistry.idl \
             nsIAppsService.idl \
             nsIDOMMozApplicationEvent.idl \
             $(NULL)
 
 include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/dom/interfaces/apps/mozIApplication.idl
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* 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/. */
-
-#include "nsIDOMApplicationRegistry.idl"
-
-/**
- * We expose Gecko-internal helpers related to "web apps" through this
- * sub-interface.
- */
-[scriptable, uuid(8de25e36-b4cb-4e89-9310-a199dce4e5f4)]
-interface mozIApplication: mozIDOMApplication
-{
-  /* Return true if this app has |permission|. */
-  boolean hasPermission(in string permission);
-};
deleted file mode 100644
--- a/dom/ipc/AppProcessPermissions.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* 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/. */
-
-#include "AppProcessPermissions.h"
-#include "ContentParent.h"
-#include "mozIApplication.h"
-#include "nsIDOMApplicationRegistry.h"
-#include "TabParent.h"
-
-using namespace mozilla::dom;
-using namespace mozilla::services;
-
-namespace mozilla {
-
-bool
-AppProcessHasPermission(PBrowserParent* aActor, const char* aPermission)
-{
-  if (!aActor) {
-    NS_WARNING("Testing permissions for null actor");
-    return false;
-  }
-
-  TabParent* tab = static_cast<TabParent*>(aActor);
-  nsCOMPtr<mozIApplication> app = tab->GetApp();
-  // isBrowser frames inherit their app descriptor to identify their
-  // data storage, but they don't inherit the permissions associated
-  // with that descriptor.
-  if (!app || tab->IsBrowserElement()) {
-    return false;
-  }
-
-  bool hasPermission = false;
-  return (NS_SUCCEEDED(app->HasPermission(aPermission, &hasPermission)) &&
-          hasPermission);
-}
-
-bool
-AppProcessHasPermission(PContentParent* aActor, const char* aPermission)
-{
-  const InfallibleTArray<PBrowserParent*>& browsers =
-    aActor->ManagedPBrowserParent();
-  for (uint32_t i = 0; i < browsers.Length(); ++i) {
-    if (AppProcessHasPermission(browsers[i], aPermission)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/ipc/AppProcessPermissions.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* 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/. */
-
-#ifndef mozilla_Capabilities_h
-#define mozilla_Capabilities_h
-
-namespace mozilla {
-
-namespace dom {
-class PBrowserParent;
-class PContentParent;
-}
-
-/**
- * Return true iff the specified browser has the specified capability.
- */
-bool
-AppProcessHasPermissions(mozilla::dom::PBrowserParent* aActor,
-                         const char* aPermission);
-
-/**
- * Return true iff any of the PBrowsers loaded in this content process
- * has the specified capability.
- */
-bool
-AppProcessHasPermission(mozilla::dom::PContentParent* aActor,
-                        const char* aPermission);
-
-// NB: when adding capability checks for other IPDL actors, please add
-// them to this file and have them delegate to the two functions above
-// as appropriate.  For example,
-//
-//   bool AppProcessHasCapability(PNeckoParent* aActor) {
-//     return AppProcessHasCapability(aActor->Manager());
-//   }
-
-} // namespace mozilla
-
-#endif // mozilla_Capabilities_h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -34,17 +34,16 @@
 
 #if defined(MOZ_SYDNEYAUDIO)
 #include "nsAudioStream.h"
 #endif
 #include "nsIMemoryReporter.h"
 #include "nsIObserverService.h"
 #include "nsTObserverArray.h"
 #include "nsIObserver.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXULAppAPI.h"
 #include "nsWeakReference.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsJSEnvironment.h"
 #include "SandboxHal.h"
 #include "nsDebugImpl.h"
@@ -398,21 +397,20 @@ PCompositorChild*
 ContentChild::AllocPCompositor(mozilla::ipc::Transport* aTransport,
                                base::ProcessId aOtherProcess)
 {
     return CompositorChild::Create(aTransport, aOtherProcess);
 }
 
 PBrowserChild*
 ContentChild::AllocPBrowser(const PRUint32& aChromeFlags,
-                            const bool& aIsBrowserElement, const AppId& aApp)
+                            const bool& aIsBrowserElement,
+                            const PRUint32& aAppId)
 {
-    PRUint32 appId = aApp.get_uint32_t();
-    nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement,
-                                             appId);
+    nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement, aAppId);
     return NS_SUCCEEDED(iframe->Init()) ? iframe.forget().get() : NULL;
 }
 
 bool
 ContentChild::DeallocPBrowser(PBrowserChild* iframe)
 {
     TabChild* child = static_cast<TabChild*>(iframe);
     NS_RELEASE(child);
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -63,17 +63,17 @@ public:
         return mAppInfo;
     }
 
     PCompositorChild* AllocPCompositor(mozilla::ipc::Transport* aTransport,
                                        base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags,
                                          const bool& aIsBrowserElement,
-                                         const AppId& aAppId);
+                                         const PRUint32& aAppId);
     virtual bool DeallocPBrowser(PBrowserChild*);
 
     virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequest(const DeviceStorageParams&);
     virtual bool DeallocPDeviceStorageRequest(PDeviceStorageRequestChild*);
 
     virtual PBlobChild* AllocPBlob(const BlobConstructorParams& aParams);
     virtual bool DeallocPBlob(PBlobChild*);
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -15,17 +15,16 @@
 
 #include "chrome/common/process_watcher.h"
 
 #include "CrashReporterParent.h"
 #include "History.h"
 #include "IDBFactory.h"
 #include "IndexedDBParent.h"
 #include "IndexedDatabaseManager.h"
-#include "mozIApplication.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Util.h"
 #include "mozilla/dom/ExternalHelperAppParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 #include "mozilla/dom/StorageParent.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
@@ -45,29 +44,26 @@
 #include "nsConsoleMessage.h"
 #include "nsDebugImpl.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDOMFile.h"
 #include "nsExternalHelperAppService.h"
 #include "nsFrameMessageManager.h"
 #include "nsHashPropertyBag.h"
 #include "nsIAlertsService.h"
-#include "nsIAppsService.h"
 #include "nsIClipboard.h"
 #include "nsIConsoleService.h"
-#include "nsIDOMApplicationRegistry.h"
 #include "nsIDOMGeoGeolocation.h"
 #include "nsIDOMWindow.h"
 #include "nsIFilePicker.h"
 #include "nsIMemoryReporter.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIRemoteBlob.h"
 #include "nsIScriptError.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIWindowWatcher.h"
 #include "nsMemoryReporterManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsSystemInfo.h"
 #include "nsThreadUtils.h"
 #include "nsToolkitCompsCID.h"
 #include "nsWidgetsCID.h"
@@ -148,96 +144,62 @@ MemoryReportRequestParent::~MemoryReport
 
 nsDataHashtable<nsStringHashKey, ContentParent*>* ContentParent::gAppContentParents;
 nsTArray<ContentParent*>* ContentParent::gNonAppContentParents;
 nsTArray<ContentParent*>* ContentParent::gPrivateContent;
 
 // The first content child has ID 1, so the chrome process can have ID 0.
 static PRUint64 gContentChildID = 1;
 
-/*static*/ ContentParent*
+ContentParent*
 ContentParent::GetNewOrUsed()
 {
     if (!gNonAppContentParents)
         gNonAppContentParents = new nsTArray<ContentParent*>();
 
     PRInt32 maxContentProcesses = Preferences::GetInt("dom.ipc.processCount", 1);
     if (maxContentProcesses < 1)
         maxContentProcesses = 1;
 
     if (gNonAppContentParents->Length() >= PRUint32(maxContentProcesses)) {
         PRUint32 idx = rand() % gNonAppContentParents->Length();
         ContentParent* p = (*gNonAppContentParents)[idx];
         NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in gNonAppContentParents?");
         return p;
     }
-
+        
     nsRefPtr<ContentParent> p =
         new ContentParent(/* appManifestURL = */ EmptyString());
     p->Init();
     gNonAppContentParents->AppendElement(p);
     return p;
 }
 
-/*static*/ TabParent*
-ContentParent::CreateBrowser(mozIApplication* aApp, bool aIsBrowserElement)
+ContentParent*
+ContentParent::GetForApp(const nsAString& aAppManifestURL)
 {
-    if (!aApp) {
-        if (ContentParent* cp = GetNewOrUsed()) {
-            nsRefPtr<TabParent> tp(new TabParent(aApp, aIsBrowserElement));
-            return static_cast<TabParent*>(
-                cp->SendPBrowserConstructor(
-                    // DeallocPBrowserParent() releases the ref we take here
-                    tp.forget().get(),
-                    /*chromeFlags*/0,
-                    aIsBrowserElement, nsIScriptSecurityManager::NO_APP_ID));
-        }
-        return nullptr;
+    if (aAppManifestURL.IsEmpty()) {
+        return GetNewOrUsed();
     }
 
     if (!gAppContentParents) {
         gAppContentParents =
             new nsDataHashtable<nsStringHashKey, ContentParent*>();
         gAppContentParents->Init();
     }
 
     // Each app gets its own ContentParent instance.
-    nsAutoString manifestURL;
-    if (NS_FAILED(aApp->GetManifestURL(manifestURL))) {
-        NS_ERROR("Failed to get manifest URL");
-        return nullptr;
-    }
-
-    nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
-    if (!appsService) {
-        NS_ERROR("Failed to get apps service");
-        return nullptr;
+    ContentParent* p = gAppContentParents->Get(aAppManifestURL);
+    if (!p) {
+        p = new ContentParent(aAppManifestURL);
+        p->Init();
+        gAppContentParents->Put(aAppManifestURL, p);
     }
 
-    // Send the local app ID to the new TabChild so it knows what app
-    // it is.
-    PRUint32 appId;
-    if (NS_FAILED(appsService->GetAppLocalIdByManifestURL(manifestURL, &appId))) {
-        NS_ERROR("Failed to get local app ID");
-        return nullptr;
-    }
-
-    ContentParent* p = gAppContentParents->Get(manifestURL);
-    if (!p) {
-        p = new ContentParent(manifestURL);
-        p->Init();
-        gAppContentParents->Put(manifestURL, p);
-    }
-
-    nsRefPtr<TabParent> tp(new TabParent(aApp, aIsBrowserElement));
-    return static_cast<TabParent*>(
-        // DeallocPBrowserParent() releases the ref we take here
-        p->SendPBrowserConstructor(tp.forget().get(),
-                                   /*chromeFlags*/0,
-                                   aIsBrowserElement, appId));
+    return p;
 }
 
 static PLDHashOperator
 AppendToTArray(const nsAString& aKey, ContentParent* aValue, void* aArray)
 {
     nsTArray<ContentParent*> *array =
         static_cast<nsTArray<ContentParent*>*>(aArray);
     array->AppendElement(aValue);
@@ -488,16 +450,22 @@ ContentParent::ActorDestroy(ActorDestroy
     // |this|.  If so, when we go out of scope here, we're deleted and
     // all hell breaks loose.
     //
     // This runnable ensures that a reference to |this| lives on at
     // least until after the current task finishes running.
     NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
 }
 
+TabParent*
+ContentParent::CreateTab(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId)
+{
+  return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags, aIsBrowserElement, aAppId));
+}
+
 void
 ContentParent::NotifyTabDestroyed(PBrowserParent* aTab)
 {
     // There can be more than one PBrowser for a given app process
     // because of popup windows.  When the last one closes, shut
     // us down.
     if (IsForApp() && ManagedPBrowserParent().Length() == 1) {
         MessageLoop::current()->PostTask(
@@ -889,50 +857,32 @@ PCompositorParent*
 ContentParent::AllocPCompositor(mozilla::ipc::Transport* aTransport,
                                 base::ProcessId aOtherProcess)
 {
     return CompositorParent::Create(aTransport, aOtherProcess);
 }
 
 PBrowserParent*
 ContentParent::AllocPBrowser(const PRUint32& aChromeFlags,
-                             const bool& aIsBrowserElement, const AppId& aApp)
+                             const bool& aIsBrowserElement,
+                             const PRUint32& aAppId)
 {
-    // We only use this Alloc() method when the content processes asks
-    // us to open a window.  In that case, we're expecting to see the
-    // opening PBrowser as its app descriptor, and we can trust the data
-    // associated with that PBrowser since it's fully owned by this
-    // process.
-    if (AppId::TPBrowserParent != aApp.type()) {
-        NS_ERROR("Content process attempting to forge app ID");
-        return nullptr;
-    }
-    TabParent* opener = static_cast<TabParent*>(aApp.get_PBrowserParent());
-
-    // Popup windows of isBrowser frames are isBrowser if the parent
-    // isBrowser.  Allocating a !isBrowser frame with same app ID
-    // would allow the content to access data it's not supposed to.
-    if (opener && opener->IsBrowserElement() && !aIsBrowserElement) {
-        NS_ERROR("Content process attempting to escalate data access privileges");
-        return nullptr;
-    }
-
-    TabParent* parent = new TabParent(opener ? opener->GetApp() : nullptr,
-                                      aIsBrowserElement);
-    // We release this ref in DeallocPBrowser()
+  TabParent* parent = new TabParent();
+  if (parent){
     NS_ADDREF(parent);
-    return parent;
+  }
+  return parent;
 }
 
 bool
 ContentParent::DeallocPBrowser(PBrowserParent* frame)
 {
-    TabParent* parent = static_cast<TabParent*>(frame);
-    NS_RELEASE(parent);
-    return true;
+  TabParent* parent = static_cast<TabParent*>(frame);
+  NS_RELEASE(parent);
+  return true;
 }
 
 PDeviceStorageRequestParent*
 ContentParent::AllocPDeviceStorageRequest(const DeviceStorageParams& aParams)
 {
   return new DeviceStorageRequestParent(aParams);
 }
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -21,17 +21,16 @@
 #include "nsIPermissionManager.h"
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIMemoryReporter.h"
 #include "nsCOMArray.h"
 #include "nsDataHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsHashKeys.h"
 
-class mozIApplication;
 class nsFrameMessageManager;
 class nsIDOMBlob;
 
 namespace mozilla {
 
 namespace ipc {
 class TestShellParent;
 }
@@ -56,33 +55,38 @@ private:
     typedef mozilla::ipc::TestShellParent TestShellParent;
     typedef mozilla::layers::PCompositorParent PCompositorParent;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
     static ContentParent* GetNewOrUsed();
 
     /**
-     * Get or create a content process for the given app descriptor,
-     * which may be null.  This function will assign processes to app
-     * or non-app browsers by internal heuristics.
+     * Get or create a content process for the given app.  A given app
+     * (identified by its manifest URL) gets one process all to itself.
      *
-     * Currently apps are given their own process, and browser tabs
-     * share processes.
+     * If the given manifest is the empty string, then this method is equivalent
+     * to GetNewOrUsed().
      */
-    static TabParent* CreateBrowser(mozIApplication* aApp,
-                                    bool aIsBrowserFrame);
-
+    static ContentParent* GetForApp(const nsAString& aManifestURL);
     static void GetAll(nsTArray<ContentParent*>& aArray);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
     NS_DECL_NSITHREADOBSERVER
     NS_DECL_NSIDOMGEOPOSITIONCALLBACK
 
+    /**
+     * Create a new tab.
+     *
+     * |aIsBrowserElement| indicates whether this tab is part of an
+     * <iframe mozbrowser>.
+     * |aAppId| indicates which app the tab belongs to.
+     */
+    TabParent* CreateTab(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId);
     /** Notify that a tab was destroyed during normal operation. */
     void NotifyTabDestroyed(PBrowserParent* aTab);
 
     TestShellParent* CreateTestShell();
     bool DestroyTestShell(TestShellParent* aTestShell);
     TestShellParent* GetTestShellSingleton();
 
     void ReportChildAlreadyBlocked();
@@ -134,19 +138,17 @@ private:
      * by the Get*() funtions.  However, the shutdown sequence itself
      * may be asynchronous.
      */
     void ShutDown();
 
     PCompositorParent* AllocPCompositor(mozilla::ipc::Transport* aTransport,
                                         base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
-    virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags,
-                                          const bool& aIsBrowserElement,
-                                          const AppId& aApp);
+    virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserElement, const PRUint32& aAppId);
     virtual bool DeallocPBrowser(PBrowserParent* frame);
 
     virtual PDeviceStorageRequestParent* AllocPDeviceStorageRequest(const DeviceStorageParams&);
     virtual bool DeallocPDeviceStorageRequest(PDeviceStorageRequestParent*);
 
     virtual PBlobParent* AllocPBlob(const BlobConstructorParams& aParams);
     virtual bool DeallocPBlob(PBlobParent*);
 
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -18,25 +18,20 @@ FAIL_ON_WARNINGS := 1
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 TEST_DIRS += tests
 endif
 
 EXPORTS = PCOMContentPermissionRequestChild.h
 
 EXPORTS_NAMESPACES = \
-  mozilla \
   mozilla/dom \
   mozilla/dom/ipc \
   $(NULL)
 
-EXPORTS_mozilla = \
-  AppProcessPermissions.h \
-  $(NULL)
-
 EXPORTS_mozilla/dom = \
   ContentChild.h \
   ContentParent.h \
   ContentProcess.h \
   CrashReporterChild.h \
   CrashReporterParent.h \
   PermissionMessageUtils.h \
   StructuredCloneUtils.h \
@@ -47,17 +42,16 @@ EXPORTS_mozilla/dom = \
 
 EXPORTS_mozilla/dom/ipc = \
   Blob.h \
   ProcessPriorityManager.h \
   nsIRemoteBlob.h \
   $(NULL)
 
 CPPSRCS = \
-  AppProcessPermissions.cpp \
   Blob.cpp \
   ContentProcess.cpp \
   ContentParent.cpp \
   ContentChild.cpp \
   CrashReporterParent.cpp \
   CrashReporterChild.cpp \
   PermissionMessageUtils.cpp \
   ProcessPriorityManager.cpp \
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -117,21 +117,16 @@ struct MysteryBlobConstructorParams
 union BlobConstructorParams
 {
   NormalBlobConstructorParams;
   FileBlobConstructorParams;
   SlicedBlobConstructorParams;
   MysteryBlobConstructorParams;
 };
 
-union AppId {
-  uint32_t;
-  nullable PBrowser;
-};
-
 rpc protocol PContent
 {
     parent opens PCompositor;
 
     manages PAudio;
     manages PBlob;
     manages PBrowser;
     manages PCrashReporter;
@@ -145,26 +140,19 @@ rpc protocol PContent
     manages PStorage;
     manages PTestShell;
 
 both:
     // Depending on exactly how the new browser is being created, it might be
     // created from either the child or parent process!
     //
     // The child creates the PBrowser as part of
-    // TabChild::BrowserFrameProvideWindow, and the parent creates the
-    // PBrowser as part of ContentParent::CreateTab.
-    //
-    // When the parent constructs a PBrowser, the app ID handed to the
-    // child side is trusted.  In that case, |appId| is uint32_t.
-    // However, when the child side constructs a PBrowser, for
-    // window.open(), the parent must validate the app ID used on the
-    // parent side.  To do so, the child process must pass a valid
-    // PBrowser as its |AppId|.
-    async PBrowser(PRUint32 chromeFlags, bool isBrowserElement, AppId appId);
+    // TabChild::BrowserFrameProvideWindow, and the parent creates the PBrowser
+    // as part of ContentParent::CreateTab.
+    async PBrowser(PRUint32 chromeFlags, bool isBrowserElement, PRUint32 appId);
 
     async PBlob(BlobConstructorParams params);
 
 child:
     PMemoryReportRequest();
 
     PTestShell();
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -417,23 +417,20 @@ TabChild::BrowserFrameProvideWindow(nsID
                                     nsIURI* aURI,
                                     const nsAString& aName,
                                     const nsACString& aFeatures,
                                     bool* aWindowIsNew,
                                     nsIDOMWindow** aReturn)
 {
   *aReturn = nullptr;
 
-  PRUint32 chromeFlags = 0;
-  nsRefPtr<TabChild> newChild = new TabChild(chromeFlags,
-                                             mIsBrowserElement, mAppId);
-  static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
-                             // We release this ref in DeallocPBrowserChild
-                             nsRefPtr<TabChild>(newChild).forget().get(),
-                             chromeFlags, mIsBrowserElement, this));
+  nsRefPtr<TabChild> newChild =
+    static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
+      /* aChromeFlags = */ 0, mIsBrowserElement, mAppId));
+
   nsCAutoString spec;
   if (aURI) {
     aURI->GetSpec(spec);
   }
 
   NS_ConvertUTF8toUTF16 url(spec);
   nsString name(aName);
   NS_ConvertUTF8toUTF16 features(aFeatures);
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -153,18 +153,16 @@ public:
      * |aIsBrowserElement| indicates whether the tab is inside an <iframe mozbrowser>.
      * |aAppId| is the app id of the app containing this tab. If the tab isn't
      * contained in an app, aAppId will be nsIScriptSecurityManager::NO_APP_ID.
      */
     TabChild(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId);
     virtual ~TabChild();
     nsresult Init();
 
-    PRUint32 GetAppId() { return mAppId; }
-
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBBROWSERCHROME
     NS_DECL_NSIWEBBROWSERCHROME2
     NS_DECL_NSIEMBEDDINGSITEWINDOW
     NS_DECL_NSIWEBBROWSERCHROMEFOCUS
     NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSIWINDOWPROVIDER
     NS_DECL_NSIDIALOGCREATOR
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -6,87 +6,81 @@
 
 #include "base/basictypes.h"
 
 #include "TabParent.h"
 
 #include "Blob.h"
 #include "IDBFactory.h"
 #include "IndexedDBParent.h"
-#include "mozIApplication.h"
 #include "mozilla/BrowserElementParent.h"
 #include "mozilla/docshell/OfflineCacheUpdateParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "nsCOMPtr.h"
 #include "nsContentPermissionHelper.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsEventDispatcher.h"
 #include "nsFocusManager.h"
 #include "nsFrameLoader.h"
 #include "nsIContent.h"
-#include "nsIDOMApplicationRegistry.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIDialogCreator.h"
 #include "nsIPromptFactory.h"
 #include "nsIURI.h"
 #include "nsIMozBrowserFrame.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsIViewManager.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsPrintfCString.h"
 #include "nsSerializationHelper.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "StructuredCloneUtils.h"
 #include "TabChild.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
-using namespace mozilla::services;
 using namespace mozilla::widget;
 using namespace mozilla::dom::indexedDB;
 
 // The flags passed by the webProgress notifications are 16 bits shifted
 // from the ones registered by webProgressListeners.
 #define NOTIFY_FLAG_SHIFT 16
 
 namespace mozilla {
 namespace dom {
 
 TabParent *TabParent::mIMETabParent = nullptr;
 
 NS_IMPL_ISUPPORTS3(TabParent, nsITabParent, nsIAuthPromptProvider, nsISecureBrowserUI)
 
-TabParent::TabParent(mozIApplication* aApp, bool aIsBrowserElement)
+TabParent::TabParent()
   : mFrameElement(NULL)
-  , mApp(aApp)
   , mIMESelectionAnchor(0)
   , mIMESelectionFocus(0)
   , mIMEComposing(false)
   , mIMECompositionEnding(false)
   , mIMECompositionStart(0)
   , mIMESeqno(0)
   , mDPI(0)
   , mActive(false)
-  , mIsBrowserElement(aIsBrowserElement)
   , mShown(false)
 {
 }
 
 TabParent::~TabParent()
 {
 }
 
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -19,17 +19,16 @@
 #include "nsIDialogParamBlock.h"
 #include "nsISecureBrowserUI.h"
 #include "nsITabParent.h"
 #include "nsWeakReference.h"
 
 struct gfxMatrix;
 struct JSContext;
 struct JSObject;
-class mozIApplication;
 class nsFrameLoader;
 class nsIDOMElement;
 class nsIURI;
 
 namespace mozilla {
 
 namespace layers {
 struct FrameMetrics;
@@ -49,28 +48,25 @@ class ContentDialogParent : public PCont
 class TabParent : public PBrowserParent 
                 , public nsITabParent 
                 , public nsIAuthPromptProvider
                 , public nsISecureBrowserUI
 {
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
-    TabParent(mozIApplication* aApp, bool aIsBrowserElement);
+    TabParent();
     virtual ~TabParent();
     nsIDOMElement* GetOwnerElement() { return mFrameElement; }
     void SetOwnerElement(nsIDOMElement* aElement);
     nsIBrowserDOMWindow *GetBrowserDOMWindow() { return mBrowserDOMWindow; }
     void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserDOMWindow) {
         mBrowserDOMWindow = aBrowserDOMWindow;
     }
  
-    mozIApplication* GetApp() { return mApp; }
-    bool IsBrowserElement() { return mIsBrowserElement; }
-
     void Destroy();
 
     virtual bool RecvMoveFocus(const bool& aForward);
     virtual bool RecvEvent(const RemoteDOMEvent& aEvent);
     virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                             const nsString& aURL,
                                             const nsString& aName,
                                             const nsString& aFeatures,
@@ -224,33 +220,31 @@ protected:
     bool AllowContentIME();
 
     virtual PRenderFrameParent* AllocPRenderFrame(ScrollingBehavior* aScrolling,
                                                   LayersBackend* aBackend,
                                                   int32_t* aMaxTextureSize,
                                                   uint64_t* aLayersId) MOZ_OVERRIDE;
     virtual bool DeallocPRenderFrame(PRenderFrameParent* aFrame) MOZ_OVERRIDE;
 
-    nsCOMPtr<mozIApplication> mApp;
     // IME
     static TabParent *mIMETabParent;
     nsString mIMECacheText;
     PRUint32 mIMESelectionAnchor;
     PRUint32 mIMESelectionFocus;
     bool mIMEComposing;
     bool mIMECompositionEnding;
     // Buffer to store composition text during ResetInputState
     // Compositions in almost all cases are small enough for nsAutoString
     nsAutoString mIMECompositionText;
     PRUint32 mIMECompositionStart;
     PRUint32 mIMESeqno;
 
     float mDPI;
     bool mActive;
-    bool mIsBrowserElement;
     bool mShown;
 
 private:
     already_AddRefed<nsFrameLoader> GetFrameLoader() const;
     already_AddRefed<nsIWidget> GetWidget() const;
     layout::RenderFrameParent* GetRenderFrame();
     void TryCacheDPI();
     // Return true iff this TabParent was created for a mozbrowser