Backed out changeset ef4884e40bb4 (bug 836654)
authorEd Morley <emorley@mozilla.com>
Thu, 14 Feb 2013 10:02:32 +0000
changeset 131751 8443f568ecde7c031e2abd229710f6d838c6be6c
parent 131750 3150005010d9b6686cae272486f0728cb9def828
child 131752 a93b93dc2d4b69fc0eaa3b61b541abea72e90d1a
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs836654
milestone21.0a1
backs outef4884e40bb4dbd501d3eecc470e3cf6ee43d951
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset ef4884e40bb4 (bug 836654)
b2g/app/b2g.js
content/base/src/nsFrameLoader.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/messages/SystemMessageManager.js
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -575,21 +575,16 @@ pref("hal.processPriorityManager.gonk.ba
 #ifndef DEBUG
 // Enable pre-launching content processes for improved startup time
 // (hiding latency).
 pref("dom.ipc.processPrelaunch.enabled", true);
 // Wait this long before pre-launching a new subprocess.
 pref("dom.ipc.processPrelaunch.delayMs", 5000);
 #endif
 
-// When a process receives a system message, we hold a CPU wake lock on its
-// behalf for this many seconds, or until it handles the system message,
-// whichever comes first.
-pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
-
 // Ignore the "dialog=1" feature in window.open.
 pref("dom.disable_window_open_dialog_feature", true);
 
 // Screen reader support
 pref("accessibility.accessfu.activate", 2);
 
 // Enable hit-target fluffing
 pref("ui.touch.radius.enabled", false);
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -94,17 +94,16 @@
 
 #include "mozilla/dom/StructuredCloneUtils.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #endif
 
 using namespace mozilla;
-using namespace mozilla::hal;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 typedef FrameMetrics::ViewID ViewID;
 
 class nsAsyncDocShellDestroyer : public nsRunnable
 {
@@ -2056,19 +2055,21 @@ nsFrameLoader::TryRemoteBrowser()
   }
   if (ownApp) {
     context.SetTabContextForAppFrame(ownApp, containingApp, scrollingBehavior);
   } else if (OwnerIsBrowserFrame()) {
     // The |else| above is unnecessary; OwnerIsBrowserFrame() implies !ownApp.
     context.SetTabContextForBrowserFrame(containingApp, scrollingBehavior);
   }
 
-  nsCOMPtr<nsIDOMElement> ownerElement = do_QueryInterface(mOwnerContent);
-  mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement);
+  mRemoteBrowser = ContentParent::CreateBrowserOrApp(context);
   if (mRemoteBrowser) {
+    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
+    mRemoteBrowser->SetOwnerElement(element);
+
     // If we're an app, send the frame element's mozapptype down to the child
     // process.  This ends up in TabChild::GetAppType().
     if (ownApp) {
       nsAutoString appType;
       mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapptype, appType);
       mRemoteBrowser->SendSetAppType(appType);
     }
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -225,49 +225,16 @@ ConsoleListener::Observe(nsIConsoleMessa
 
     nsXPIDLString msg;
     nsresult rv = aMessage->GetMessageMoz(getter_Copies(msg));
     NS_ENSURE_SUCCESS(rv, rv);
     mChild->SendConsoleMessage(msg);
     return NS_OK;
 }
 
-class SystemMessageHandledObserver MOZ_FINAL : public nsIObserver
-{
-public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIOBSERVER
-
-    void Init();
-};
-
-void SystemMessageHandledObserver::Init()
-{
-    nsCOMPtr<nsIObserverService> os =
-        mozilla::services::GetObserverService();
-
-    if (os) {
-        os->AddObserver(this, "SystemMessageManager:HandleMessageDone",
-                        /* ownsWeak */ false);
-    }
-}
-
-NS_IMETHODIMP
-SystemMessageHandledObserver::Observe(nsISupports* aSubject,
-                                      const char* aTopic,
-                                      const PRUnichar* aData)
-{
-    if (ContentChild::GetSingleton()) {
-        ContentChild::GetSingleton()->SendSystemMessageHandled();
-    }
-    return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS1(SystemMessageHandledObserver, nsIObserver)
-
 ContentChild* ContentChild::sSingleton;
 
 ContentChild::ContentChild()
  : mID(uint64_t(-1))
 #ifdef ANDROID
    ,mScreenSize(0, 0)
 #endif
 {
@@ -375,21 +342,16 @@ ContentChild::InitXPCOM()
         NS_WARNING("Couldn't register console listener for child process");
 
     bool isOffline;
     SendGetXPCOMProcessAttributes(&isOffline);
     RecvSetOffline(isOffline);
 
     DebugOnly<FileUpdateDispatcher*> observer = FileUpdateDispatcher::GetSingleton();
     NS_ASSERTION(observer, "FileUpdateDispatcher is null");
-
-    // This object is held alive by the observer service.
-    nsRefPtr<SystemMessageHandledObserver> sysMsgObserver =
-        new SystemMessageHandledObserver();
-    sysMsgObserver->Init();
 }
 
 PMemoryReportRequestChild*
 ContentChild::AllocPMemoryReportRequest()
 {
     return new MemoryReportRequestChild();
 }
 
@@ -568,22 +530,21 @@ ContentChild::AllocPBrowser(const IPCTab
     static bool hasRunOnce = false;
     if (!hasRunOnce) {
         hasRunOnce = true;
 
         MOZ_ASSERT(!sFirstIdleTask);
         sFirstIdleTask = NewRunnableFunction(FirstIdle);
         MessageLoop::current()->PostIdleTask(FROM_HERE, sFirstIdleTask);
 
-        // We are either a brand-new process loading its first PBrowser, or we
-        // are the preallocated process transforming into a particular
-        // app/browser.  Either way, our parent has already set our process
-        // priority, and we want to leave it there for a few seconds while we
-        // start up.
-        TemporarilyLockProcessPriority();
+        // If we are the preallocated process transforming into an app process,
+        // we'll have background priority at this point.  Give ourselves a
+        // priority boost for a few seconds, so we don't get killed while we're
+        // loading our first TabChild.
+        TemporarilySetProcessPriorityToForeground();
     }
 
     // We'll happily accept any kind of IPCTabContext here; we don't need to
     // check that it's of a certain type for security purposes, because we
     // believe whatever the parent process tells us.
 
     nsRefPtr<TabChild> child = TabChild::Create(TabContext(aContext), aChromeFlags);
 
@@ -1171,9 +1132,9 @@ ContentChild::RecvFileSystemUpdate(const
     unused << aName;
     unused << aState;
     unused << aMountGeneration;
 #endif
     return true;
 }
 
 } // namespace dom
-} // namespace mozilla
+} // namespace mozilla
\ No newline at end of file
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -23,17 +23,16 @@
 #include "IHistory.h"
 #include "IDBFactory.h"
 #include "IndexedDBParent.h"
 #include "IndexedDatabaseManager.h"
 #include "mozIApplication.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/ExternalHelperAppParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
-#include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/StorageParent.h"
 #include "mozilla/dom/bluetooth/PBluetoothParent.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
 #include "SmsParent.h"
 #include "mozilla/Hal.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/layers/CompositorParent.h"
@@ -57,21 +56,19 @@
 #include "nsDOMFile.h"
 #include "nsExternalHelperAppService.h"
 #include "nsFrameMessageManager.h"
 #include "nsHashPropertyBag.h"
 #include "nsIAlertsService.h"
 #include "nsIClipboard.h"
 #include "nsIDOMApplicationRegistry.h"
 #include "nsIDOMGeoGeolocation.h"
-#include "nsIDOMWakeLock.h"
 #include "nsIDOMWindow.h"
 #include "nsIFilePicker.h"
 #include "nsIMemoryReporter.h"
-#include "nsIMozBrowserFrame.h"
 #include "nsIMutable.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIRemoteBlob.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIWindowWatcher.h"
@@ -116,19 +113,18 @@ using namespace mozilla::system;
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 static const char* sClipboardTextFlavors[] = { kUnicodeMime };
 
 using base::ChildPrivileges;
 using base::KillProcess;
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::devicestorage;
+using namespace mozilla::dom::sms;
 using namespace mozilla::dom::indexedDB;
-using namespace mozilla::dom::power;
-using namespace mozilla::dom::sms;
 using namespace mozilla::hal;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::net;
 
 namespace mozilla {
 namespace dom {
 
@@ -224,18 +220,17 @@ ContentParent::PreallocateAppProcess()
         sPreallocateAppProcessTask = nullptr;
     }
 
     sPreallocatedAppProcess =
         new ContentParent(MAGIC_PREALLOCATED_APP_MANIFEST_URL,
                           /*isBrowserElement=*/false,
                           // Final privileges are set when we
                           // transform into our app.
-                          base::PRIVILEGES_INHERIT,
-                          PROCESS_PRIORITY_BACKGROUND);
+                          base::PRIVILEGES_INHERIT);
     sPreallocatedAppProcess->Init();
 }
 
 /*static*/ void
 ContentParent::DelayedPreallocateAppProcess()
 {
     sPreallocateAppProcessTask = nullptr;
     if (!sPreallocatedAppProcess) {
@@ -252,28 +247,29 @@ ContentParent::ScheduleDelayedPreallocat
     sPreallocateAppProcessTask =
         NewRunnableFunction(DelayedPreallocateAppProcess);
     MessageLoop::current()->PostDelayedTask(
         FROM_HERE, sPreallocateAppProcessTask, sPreallocateDelayMs);
 }
 
 /*static*/ already_AddRefed<ContentParent>
 ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
-                                               ChildPrivileges aPrivs,
-                                               ProcessPriority aInitialPriority)
+                                               ChildPrivileges aPrivs)
 {
     nsRefPtr<ContentParent> process = sPreallocatedAppProcess.get();
     sPreallocatedAppProcess = nullptr;
 
     if (!process) {
         return nullptr;
     }
 
-    if (!process->TransformPreallocatedIntoApp(aAppManifestURL, aPrivs,
-                                               aInitialPriority)) {
+    if (!process->TransformPreallocatedIntoApp(aAppManifestURL, aPrivs)) {
+        NS_WARNING("Can't TransformPrealocatedIntoApp.  Maybe "
+                   "the preallocated process died?");
+
         // Kill the process just in case it's not actually dead; we don't want
         // to "leak" this process!
         process->KillHard();
         return nullptr;
     }
 
     return process.forget();
 }
@@ -381,19 +377,17 @@ ContentParent::GetNewOrUsed(bool aForBro
         uint32_t 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(),
-                          aForBrowserElement,
-                          base::PRIVILEGES_DEFAULT,
-                          PROCESS_PRIORITY_FOREGROUND);
+                          aForBrowserElement);
     p->Init();
     gNonAppContentParents->AppendElement(p);
     return p;
 }
 
 namespace {
 struct SpecialPermission {
     const char* perm;           // an app permission
@@ -420,56 +414,26 @@ PrivilegesForApp(mozIApplication* aApp)
             break;
         } else if (hasPermission) {
             return specialPermissions[i].privs;
         }
     }
     return base::PRIVILEGES_DEFAULT;
 }
 
-/*static*/ ProcessPriority
-ContentParent::GetInitialProcessPriority(nsIDOMElement* aFrameElement)
-{
-    // Frames with mozapptype == critical which are expecting a system message
-    // get FOREGROUND_HIGH priority.  All other frames get FOREGROUND priority.
-
-    if (!aFrameElement) {
-        return PROCESS_PRIORITY_FOREGROUND;
-    }
-
-    nsAutoString appType;
-    nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
-    frameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapptype, appType);
-    if (appType != NS_LITERAL_STRING("critical")) {
-        return PROCESS_PRIORITY_FOREGROUND;
-    }
-
-    nsCOMPtr<nsIMozBrowserFrame> browserFrame =
-        do_QueryInterface(aFrameElement);
-    if (!browserFrame) {
-        return PROCESS_PRIORITY_FOREGROUND;
-    }
-
-    return browserFrame->GetIsExpectingSystemMessage() ?
-               PROCESS_PRIORITY_FOREGROUND_HIGH :
-               PROCESS_PRIORITY_FOREGROUND;
-}
-
 /*static*/ TabParent*
-ContentParent::CreateBrowserOrApp(const TabContext& aContext,
-                                  nsIDOMElement* aFrameElement)
+ContentParent::CreateBrowserOrApp(const TabContext& aContext)
 {
     if (!sCanLaunchSubprocesses) {
         return nullptr;
     }
 
     if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
         if (ContentParent* cp = GetNewOrUsed(aContext.IsBrowserElement())) {
             nsRefPtr<TabParent> tp(new TabParent(aContext));
-            tp->SetOwnerElement(aFrameElement);
             PBrowserParent* browser = cp->SendPBrowserConstructor(
                 tp.forget().get(), // DeallocPBrowserParent() releases this ref.
                 aContext.AsIPCTabContext(),
                 /* chromeFlags */ 0);
             return static_cast<TabParent*>(browser);
         }
         return nullptr;
     }
@@ -489,34 +453,28 @@ ContentParent::CreateBrowserOrApp(const 
     nsAutoString manifestURL;
     if (NS_FAILED(ownApp->GetManifestURL(manifestURL))) {
         NS_ERROR("Failed to get manifest URL");
         return nullptr;
     }
 
     nsRefPtr<ContentParent> p = gAppContentParents->Get(manifestURL);
     if (!p) {
-        ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
-
         ChildPrivileges privs = PrivilegesForApp(ownApp);
-        p = MaybeTakePreallocatedAppProcess(manifestURL, privs,
-                                            initialPriority);
+        p = MaybeTakePreallocatedAppProcess(manifestURL, privs);
         if (!p) {
             NS_WARNING("Unable to use pre-allocated app process");
             p = new ContentParent(manifestURL, /* isBrowserElement = */ false,
-                                  privs, initialPriority);
+                                  privs);
             p->Init();
         }
         gAppContentParents->Put(manifestURL, p);
     }
 
-    p->MaybeTakeCPUWakeLock(aFrameElement);
-
     nsRefPtr<TabParent> tp = new TabParent(aContext);
-    tp->SetOwnerElement(aFrameElement);
     PBrowserParent* browser = p->SendPBrowserConstructor(
         tp.forget().get(), // DeallocPBrowserParent() releases this ref.
         aContext.AsIPCTabContext(),
         /* chromeFlags */ 0);
     return static_cast<TabParent*>(browser);
 }
 
 static PLDHashOperator
@@ -583,146 +541,33 @@ ContentParent::Init()
         unused << SendActivateA11y();
     }
 #endif
 
     DebugOnly<FileUpdateDispatcher*> observer = FileUpdateDispatcher::GetSingleton();
     NS_ASSERTION(observer, "FileUpdateDispatcher is null");
 }
 
-namespace {
-
-class SystemMessageHandledListener MOZ_FINAL
-    : public nsITimerCallback
-    , public LinkedListElement<SystemMessageHandledListener>
-{
-public:
-    NS_DECL_ISUPPORTS
-
-    SystemMessageHandledListener() {}
-
-    static void OnSystemMessageHandled()
-    {
-        if (!sListeners) {
-            return;
-        }
-
-        SystemMessageHandledListener* listener = sListeners->popFirst();
-        if (!listener) {
-            return;
-        }
-
-        // Careful: ShutDown() may delete |this|.
-        listener->ShutDown();
-    }
-
-    void Init(nsIDOMMozWakeLock* aWakeLock)
-    {
-        MOZ_ASSERT(!mWakeLock);
-        MOZ_ASSERT(!mTimer);
-
-        // mTimer keeps a strong reference to |this|.  When this object's
-        // destructor runs, it will remove itself from the LinkedList.
-
-        if (!sListeners) {
-            sListeners = new LinkedList<SystemMessageHandledListener>();
-            ClearOnShutdown(&sListeners);
-        }
-        sListeners->insertBack(this);
-
-        mWakeLock = aWakeLock;
-
-        mTimer = do_CreateInstance("@mozilla.org/timer;1");
-
-        uint32_t timeoutSec =
-            Preferences::GetInt("dom.ipc.systemMessageCPULockTimeoutSec", 30);
-        mTimer->InitWithCallback(this, timeoutSec * 1000,
-                                 nsITimer::TYPE_ONE_SHOT);
-    }
-
-    NS_IMETHOD Notify(nsITimer* aTimer)
-    {
-        // Careful: ShutDown() may delete |this|.
-        ShutDown();
-        return NS_OK;
-    }
-
-private:
-    static StaticAutoPtr<LinkedList<SystemMessageHandledListener> > sListeners;
-
-    void ShutDown()
-    {
-        nsRefPtr<SystemMessageHandledListener> kungFuDeathGrip = this;
-
-        mWakeLock->Unlock();
-
-        if (mTimer) {
-            mTimer->Cancel();
-            mTimer = nullptr;
-        }
-    }
-
-    nsCOMPtr<nsIDOMMozWakeLock> mWakeLock;
-    nsCOMPtr<nsITimer> mTimer;
-};
-
-StaticAutoPtr<LinkedList<SystemMessageHandledListener> >
-    SystemMessageHandledListener::sListeners;
-
-NS_IMPL_ISUPPORTS1(SystemMessageHandledListener,
-                   nsITimerCallback)
-
-} // anonymous namespace
-
-void
-ContentParent::SetProcessInitialPriority(ProcessPriority aInitialPriority)
-{
-    if (!Preferences::GetBool("dom.ipc.processPriorityManager.enabled")) {
-        return;
-    }
-
-    SetProcessPriority(base::GetProcId(mSubprocess->GetChildProcessHandle()),
-                       aInitialPriority);
-}
-
-void
-ContentParent::MaybeTakeCPUWakeLock(nsIDOMElement* aFrameElement)
-{
-    // Take the CPU wake lock on behalf of this processs if it's expecting a
-    // system message.  We'll release the CPU lock once the message is
-    // delivered, or after some period of time, which ever comes first.
-
-    nsCOMPtr<nsIMozBrowserFrame> browserFrame =
-        do_QueryInterface(aFrameElement);
-    if (!browserFrame ||
-        !browserFrame->GetIsExpectingSystemMessage()) {
-        return;
-    }
-
-    nsRefPtr<PowerManagerService> pms = PowerManagerService::GetInstance();
-    nsCOMPtr<nsIDOMMozWakeLock> lock =
-        pms->NewWakeLockOnBehalfOfProcess(NS_LITERAL_STRING("cpu"), this);
-
-    // This object's Init() function keeps it alive.
-    nsRefPtr<SystemMessageHandledListener> listener =
-        new SystemMessageHandledListener();
-    listener->Init(lock);
-}
-
 bool
 ContentParent::TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
-                                            ChildPrivileges aPrivs,
-                                            ProcessPriority aInitialPriority)
+                                            ChildPrivileges aPrivs)
 {
     MOZ_ASSERT(mAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL);
     // Clients should think of mAppManifestURL as const ... we're
     // bending the rules here just for the preallocation hack.
     const_cast<nsString&>(mAppManifestURL) = aAppManifestURL;
 
-    SetProcessInitialPriority(aInitialPriority);
+    // Boost this process's priority.  The subprocess will call
+    // TemporarilySetProcessPriorityToForeground() from within
+    // ContentChild::AllocPBrowser, but this happens earlier, thus reducing the
+    // window in which the child might be killed due to low memory.
+    if (Preferences::GetBool("dom.ipc.processPriorityManager.enabled")) {
+        SetProcessPriority(base::GetProcId(mSubprocess->GetChildProcessHandle()),
+                           PROCESS_PRIORITY_FOREGROUND);
+    }
 
     // Now that we've increased the process's priority from BACKGROUND (where
     // the preallocated app sits) to something higher, check whether the process
     // is still alive.  Hopefully the process won't unexpectedly crash after
     // this point!
     //
     // It's not legal to call DidProcessCrash on Windows if the process has not
     // terminated yet, so we have to skip this check there.
@@ -1037,18 +882,17 @@ ContentParent::GetTestShellSingleton()
 {
     if (!ManagedPTestShellParent().Length())
         return nullptr;
     return static_cast<TestShellParent*>(ManagedPTestShellParent()[0]);
 }
 
 ContentParent::ContentParent(const nsAString& aAppManifestURL,
                              bool aIsForBrowser,
-                             ChildPrivileges aOSPrivileges,
-                             ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
+                             ChildPrivileges aOSPrivileges)
     : mSubprocess(nullptr)
     , mOSPrivileges(aOSPrivileges)
     , mChildID(CONTENT_PROCESS_ID_UNKNOWN)
     , mGeolocationWatchID(-1)
     , mRunToCompletionDepth(0)
     , mShouldCallUnblockChild(false)
     , mAppManifestURL(aAppManifestURL)
     , mForceKillTask(nullptr)
@@ -1063,20 +907,30 @@ ContentParent::ContentParent(const nsASt
     nsDebugImpl::SetMultiprocessMode("Parent");
 
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content,
                                             aOSPrivileges);
 
     mSubprocess->LaunchAndWaitForProcessHandle();
 
-    // Set the subprocess's priority.  We do this first because we're likely
-    // /lowering/ its CPU and memory priority, which it has inherited from this
-    // process.
-    SetProcessInitialPriority(aInitialPriority);
+    // Set the subprocess's priority (bg if we're a preallocated process, fg
+    // otherwise).  We do this first because we're likely /lowering/ its CPU and
+    // memory priority, which it has inherited from this process.
+    if (Preferences::GetBool("dom.ipc.processPriorityManager.enabled")) {
+        ProcessPriority priority;
+        if (aAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL) {
+            priority = PROCESS_PRIORITY_BACKGROUND;
+        } else {
+            priority = PROCESS_PRIORITY_FOREGROUND;
+        }
+
+        SetProcessPriority(base::GetProcId(mSubprocess->GetChildProcessHandle()),
+                           priority);
+    }
 
     Open(mSubprocess->GetChannel(), mSubprocess->GetChildProcessHandle());
 
     // NB: internally, this will send an IPC message to the child
     // process to get it to create the CompositorChild.  This
     // message goes through the regular IPC queue for this
     // channel, so delivery will happen-before any other messages
     // we send.  The CompositorChild must be created before any
@@ -2452,17 +2306,10 @@ ContentParent::CheckManifestURL(const ns
 }
 
 bool
 ContentParent::CheckAppHasPermission(const nsAString& aPermission)
 {
   return AssertAppHasPermission(this, NS_ConvertUTF16toUTF8(aPermission).get());
 }
 
-bool
-ContentParent::RecvSystemMessageHandled()
-{
-    SystemMessageHandledListener::OnSystemMessageHandled();
-    return true;
-}
-
 } // namespace dom
-} // namespace mozilla
+} // namespace mozilla
\ No newline at end of file
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -79,23 +79,19 @@ public:
      * very expensive in general.  It also bypasses the normal
      * shutdown process.
      */
     static void JoinAllSubprocesses();
 
     static ContentParent* GetNewOrUsed(bool aForBrowserElement = false);
 
     /**
-     * Get or create a content process for the given TabContext.  aFrameElement
-     * should be the frame/iframe element with which this process will
-     * associated.
+     * Get or create a content process for the given TabContext.
      */
-    static TabParent*
-    CreateBrowserOrApp(const TabContext& aContext,
-                       nsIDOMElement* aFrameElement);
+    static TabParent* CreateBrowserOrApp(const TabContext& aContext);
 
     static void GetAll(nsTArray<ContentParent*>& aArray);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
     NS_DECL_NSITHREADOBSERVER
     NS_DECL_NSIDOMGEOPOSITIONCALLBACK
 
@@ -161,51 +157,36 @@ private:
     static void DelayedPreallocateAppProcess();
     static void ScheduleDelayedPreallocateAppProcess();
 
     // Take the preallocated process and transform it into a "real" app process,
     // for the specified manifest URL.  If there is no preallocated process (or
     // if it's dead), this returns false.
     static already_AddRefed<ContentParent>
     MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
-                                    ChildPrivileges aPrivs,
-                                    hal::ProcessPriority aInitialPriority);
-
-    static hal::ProcessPriority GetInitialProcessPriority(nsIDOMElement* aFrameElement);
+                                    ChildPrivileges aPrivs);
 
     static void FirstIdle();
 
     // Hide the raw constructor methods since we don't want client code
     // using them.
     using PContentParent::SendPBrowserConstructor;
     using PContentParent::SendPTestShellConstructor;
 
     ContentParent(const nsAString& aAppManifestURL, bool aIsForBrowser,
-                  ChildPrivileges aOSPrivileges = base::PRIVILEGES_DEFAULT,
-                  hal::ProcessPriority aInitialPriority = hal::PROCESS_PRIORITY_FOREGROUND);
+                  base::ChildPrivileges aOSPrivileges = base::PRIVILEGES_DEFAULT);
     virtual ~ContentParent();
 
     void Init();
 
-    // Set the child process's priority.  Once the child starts up, it will
-    // manage its own priority via the ProcessPriorityManager.
-    void SetProcessInitialPriority(hal::ProcessPriority aInitialPriority);
-
-    // If the frame element indicates that the child process is "critical" and
-    // has a pending system message, this function acquires the CPU wake lock on
-    // behalf of the child.  We'll release the lock when the system message is
-    // handled or after a timeout, whichever comes first.
-    void MaybeTakeCPUWakeLock(nsIDOMElement* aFrameElement);
-
     // Transform a pre-allocated app process into a "real" app
     // process, for the specified manifest URL.  If this returns false, the
     // child process has died.
     bool TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
-                                      ChildPrivileges aPrivs,
-                                      hal::ProcessPriority aInitialPriority);
+                                      ChildPrivileges aPrivs);
 
     /**
      * Mark this ContentParent as dead for the purposes of Get*().
      * This method is idempotent.
      */
     void MarkAsDead();
 
     /**
@@ -361,18 +342,16 @@ private:
                                                 const bool& aElementHidden);
 
     virtual bool RecvAudioChannelChangedNotification();
 
     virtual bool RecvBroadcastVolume(const nsString& aVolumeName);
 
     virtual bool RecvRecordingDeviceEvents(const nsString& aRecordingStatus);
 
-    virtual bool RecvSystemMessageHandled() MOZ_OVERRIDE;
-
     virtual void ProcessingError(Result what) MOZ_OVERRIDE;
 
     GeckoChildProcessHost* mSubprocess;
     base::ChildPrivileges mOSPrivileges;
 
     uint64_t mChildID;
     int32_t mGeolocationWatchID;
     int mRunToCompletionDepth;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -480,17 +480,14 @@ parent:
     async FilePathUpdateNotify(nsString aType,
                                nsString aFilepath,
                                nsCString aReason);
     // get nsIVolumeService to broadcast volume information
     async BroadcastVolume(nsString volumeName);
 
     async RecordingDeviceEvents(nsString recordingStatus);
 
-    // Notify the parent that the child has finished handling a system message.
-    async SystemMessageHandled();
-
 both:
      AsyncMessage(nsString aMessage, ClonedMessageData aData);
 };
 
 }
 }
--- a/dom/messages/SystemMessageManager.js
+++ b/dom/messages/SystemMessageManager.js
@@ -70,19 +70,20 @@ SystemMessageManager.prototype = {
         wrapped = true;
         debug("wrapped = " + aMessage);
       }
     }
 
     aHandler.handleMessage(wrapped ? aMessage
                                    : ObjectWrapper.wrap(aMessage, this._window));
 
-    Services.obs.notifyObservers(/* aSubject */ null,
-                                 "SystemMessageManager:HandleMessageDone",
-                                 /* aData */ null);
+    // Notify the parent process the message is handled.
+    cpmm.sendAsyncMessage("SystemMessageManager:HandleMessageDone",
+                          { type: aType,
+                            message: aMessage });
   },
 
   mozSetMessageHandler: function sysMessMgr_setMessageHandler(aType, aHandler) {
     debug("set message handler for [" + aType + "] " + aHandler);
 
     if (this._isInBrowserElement) {
       debug("the app loaded in the browser cannot set message handler");
       throw Cr.NS_ERROR_FAILURE;