Backout 52be204da1cf (bug 776663), 965397b043c0 (bug 777508), 182c763efa68 (bug 776832), a2a509184b07 & cba5ba69091f (bug 789973) for failures in test_child_process_shutdown_message.html and friends / conflicting with the backout on a CLOSED TREE
authorEd Morley <emorley@mozilla.com>
Fri, 28 Sep 2012 14:08:04 +0100
changeset 108481 dc9d251fdb2e39fcf22e3d096e863b4740bbfe11
parent 108480 cfce5efab7ac5853e3992163a887fbd907c10a39
child 108482 07914b108f91c82f77061ed58391399c7280d1fb
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs776663, 777508, 776832, 789973
milestone18.0a1
backs out52be204da1cfa0c3188d744ba21a5563affc8e34
Backout 52be204da1cf (bug 776663), 965397b043c0 (bug 777508), 182c763efa68 (bug 776832), a2a509184b07 & cba5ba69091f (bug 789973) for failures in test_child_process_shutdown_message.html and friends / conflicting with the backout on a CLOSED TREE
content/base/public/nsIMessageManager.idl
content/base/src/nsCCUncollectableMarker.cpp
content/base/src/nsFrameLoader.cpp
content/base/src/nsFrameLoader.h
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsFrameMessageManager.h
content/base/src/nsInProcessTabChildGlobal.cpp
content/base/src/nsInProcessTabChildGlobal.h
content/base/test/Makefile.in
content/base/test/test_child_process_shutdown_message.html
content/base/test/test_messagemanager_assertpermission.html
content/events/src/nsEventListenerManager.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_worker.js
dom/time/Makefile.in
dom/time/TimeManager.cpp
dom/time/TimeManager.h
dom/time/TimeService.cpp
dom/time/TimeService.h
dom/time/nsITimeService.idl
layout/build/nsLayoutModule.cpp
--- a/content/base/public/nsIMessageManager.idl
+++ b/content/base/public/nsIMessageManager.idl
@@ -330,35 +330,8 @@ interface nsIFrameScriptLoader : nsISupp
    */
   void loadFrameScript(in AString aURL, in boolean aAllowDelayedLoad);
 
   /**
    * Removes aURL from the list of scripts which support delayed load.
    */
   void removeDelayedFrameScript(in AString aURL);
 };
-
-[scriptable, builtinclass, uuid(5f552699-01a2-4f17-833b-ddb3fa0d98b2)]
-interface nsIPermissionChecker : nsISupports
-{
-
-  /**
-   * Return true iff the "remote" process has |aPermission|.  This is
-   * intended to be used by JS implementations of cross-process DOM
-   * APIs, like so
-   *
-   *   recvFooRequest: function(message) {
-   *     if (!message.target.assertPermission("foo")) {
-   *       return false;
-   *     }
-   *     // service foo request
-   *
-   * This interface only returns meaningful data when our content is
-   * in a separate process.  If it shares the same OS process as us,
-   * then applying this permission check doesn't add any security,
-   * though it doesn't hurt anything either.
-   *
-   * Note: If the remote content process does *not* have |aPermission|,
-   * it will be killed as a precaution.
-   */
-  boolean assertPermission(in DOMString aPermission);
-
-};
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -115,21 +115,21 @@ MarkMessageManagers()
       nsCOMPtr<nsIMessageListenerManager> childMM;
       windowMM->GetChildAt(j, getter_AddRefs(childMM));
       if (!childMM) {
         continue;
       }
       nsCOMPtr<nsIMessageSender> tabMM = do_QueryInterface(childMM);
       tabMM->MarkForCC();
       //XXX hack warning, but works, since we know that
-      //    callback is frameloader.
-      mozilla::dom::ipc::MessageManagerCallback* cb =
-        static_cast<nsFrameMessageManager*>(tabMM.get())->GetCallback();
-      if (cb) {
-        nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb);
+      //    callback data is frameloader.
+      void* cb = static_cast<nsFrameMessageManager*>(tabMM.get())->
+        GetCallbackData();
+      nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb);
+      if (fl) {
         nsIDOMEventTarget* et = fl->GetTabChildGlobalAsEventTarget();
         if (!et) {
           continue;
         }
         static_cast<nsInProcessTabChildGlobal*>(et)->MarkForCC();
         nsEventListenerManager* elm = et->GetListenerManager(false);
         if (elm) {
           elm->UnmarkGrayJSListeners();
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -71,17 +71,16 @@
 
 #include "nsThreadUtils.h"
 
 #include "nsIDOMChromeWindow.h"
 #include "nsInProcessTabChildGlobal.h"
 
 #include "Layers.h"
 
-#include "AppProcessPermissions.h"
 #include "ContentParent.h"
 #include "TabParent.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "nsIAppsService.h"
@@ -93,17 +92,16 @@
 #include "mozilla/dom/StructuredCloneUtils.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #endif
 
 using namespace mozilla;
 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
 {
 public:
   nsAsyncDocShellDestroyer(nsIDocShell* aDocShell)
@@ -1239,23 +1237,23 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
   JSContext* thisCx =
     mMessageManager ? mMessageManager->GetJSContext() : nullptr;
   JSContext* otherCx = 
     aOther->mMessageManager ? aOther->mMessageManager->GetJSContext() : nullptr;
   if (mMessageManager) {
     mMessageManager->RemoveFromParent();
     mMessageManager->SetJSContext(otherCx);
     mMessageManager->SetParentManager(otherParentManager);
-    mMessageManager->SetCallback(aOther, false);
+    mMessageManager->SetCallbackData(aOther, false);
   }
   if (aOther->mMessageManager) {
     aOther->mMessageManager->RemoveFromParent();
     aOther->mMessageManager->SetJSContext(thisCx);
     aOther->mMessageManager->SetParentManager(ourParentManager);
-    aOther->mMessageManager->SetCallback(this, false);
+    aOther->mMessageManager->SetCallbackData(this, false);
   }
   mMessageManager.swap(aOther->mMessageManager);
 
   aFirstToSwap.swap(aSecondToSwap);
 
   // Drop any cached content viewers in the two session histories.
   nsCOMPtr<nsISHistoryInternal> ourInternalHistory =
     do_QueryInterface(ourHistory);
@@ -2132,37 +2130,38 @@ nsFrameLoader::CreateStaticClone(nsIFram
   NS_ENSURE_STATE(doc);
   nsCOMPtr<nsIDocument> clonedDoc = doc->CreateStaticClone(dest->mDocShell);
   nsCOMPtr<nsIDOMDocument> clonedDOMDoc = do_QueryInterface(clonedDoc);
 
   viewer->SetDOMDocument(clonedDOMDoc);
   return NS_OK;
 }
 
-bool
-nsFrameLoader::DoLoadFrameScript(const nsAString& aURL)
+bool LoadScript(void* aCallbackData, const nsAString& aURL)
 {
-  mozilla::dom::PBrowserParent* tabParent = GetRemoteBrowser();
+  mozilla::dom::PBrowserParent* tabParent =
+    static_cast<nsFrameLoader*>(aCallbackData)->GetRemoteBrowser();
   if (tabParent) {
     return tabParent->SendLoadRemoteScript(nsString(aURL));
   }
+  nsFrameLoader* fl = static_cast<nsFrameLoader*>(aCallbackData);
   nsRefPtr<nsInProcessTabChildGlobal> tabChild =
-    static_cast<nsInProcessTabChildGlobal*>(GetTabChildGlobalAsEventTarget());
+    static_cast<nsInProcessTabChildGlobal*>(fl->GetTabChildGlobalAsEventTarget());
   if (tabChild) {
     tabChild->LoadFrameScript(aURL);
   }
   return true;
 }
 
 class nsAsyncMessageToChild : public nsRunnable
 {
 public:
   nsAsyncMessageToChild(nsFrameLoader* aFrameLoader,
-                        const nsAString& aMessage,
-                        const StructuredCloneData& aData)
+                              const nsAString& aMessage,
+                              const StructuredCloneData& aData)
     : mFrameLoader(aFrameLoader), mMessage(aMessage)
   {
     if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
       NS_RUNTIMEABORT("OOM");
     }
     mClosure = aData.mClosure;
   }
 
@@ -2185,21 +2184,22 @@ public:
     return NS_OK;
   }
   nsRefPtr<nsFrameLoader> mFrameLoader;
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
 };
 
-bool
-nsFrameLoader::DoSendAsyncMessage(const nsAString& aMessage,
-                                  const StructuredCloneData& aData)
+bool SendAsyncMessageToChild(void* aCallbackData,
+                             const nsAString& aMessage,
+                                   const StructuredCloneData& aData)
 {
-  PBrowserParent* tabParent = GetRemoteBrowser();
+  PBrowserParent* tabParent =
+    static_cast<nsFrameLoader*>(aCallbackData)->GetRemoteBrowser();
   if (tabParent) {
     ClonedMessageData data;
 
     SerializedStructuredCloneBuffer& buffer = data.data();
     buffer.data = aData.mData;
     buffer.dataLength = aData.mDataLength;
 
     const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
@@ -2219,33 +2219,28 @@ nsFrameLoader::DoSendAsyncMessage(const 
 
         blobParents.AppendElement(blobParent);
       }
     }
 
     return tabParent->SendAsyncMessage(nsString(aMessage), data);
   }
 
-  if (mChildMessageManager) {
-    nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(this, aMessage, aData);
+  if (static_cast<nsFrameLoader*>(aCallbackData)->mChildMessageManager) {
+    nsRefPtr<nsIRunnable> ev =
+      new nsAsyncMessageToChild(static_cast<nsFrameLoader*>(aCallbackData),
+                                aMessage, aData);
     NS_DispatchToCurrentThread(ev);
     return true;
   }
 
   // We don't have any targets to send our asynchronous message to.
   return false;
 }
 
-bool
-nsFrameLoader::CheckPermission(const nsAString& aPermission)
-{
-  return AssertAppProcessPermission(GetRemoteBrowser(),
-                                    NS_ConvertUTF16toUTF8(aPermission).get());
-}
-
 NS_IMETHODIMP
 nsFrameLoader::GetMessageManager(nsIMessageSender** aManager)
 {
   EnsureMessageManager();
   if (mMessageManager) {
     CallQueryInterface(mMessageManager, aManager);
   }
   return NS_OK;
@@ -2316,17 +2311,17 @@ nsFrameLoader::EnsureMessageManager()
   }
 
   if (!mIsTopLevelContent && !OwnerIsBrowserFrame() && !mRemoteFrame) {
     return NS_OK;
   }
 
   if (mMessageManager) {
     if (ShouldUseRemoteProcess()) {
-      mMessageManager->SetCallback(mRemoteBrowserShown ? this : nullptr);
+      mMessageManager->SetCallbackData(mRemoteBrowserShown ? this : nullptr);
     }
     return NS_OK;
   }
 
   nsIScriptContext* sctx = mOwnerContent->GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_STATE(sctx);
   JSContext* cx = sctx->GetNativeContext();
@@ -2335,30 +2330,34 @@ nsFrameLoader::EnsureMessageManager()
   nsCOMPtr<nsIDOMChromeWindow> chromeWindow =
     do_QueryInterface(GetOwnerDoc()->GetWindow());
   nsCOMPtr<nsIMessageBroadcaster> parentManager;
   if (chromeWindow) {
     chromeWindow->GetMessageManager(getter_AddRefs(parentManager));
   }
 
   if (ShouldUseRemoteProcess()) {
-    mMessageManager = new nsFrameMessageManager(mRemoteBrowserShown ? this : nullptr,
+    mMessageManager = new nsFrameMessageManager(true, /* aChrome */
+                                                nullptr,
+                                                SendAsyncMessageToChild,
+                                                LoadScript,
+                                                mRemoteBrowserShown ? this : nullptr,
                                                 static_cast<nsFrameMessageManager*>(parentManager.get()),
-                                                cx,
-                                                MM_CHROME);
+                                                cx);
   } else {
-    mMessageManager = new nsFrameMessageManager(nullptr,
+    mMessageManager = new nsFrameMessageManager(true, /* aChrome */
+                                                nullptr,
+                                                SendAsyncMessageToChild,
+                                                LoadScript,
+                                                nullptr,
                                                 static_cast<nsFrameMessageManager*>(parentManager.get()),
-                                                cx,
-                                                MM_CHROME);
-
+                                                cx);
     mChildMessageManager =
       new nsInProcessTabChildGlobal(mDocShell, mOwnerContent, mMessageManager);
-    // Force pending frame scripts to be loaded.
-    mMessageManager->SetCallback(this);
+    mMessageManager->SetCallbackData(this);
   }
   return NS_OK;
 }
 
 nsIDOMEventTarget*
 nsFrameLoader::GetTabChildGlobalAsEventTarget()
 {
   return static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get());
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -33,17 +33,16 @@ class nsITabParent;
 class nsIDocShellTreeItem;
 class nsIDocShellTreeOwner;
 class nsIDocShellTreeNode;
 
 namespace mozilla {
 namespace dom {
 class PBrowserParent;
 class TabParent;
-struct StructuredCloneData;
 }
 
 namespace layout {
 class RenderFrameParent;
 }
 }
 
 #ifdef MOZ_WIDGET_GTK2
@@ -136,18 +135,17 @@ private:
 
   ViewID mScrollId;
   ViewConfig mConfig;
 };
 
 
 class nsFrameLoader MOZ_FINAL : public nsIFrameLoader,
                                 public nsIContentViewManager,
-                                public nsStubMutationObserver,
-                                public mozilla::dom::ipc::MessageManagerCallback
+                                public nsStubMutationObserver
 {
   friend class AutoResetInShow;
   typedef mozilla::dom::PBrowserParent PBrowserParent;
   typedef mozilla::dom::TabParent TabParent;
   typedef mozilla::layout::RenderFrameParent RenderFrameParent;
 
 protected:
   nsFrameLoader(mozilla::dom::Element* aOwner, bool aNetworkCreated);
@@ -177,25 +175,16 @@ public:
   NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI);
   nsresult ReallyStartLoading();
   void Finalize();
   nsIDocShell* GetExistingDocShell() { return mDocShell; }
   nsIDOMEventTarget* GetTabChildGlobalAsEventTarget();
   nsresult CreateStaticClone(nsIFrameLoader* aDest);
 
   /**
-   * MessageManagerCallback methods that we override.
-   */
-  virtual bool DoLoadFrameScript(const nsAString& aURL);
-  virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                  const mozilla::dom::StructuredCloneData& aData);
-  virtual bool CheckPermission(const nsAString& aPermission);
-
-
-  /**
    * Called from the layout frame associated with this frame loader;
    * this notifies us to hook up with the widget and view.
    */
   bool Show(int32_t marginWidth, int32_t marginHeight,
               int32_t scrollbarPrefX, int32_t scrollbarPrefY,
               nsSubDocumentFrame* frame);
 
   /**
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -2,28 +2,26 @@
 /* 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 "base/basictypes.h"
 
 #include "nsFrameMessageManager.h"
 
-#include "AppProcessPermissions.h"
 #include "ContentChild.h"
 #include "ContentParent.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "nsJSUtils.h"
 #include "nsJSPrincipals.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
-#include "nsFrameLoader.h"
 #include "nsIJSContextStack.h"
 #include "nsIXULRuntime.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIJSRuntimeService.h"
 #include "nsIDOMClassInfo.h"
@@ -36,18 +34,16 @@
 #include <android/log.h>
 #endif
 #ifdef XP_WIN
 #include <windows.h>
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
-using namespace mozilla::dom::ipc;
-
 
 static bool
 IsChromeProcess()
 {
   nsCOMPtr<nsIXULRuntime> rt = do_GetService("@mozilla.org/xre/runtime;1");
   if (!rt)
     return true;
 
@@ -102,20 +98,16 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   /* nsIContentFrameMessageManager is accessible only in TabChildGlobal. */
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIContentFrameMessageManager,
                                      !mChrome && !mIsProcessManager)
 
   /* Frame message managers (non-process message managers) support nsIFrameScriptLoader. */
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFrameScriptLoader,
                                      mChrome && !mIsProcessManager)
 
-  /* Message senders in the chrome process support nsIPermissionChecker. */
-  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIPermissionChecker,
-                                     mChrome && !mIsBroadcaster)
-
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(ChromeMessageBroadcaster,
                                                    mChrome && mIsBroadcaster)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(ChromeMessageSender,
                                                    mChrome && !mIsBroadcaster)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameMessageManager)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameMessageManager)
@@ -162,28 +154,28 @@ nsFrameMessageManager::RemoveMessageList
 NS_IMETHODIMP
 nsFrameMessageManager::LoadFrameScript(const nsAString& aURL,
                                        bool aAllowDelayedLoad)
 {
   if (aAllowDelayedLoad) {
     if (IsGlobal() || IsWindowLevel()) {
       // Cache for future windows or frames
       mPendingScripts.AppendElement(aURL);
-    } else if (!mCallback) {
+    } else if (!mCallbackData) {
       // We're frame message manager, which isn't connected yet.
       mPendingScripts.AppendElement(aURL);
       return NS_OK;
     }
   }
 
-  if (mCallback) {
+  if (mCallbackData) {
 #ifdef DEBUG_smaug
     printf("Will load %s \n", NS_ConvertUTF16toUTF8(aURL).get());
 #endif
-    NS_ENSURE_TRUE(mCallback->DoLoadFrameScript(aURL), NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(mLoadScriptCallback(mCallbackData, aURL), NS_ERROR_FAILURE);
   }
 
   for (int32_t i = 0; i < mChildManagers.Count(); ++i) {
     nsRefPtr<nsFrameMessageManager> mm =
       static_cast<nsFrameMessageManager*>(mChildManagers[i]);
     if (mm) {
       // Use false here, so that child managers don't cache the script, which
       // is already cached in the parent.
@@ -245,116 +237,119 @@ nsFrameMessageManager::SendSyncMessage(c
                                        const jsval& aObject,
                                        JSContext* aCx,
                                        uint8_t aArgc,
                                        jsval* aRetval)
 {
   NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!IsWindowLevel(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
-
   *aRetval = JSVAL_VOID;
-  NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
+  if (mSyncCallback) {
+    NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
+    StructuredCloneData data;
+    JSAutoStructuredCloneBuffer buffer;
+    if (aArgc >= 2 &&
+        !GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
+      return NS_ERROR_DOM_DATA_CLONE_ERR;
+    }
+    data.mData = buffer.data();
+    data.mDataLength = buffer.nbytes();
 
-  StructuredCloneData data;
-  JSAutoStructuredCloneBuffer buffer;
-  if (aArgc >= 2 &&
-      !GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
-    return NS_ERROR_DOM_DATA_CLONE_ERR;
-  }
-  data.mData = buffer.data();
-  data.mDataLength = buffer.nbytes();
+    InfallibleTArray<nsString> retval;
+    if (mSyncCallback(mCallbackData, aMessageName, data, &retval)) {
+      JSAutoRequest ar(aCx);
+      uint32_t len = retval.Length();
+      JSObject* dataArray = JS_NewArrayObject(aCx, len, NULL);
+      NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
 
-  InfallibleTArray<nsString> retval;
-  if (mCallback->DoSendSyncMessage(aMessageName, data, &retval)) {
-    JSAutoRequest ar(aCx);
-    uint32_t len = retval.Length();
-    JSObject* dataArray = JS_NewArrayObject(aCx, len, NULL);
-    NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
+      for (uint32_t i = 0; i < len; ++i) {
+        if (retval[i].IsEmpty()) {
+          continue;
+        }
 
-    for (uint32_t i = 0; i < len; ++i) {
-      if (retval[i].IsEmpty()) {
-        continue;
+        jsval ret = JSVAL_VOID;
+        if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
+                          retval[i].Length(), &ret)) {
+          return NS_ERROR_UNEXPECTED;
+        }
+        NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret), NS_ERROR_OUT_OF_MEMORY);
       }
 
-      jsval ret = JSVAL_VOID;
-      if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
-                        retval[i].Length(), &ret)) {
-        return NS_ERROR_UNEXPECTED;
-      }
-      NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret), NS_ERROR_OUT_OF_MEMORY);
+      *aRetval = OBJECT_TO_JSVAL(dataArray);
     }
-
-    *aRetval = OBJECT_TO_JSVAL(dataArray);
   }
   return NS_OK;
 }
 
 nsresult
 nsFrameMessageManager::DispatchAsyncMessageInternal(const nsAString& aMessage,
-                                                    const StructuredCloneData& aData)
+                                                    const StructuredCloneData& aData,
+                                                    ShouldBroadcast aBroadcast)
 {
-  if (mIsBroadcaster) {
+  if (mAsyncCallback) {
+    NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
+
+    if (!mAsyncCallback(mCallbackData, aMessage, aData)) {
+      return NS_ERROR_FAILURE;
+    }
+  }
+  if (aBroadcast == BROADCAST) {
     int32_t len = mChildManagers.Count();
     for (int32_t i = 0; i < len; ++i) {
       static_cast<nsFrameMessageManager*>(mChildManagers[i])->
-         DispatchAsyncMessageInternal(aMessage, aData);
+         DispatchAsyncMessageInternal(aMessage, aData, aBroadcast);
     }
-    return NS_OK;
-  }
-
-  NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
-  if (!mCallback->DoSendAsyncMessage(aMessage, aData)) {
-    return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
 nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
                                             const jsval& aObject,
                                             JSContext* aCx,
-                                            uint8_t aArgc)
+                                            uint8_t aArgc,
+                                            ShouldBroadcast aBroadcast)
 {
   StructuredCloneData data;
   JSAutoStructuredCloneBuffer buffer;
 
   if (aArgc >= 2 &&
       !GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
     return NS_ERROR_DOM_DATA_CLONE_ERR;
   }
 
   data.mData = buffer.data();
   data.mDataLength = buffer.nbytes();
 
-  return DispatchAsyncMessageInternal(aMessageName, data);
+  return DispatchAsyncMessageInternal(aMessageName, data, aBroadcast);
 }
 
 
 // nsIMessageSender
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
                                         const jsval& aObject,
                                         JSContext* aCx,
                                         uint8_t aArgc)
 {
-  return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc);
+  return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc, DONT_BROADCAST);
 }
 
 
 // nsIMessageBroadcaster
 
 NS_IMETHODIMP
 nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
                                              const jsval& aObject,
                                              JSContext* aCx,
                                              uint8_t aArgc)
 {
-  return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc);
+  return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc, BROADCAST);
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::GetChildCount(uint32_t* aChildCount)
 {
   *aChildCount = static_cast<uint32_t>(mChildManagers.Count()); 
   return NS_OK;
 }
@@ -418,33 +413,16 @@ nsFrameMessageManager::Btoa(const nsAStr
 
 NS_IMETHODIMP
 nsFrameMessageManager::Atob(const nsAString& aAsciiString,
                             nsAString& aBinaryData)
 {
   return NS_OK;
 }
 
-// nsIPermissionChecker
-
-NS_IMETHODIMP
-nsFrameMessageManager::AssertPermission(const nsAString& aPermission, bool* aHasPermission)
-{
-  *aHasPermission = false;
-
-  // This API is only supported for message senders in the chrome process.
-  if (!mChrome || mIsBroadcaster) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-  if (!mCallback) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-  *aHasPermission = mCallback->CheckPermission(aPermission);
-  return NS_OK;
-}
 
 class MMListenerRemover
 {
 public:
   MMListenerRemover(nsFrameMessageManager* aMM)
     : mWasHandlingMessage(aMM->mHandlingMessage)
     , mMM(aMM)
   {
@@ -627,25 +605,20 @@ nsFrameMessageManager::AddChildManager(n
     }
     for (uint32_t i = 0; i < mPendingScripts.Length(); ++i) {
       aManager->LoadFrameScript(mPendingScripts[i], false);
     }
   }
 }
 
 void
-nsFrameMessageManager::SetCallback(MessageManagerCallback* aCallback, bool aLoadScripts)
+nsFrameMessageManager::SetCallbackData(void* aData, bool aLoadScripts)
 {
-  NS_ASSERTION(!mIsBroadcaster || !mCallback,
-               "Broadcasters cannot have callbacks!");
-  if (aCallback && mCallback != aCallback) {
-    mCallback = aCallback;
-    if (mOwnsCallback) {
-      mOwnedCallback = aCallback;
-    }
+  if (aData && mCallbackData != aData) {
+    mCallbackData = aData;
     // First load global scripts by adding this to parent manager.
     if (mParentManager) {
       mParentManager->AddChildManager(this, aLoadScripts);
     }
     if (aLoadScripts) {
       for (uint32_t i = 0; i < mPendingScripts.Length(); ++i) {
         LoadFrameScript(mPendingScripts[i], false);
       }
@@ -655,45 +628,50 @@ nsFrameMessageManager::SetCallback(Messa
 
 void
 nsFrameMessageManager::RemoveFromParent()
 {
   if (mParentManager) {
     mParentManager->RemoveChildManager(this);
   }
   mParentManager = nullptr;
-  mCallback = nullptr;
-  mOwnedCallback = nullptr;
+  mCallbackData = nullptr;
   mContext = nullptr;
 }
 
 void
 nsFrameMessageManager::Disconnect(bool aRemoveFromParent)
 {
   if (mParentManager && aRemoveFromParent) {
     mParentManager->RemoveChildManager(this);
   }
   mDisconnected = true;
   mParentManager = nullptr;
-  mCallback = nullptr;
-  mOwnedCallback = nullptr;
+  mCallbackData = nullptr;
   mContext = nullptr;
   if (!mHandlingMessage) {
     mListeners.Clear();
   }
 }
 
 nsresult
 NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult)
 {
   NS_ENSURE_TRUE(IsChromeProcess(), NS_ERROR_NOT_AVAILABLE);
-  nsFrameMessageManager* mm = new nsFrameMessageManager(nullptr,
+  nsFrameMessageManager* mm = new nsFrameMessageManager(true /* aChrome */,
+                                                        nullptr,
+                                                        nullptr,
+                                                        nullptr,
                                                         nullptr,
                                                         nullptr,
-                                                        MM_CHROME | MM_GLOBAL | MM_BROADCASTER);
+                                                        nullptr,
+                                                        true /* aGlobal */,
+                                                        false /* aProcessManager */,
+                                                        true /* aBroadcaster */);
+  NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
   return CallQueryInterface(mm, aResult);
 }
 
 void
 ContentScriptErrorReporter(JSContext* aCx,
                            const char* aMessage,
                            JSErrorReport* aReport)
 {
@@ -1018,16 +996,46 @@ nsFrameScriptExecutor::Traverse(nsFrameS
 
 NS_IMPL_ISUPPORTS1(nsScriptCacheCleaner, nsIObserver)
 
 nsFrameMessageManager* nsFrameMessageManager::sChildProcessManager = nullptr;
 nsFrameMessageManager* nsFrameMessageManager::sParentProcessManager = nullptr;
 nsFrameMessageManager* nsFrameMessageManager::sSameProcessParentManager = nullptr;
 nsTArray<nsCOMPtr<nsIRunnable> >* nsFrameMessageManager::sPendingSameProcessAsyncMessages = nullptr;
 
+bool SendAsyncMessageToChildProcess(void* aCallbackData,
+                                    const nsAString& aMessage,
+                                    const StructuredCloneData& aData)
+{
+  mozilla::dom::ContentParent* cp =
+    static_cast<mozilla::dom::ContentParent*>(aCallbackData);
+  NS_WARN_IF_FALSE(cp, "No child process!");
+  if (cp) {
+    ClonedMessageData data;
+    SerializedStructuredCloneBuffer& buffer = data.data();
+    buffer.data = aData.mData;
+    buffer.dataLength = aData.mDataLength;
+    const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
+    if (!blobs.IsEmpty()) {
+      InfallibleTArray<PBlobParent*>& blobParents = data.blobsParent();
+      uint32_t length = blobs.Length();
+      blobParents.SetCapacity(length);
+      for (uint32_t i = 0; i < length; ++i) {
+        BlobParent* blobParent = cp->GetOrCreateActorForBlob(blobs[i]);
+        if (!blobParent) {
+          return false;
+  }
+        blobParents.AppendElement(blobParent);
+      }
+    }
+
+    return cp->SendAsyncMessage(nsString(aMessage), data);
+  }
+  return true;
+}
 
 class nsAsyncMessageToSameProcessChild : public nsRunnable
 {
 public:
   nsAsyncMessageToSameProcessChild(const nsAString& aMessage,
                                    const StructuredCloneData& aData)
     : mMessage(aMessage)
   {
@@ -1051,74 +1059,34 @@ public:
     }
     return NS_OK;
   }
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
 };
 
-
-/**
- * Send messages to an imaginary child process in a single-process scenario.
- */
-class SameParentProcessMessageManagerCallback : public MessageManagerCallback
+bool SendAsyncMessageToSameProcessChild(void* aCallbackData,
+                                        const nsAString& aMessage,
+                                        const StructuredCloneData& aData)
 {
-public:
-  SameParentProcessMessageManagerCallback()
-  {
-    MOZ_COUNT_CTOR(SameParentProcessMessageManagerCallback);
-  }
-  virtual ~SameParentProcessMessageManagerCallback()
-  {
-    MOZ_COUNT_DTOR(SameParentProcessMessageManagerCallback);
-  }
-
-  virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                  const StructuredCloneData& aData)
-  {
-    nsRefPtr<nsIRunnable> ev =
-      new nsAsyncMessageToSameProcessChild(aMessage, aData);
-    NS_DispatchToCurrentThread(ev);
-    return true;
-  }
+  nsRefPtr<nsIRunnable> ev =
+    new nsAsyncMessageToSameProcessChild(aMessage, aData);
+  NS_DispatchToCurrentThread(ev);
+  return true;
+}
 
-  bool CheckPermission(const nsAString& aPermission)
-  {
-    // In a single-process scenario, the child always has all capabilities.
-    return true;
-  }
-
-};
-
-
-/**
- * Send messages to the parent process.
- */
-class ChildProcessMessageManagerCallback : public MessageManagerCallback
+bool SendSyncMessageToParentProcess(void* aCallbackData,
+                                    const nsAString& aMessage,
+                                    const StructuredCloneData& aData,
+                                    InfallibleTArray<nsString>* aJSONRetVal)
 {
-public:
-  ChildProcessMessageManagerCallback()
-  {
-    MOZ_COUNT_CTOR(ChildProcessMessageManagerCallback);
-  }
-  virtual ~ChildProcessMessageManagerCallback()
-  {
-    MOZ_COUNT_DTOR(ChildProcessMessageManagerCallback);
-  }
-
-  virtual bool DoSendSyncMessage(const nsAString& aMessage,
-                                 const mozilla::dom::StructuredCloneData& aData,
-                                 InfallibleTArray<nsString>* aJSONRetVal)
-  {
-    mozilla::dom::ContentChild* cc =
-      mozilla::dom::ContentChild::GetSingleton();
-    if (!cc) {
-      return true;
-    }
+  mozilla::dom::ContentChild* cc =
+    mozilla::dom::ContentChild::GetSingleton();
+  if (cc) {
     ClonedMessageData data;
     SerializedStructuredCloneBuffer& buffer = data.data();
     buffer.data = aData.mData;
     buffer.dataLength = aData.mDataLength;
     const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
     if (!blobs.IsEmpty()) {
       InfallibleTArray<PBlobChild*>& blobChildList = data.blobsChild();
       uint32_t length = blobs.Length();
@@ -1126,27 +1094,51 @@ public:
       for (uint32_t i = 0; i < length; ++i) {
         BlobChild* blobChild = cc->GetOrCreateActorForBlob(blobs[i]);
         if (!blobChild) {
           return false;
         }
         blobChildList.AppendElement(blobChild);
       }
     }
-    return cc->SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
+    return
+      cc->SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
   }
+  return true;
+}
 
-  virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                  const mozilla::dom::StructuredCloneData& aData)
-  {
-    mozilla::dom::ContentChild* cc =
-      mozilla::dom::ContentChild::GetSingleton();
-    if (!cc) {
-      return true;
+bool SendSyncMessageToSameProcessParent(void* aCallbackData,
+                                        const nsAString& aMessage,
+                                        const StructuredCloneData& aData,
+                                        InfallibleTArray<nsString>* aJSONRetVal)
+{
+  nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
+  if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
+    asyncMessages.SwapElements(*nsFrameMessageManager::sPendingSameProcessAsyncMessages);
+    uint32_t len = asyncMessages.Length();
+    for (uint32_t i = 0; i < len; ++i) {
+      nsCOMPtr<nsIRunnable> async = asyncMessages[i];
+      async->Run();
     }
+  }
+  if (nsFrameMessageManager::sSameProcessParentManager) {
+    nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
+    ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
+                        true, &aData, nullptr, aJSONRetVal);
+  }
+  return true;
+}
+
+bool SendAsyncMessageToParentProcess(void* aCallbackData,
+                                     const nsAString& aMessage,
+                                          const StructuredCloneData& aData)
+{
+  mozilla::dom::ContentChild* cc =
+    mozilla::dom::ContentChild::GetSingleton();
+  if (cc) {
     ClonedMessageData data;
     SerializedStructuredCloneBuffer& buffer = data.data();
     buffer.data = aData.mData;
     buffer.dataLength = aData.mDataLength;
     const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
     if (!blobs.IsEmpty()) {
       InfallibleTArray<PBlobChild*>& blobChildList = data.blobsChild();
       uint32_t length = blobs.Length();
@@ -1156,25 +1148,24 @@ public:
         if (!blobChild) {
           return false;
         }
         blobChildList.AppendElement(blobChild);
       }
     }
     return cc->SendAsyncMessage(nsString(aMessage), data);
   }
-
-};
-
+  return true;
+}
 
 class nsAsyncMessageToSameProcessParent : public nsRunnable
 {
 public:
   nsAsyncMessageToSameProcessParent(const nsAString& aMessage,
-                                    const StructuredCloneData& aData)
+                                         const StructuredCloneData& aData)
     : mMessage(aMessage)
   {
     if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
       NS_RUNTIMEABORT("OOM");
     }
     mClosure = aData.mClosure;
   }
 
@@ -1196,126 +1187,95 @@ public:
      }
      return NS_OK;
   }
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
 };
 
-/**
- * Send messages to the imaginary parent process in a single-process scenario.
- */
-class SameChildProcessMessageManagerCallback : public MessageManagerCallback
+bool SendAsyncMessageToSameProcessParent(void* aCallbackData,
+                                              const nsAString& aMessage,
+                                              const StructuredCloneData& aData)
 {
-public:
-  SameChildProcessMessageManagerCallback()
-  {
-    MOZ_COUNT_CTOR(SameChildProcessMessageManagerCallback);
-  }
-  virtual ~SameChildProcessMessageManagerCallback()
-  {
-    MOZ_COUNT_DTOR(SameChildProcessMessageManagerCallback);
+  if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
+    nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
   }
-
-  virtual bool DoSendSyncMessage(const nsAString& aMessage,
-                                 const mozilla::dom::StructuredCloneData& aData,
-                                 InfallibleTArray<nsString>* aJSONRetVal)
-  {
-    nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
-    if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
-      asyncMessages.SwapElements(*nsFrameMessageManager::sPendingSameProcessAsyncMessages);
-      uint32_t len = asyncMessages.Length();
-      for (uint32_t i = 0; i < len; ++i) {
-        nsCOMPtr<nsIRunnable> async = asyncMessages[i];
-        async->Run();
-      }
-    }
-    if (nsFrameMessageManager::sSameProcessParentManager) {
-      nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
-      ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
-                          true, &aData, nullptr, aJSONRetVal);
-    }
-    return true;
-  }
-
-  virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                  const mozilla::dom::StructuredCloneData& aData)
-  {
-    if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
-      nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
-    }
-    nsCOMPtr<nsIRunnable> ev =
-      new nsAsyncMessageToSameProcessParent(aMessage, aData);
-    nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
-    NS_DispatchToCurrentThread(ev);
-    return true;
-  }
-
-};
-
+  nsCOMPtr<nsIRunnable> ev =
+    new nsAsyncMessageToSameProcessParent(aMessage, aData);
+  nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
+  NS_DispatchToCurrentThread(ev);
+  return true;
+}
 
 // This creates the global parent process message manager.
 nsresult
 NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
 {
   NS_ASSERTION(!nsFrameMessageManager::sParentProcessManager,
                "Re-creating sParentProcessManager");
   NS_ENSURE_TRUE(IsChromeProcess(), NS_ERROR_NOT_AVAILABLE);
-  nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(nullptr,
+  nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(true /* aChrome */,
+                                                                 nullptr,
+                                                                 nullptr,
                                                                  nullptr,
                                                                  nullptr,
-                                                                 MM_CHROME | MM_PROCESSMANAGER | MM_BROADCASTER);
+                                                                 nullptr,
+                                                                 nullptr,
+                                                                 false, /* aGlobal */
+                                                                 true /* aProcessManager */,
+                                                                 true /* aBroadcaster */);
   NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
   nsFrameMessageManager::sParentProcessManager = mm;
   nsFrameMessageManager::NewProcessMessageManager(nullptr); // Create same process message manager.
   return CallQueryInterface(mm, aResult);
 }
 
-
 nsFrameMessageManager*
 nsFrameMessageManager::NewProcessMessageManager(mozilla::dom::ContentParent* aProcess)
 {
   if (!nsFrameMessageManager::sParentProcessManager) {
      nsCOMPtr<nsIMessageBroadcaster> dummy;
      NS_NewParentProcessMessageManager(getter_AddRefs(dummy));
   }
 
-  nsFrameMessageManager* mm;
-  if (aProcess) {
-    mm = new nsFrameMessageManager(aProcess,
-                                   nsFrameMessageManager::sParentProcessManager,
-                                   nullptr,
-                                   MM_CHROME | MM_PROCESSMANAGER);
-  } else {
-    mm = new nsFrameMessageManager(new SameParentProcessMessageManagerCallback(),
-                                   nsFrameMessageManager::sParentProcessManager,
-                                   nullptr,
-                                   MM_CHROME | MM_PROCESSMANAGER | MM_OWNSCALLBACK);
+  nsFrameMessageManager* mm = new nsFrameMessageManager(true /* aChrome */,
+                                                        nullptr,
+                                                        aProcess ? SendAsyncMessageToChildProcess
+                                                                 : SendAsyncMessageToSameProcessChild,
+                                                        nullptr,
+                                                        aProcess ? static_cast<void*>(aProcess)
+                                                                 : static_cast<void*>(&nsFrameMessageManager::sChildProcessManager),
+                                                        nsFrameMessageManager::sParentProcessManager,
+                                                        nullptr,
+                                                        false, /* aGlobal */
+                                                        true /* aProcessManager */);
+  if (!aProcess) {
     sSameProcessParentManager = mm;
   }
   return mm;
 }
 
 nsresult
 NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult)
 {
   NS_ASSERTION(!nsFrameMessageManager::sChildProcessManager,
                "Re-creating sChildProcessManager");
-
-  MessageManagerCallback* cb;
-  if (IsChromeProcess()) {
-    cb = new SameChildProcessMessageManagerCallback();
-  } else {
-    cb = new ChildProcessMessageManagerCallback();
-  }
-  nsFrameMessageManager* mm = new nsFrameMessageManager(cb,
+  bool isChrome = IsChromeProcess();
+  nsFrameMessageManager* mm = new nsFrameMessageManager(false /* aChrome */,
+                                                        isChrome ? SendSyncMessageToSameProcessParent
+                                                                 : SendSyncMessageToParentProcess,
+                                                        isChrome ? SendAsyncMessageToSameProcessParent
+                                                                 : SendAsyncMessageToParentProcess,
+                                                        nullptr,
+                                                        &nsFrameMessageManager::sChildProcessManager,
                                                         nullptr,
                                                         nullptr,
-                                                        MM_PROCESSMANAGER | MM_OWNSCALLBACK);
+                                                        false /* aGlobal */,
+                                                        true /* aProcessManager */);
   NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
   nsFrameMessageManager::sChildProcessManager = mm;
   return CallQueryInterface(mm, aResult);
 }
 
 bool
 nsFrameMessageManager::MarkForCC()
 {
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -19,112 +19,79 @@
 #include "nsDataHashtable.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Attributes.h"
 
 namespace mozilla {
 namespace dom {
-
 class ContentParent;
 struct StructuredCloneData;
-
-namespace ipc {
-
-enum MessageManagerFlags {
-  MM_CHILD = 0,
-  MM_CHROME = 1,
-  MM_GLOBAL = 2,
-  MM_PROCESSMANAGER = 4,
-  MM_BROADCASTER = 8,
-  MM_OWNSCALLBACK = 16
-};
-
-class MessageManagerCallback
-{
-public:
-  virtual ~MessageManagerCallback() {}
-
-  virtual bool DoLoadFrameScript(const nsAString& aURL)
-  {
-    return true;
-  }
-
-  virtual bool DoSendSyncMessage(const nsAString& aMessage,
-                                 const mozilla::dom::StructuredCloneData& aData,
-                                 InfallibleTArray<nsString>* aJSONRetVal)
-  {
-    return true;
-  }
-
-  virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                  const mozilla::dom::StructuredCloneData& aData)
-  {
-    return true;
-  }
-
-  virtual bool CheckPermission(const nsAString& aPermission)
-  {
-    return false;
-  }
-};
-
-} // namespace ipc
-} // namespace dom
-} // namespace mozilla
+}
+}
 
 class nsAXPCNativeCallContext;
 struct JSContext;
 struct JSObject;
 
 struct nsMessageListenerInfo
 {
   nsCOMPtr<nsIMessageListener> mListener;
   nsCOMPtr<nsIAtom> mMessage;
 };
 
+typedef bool (*nsLoadScriptCallback)(void* aCallbackData, const nsAString& aURL);
+typedef bool (*nsSyncMessageCallback)(void* aCallbackData,
+                                      const nsAString& aMessage,
+                                      const mozilla::dom::StructuredCloneData& aData,
+                                      InfallibleTArray<nsString>* aJSONRetVal);
+typedef bool (*nsAsyncMessageCallback)(void* aCallbackData,
+                                       const nsAString& aMessage,
+                                             const mozilla::dom::StructuredCloneData& aData);
 
 class nsFrameMessageManager MOZ_FINAL : public nsIContentFrameMessageManager,
                                         public nsIMessageBroadcaster,
-                                        public nsIFrameScriptLoader,
-                                        public nsIPermissionChecker
+                                        public nsIFrameScriptLoader
 {
   typedef mozilla::dom::StructuredCloneData StructuredCloneData;
 public:
-  nsFrameMessageManager(mozilla::dom::ipc::MessageManagerCallback* aCallback,
+  nsFrameMessageManager(bool aChrome,
+                        nsSyncMessageCallback aSyncCallback,
+                        nsAsyncMessageCallback aAsyncCallback,
+                        nsLoadScriptCallback aLoadScriptCallback,
+                        void* aCallbackData,
                         nsFrameMessageManager* aParentManager,
                         JSContext* aContext,
-                        /* mozilla::dom::ipc::MessageManagerFlags */ uint32_t aFlags)
-  : mChrome(!!(aFlags & mozilla::dom::ipc::MM_CHROME)),
-    mGlobal(!!(aFlags & mozilla::dom::ipc::MM_GLOBAL)),
-    mIsProcessManager(!!(aFlags & mozilla::dom::ipc::MM_PROCESSMANAGER)),
-    mIsBroadcaster(!!(aFlags & mozilla::dom::ipc::MM_BROADCASTER)),
-    mOwnsCallback(!!(aFlags & mozilla::dom::ipc::MM_OWNSCALLBACK)),
+                        bool aGlobal = false,
+                        bool aProcessManager = false,
+                        bool aBroadcaster = false)
+  : mChrome(aChrome),
+    mGlobal(aGlobal),
+    mIsProcessManager(aProcessManager),
+    mIsBroadcaster(aBroadcaster),
     mHandlingMessage(false),
     mDisconnected(false),
-    mCallback(aCallback),
     mParentManager(aParentManager),
+    mSyncCallback(aSyncCallback),
+    mAsyncCallback(aAsyncCallback),
+    mLoadScriptCallback(aLoadScriptCallback),
+    mCallbackData(aCallbackData),
     mContext(aContext)
   {
-    NS_ASSERTION(mContext || (mChrome && !mParentManager) || mIsProcessManager,
+    NS_ASSERTION(mContext || (aChrome && !aParentManager) || aProcessManager,
                  "Should have mContext in non-global/non-process manager!");
-    NS_ASSERTION(mChrome || !aParentManager, "Should not set parent manager!");
-    NS_ASSERTION(!mIsBroadcaster || !mCallback,
-                 "Broadcasters cannot have callbacks!");
+    NS_ASSERTION(aChrome || !aParentManager, "Should not set parent manager!");
     // This is a bit hackish. When parent manager is global, we want
     // to attach the window message manager to it immediately.
     // Is it just the frame message manager which waits until the
     // content process is running.
-    if (mParentManager && (mCallback || IsWindowLevel())) {
+    if (mParentManager && (mCallbackData || IsWindowLevel())) {
       mParentManager->AddChildManager(this);
     }
-    if (mOwnsCallback) {
-      mOwnedCallback = aCallback;
-    }
   }
 
   ~nsFrameMessageManager()
   {
     for (int32_t i = mChildManagers.Count(); i > 0; --i) {
       static_cast<nsFrameMessageManager*>(mChildManagers[i - 1])->
         Disconnect(false);
     }
@@ -147,48 +114,45 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameMessageManager,
                                            nsIContentFrameMessageManager)
   NS_DECL_NSIMESSAGELISTENERMANAGER
   NS_DECL_NSIMESSAGESENDER
   NS_DECL_NSIMESSAGEBROADCASTER
   NS_DECL_NSISYNCMESSAGESENDER
   NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
   NS_DECL_NSIFRAMESCRIPTLOADER
-  NS_DECL_NSIPERMISSIONCHECKER
 
   static nsFrameMessageManager*
   NewProcessMessageManager(mozilla::dom::ContentParent* aProcess);
 
   nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
                           bool aSync, const StructuredCloneData* aCloneData,
                           JSObject* aObjectsArray,
                           InfallibleTArray<nsString>* aJSONRetVal,
                           JSContext* aContext = nullptr);
 
   void AddChildManager(nsFrameMessageManager* aManager,
                        bool aLoadScripts = true);
   void RemoveChildManager(nsFrameMessageManager* aManager)
   {
     mChildManagers.RemoveObject(aManager);
   }
+
   void Disconnect(bool aRemoveFromParent = true);
-
-  void SetCallback(mozilla::dom::ipc::MessageManagerCallback* aCallback,
-                   bool aLoadScripts = true);
-  mozilla::dom::ipc::MessageManagerCallback* GetCallback()
-  {
-    return mCallback;
-  }
-
+  void SetCallbackData(void* aData, bool aLoadScripts = true);
+  void* GetCallbackData() { return mCallbackData; }
+  enum ShouldBroadcast { BROADCAST, DONT_BROADCAST };
   nsresult DispatchAsyncMessage(const nsAString& aMessageName,
                                 const jsval& aObject,
                                 JSContext* aCx,
-                                uint8_t aArgc);
+                                uint8_t aArgc,
+                                ShouldBroadcast aBroadcast);
   nsresult DispatchAsyncMessageInternal(const nsAString& aMessage,
-                                        const StructuredCloneData& aData);
+                                        const StructuredCloneData& aData,
+                                        ShouldBroadcast aBroadcast);
   JSContext* GetJSContext() { return mContext; }
   void SetJSContext(JSContext* aCx) { mContext = aCx; }
   void RemoveFromParent();
   nsFrameMessageManager* GetParentManager() { return mParentManager; }
   void SetParentManager(nsFrameMessageManager* aParent)
   {
     NS_ASSERTION(!mParentManager, "We have parent manager already!");
     NS_ASSERTION(mChrome, "Should not set parent manager!");
@@ -205,25 +169,26 @@ public:
   {
     return sChildProcessManager;
   }
 protected:
   friend class MMListenerRemover;
   nsTArray<nsMessageListenerInfo> mListeners;
   nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
   bool mChrome;     // true if we're in the chrome process
-  bool mGlobal;     // true if we're the global frame message manager
+  bool mGlobal;     // true if 
   bool mIsProcessManager; // true if the message manager belongs to the process realm
   bool mIsBroadcaster; // true if the message manager is a broadcaster
-  bool mOwnsCallback;
   bool mHandlingMessage;
   bool mDisconnected;
-  mozilla::dom::ipc::MessageManagerCallback* mCallback;
-  nsAutoPtr<mozilla::dom::ipc::MessageManagerCallback> mOwnedCallback;
   nsFrameMessageManager* mParentManager;
+  nsSyncMessageCallback mSyncCallback;
+  nsAsyncMessageCallback mAsyncCallback;
+  nsLoadScriptCallback mLoadScriptCallback;
+  void* mCallbackData;
   JSContext* mContext;
   nsTArray<nsString> mPendingScripts;
 public:
   static nsFrameMessageManager* sParentProcessManager;
   static nsFrameMessageManager* sChildProcessManager;
   static nsFrameMessageManager* sSameProcessParentManager;
   static nsTArray<nsCOMPtr<nsIRunnable> >* sPendingSameProcessAsyncMessages;
 };
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -20,31 +20,34 @@
 #include "xpcpublic.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsDOMClassInfoID.h"
 #include "mozilla/dom/StructuredCloneUtils.h"
 
 using mozilla::dom::StructuredCloneData;
 using mozilla::dom::StructuredCloneClosure;
 
-bool
-nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
-                                             const StructuredCloneData& aData,
-                                             InfallibleTArray<nsString>* aJSONRetVal)
+bool SendSyncMessageToParent(void* aCallbackData,
+                             const nsAString& aMessage,
+                             const StructuredCloneData& aData,
+                             InfallibleTArray<nsString>* aJSONRetVal)
 {
+  nsInProcessTabChildGlobal* tabChild =
+    static_cast<nsInProcessTabChildGlobal*>(aCallbackData);
+  nsCOMPtr<nsIContent> owner = tabChild->mOwner;
   nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
-  asyncMessages.SwapElements(mASyncMessages);
+  asyncMessages.SwapElements(tabChild->mASyncMessages);
   uint32_t len = asyncMessages.Length();
   for (uint32_t i = 0; i < len; ++i) {
     nsCOMPtr<nsIRunnable> async = asyncMessages[i];
     async->Run();
   }
-  if (mChromeMessageManager) {
-    nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
-    mm->ReceiveMessage(mOwner, aMessage, true, &aData, nullptr, aJSONRetVal);
+  if (tabChild->mChromeMessageManager) {
+    nsRefPtr<nsFrameMessageManager> mm = tabChild->mChromeMessageManager;
+    mm->ReceiveMessage(owner, aMessage, true, &aData, nullptr, aJSONRetVal);
   }
   return true;
 }
 
 class nsAsyncMessageToParent : public nsRunnable
 {
 public:
   nsAsyncMessageToParent(nsInProcessTabChildGlobal* aTabChild,
@@ -74,23 +77,25 @@ public:
     return NS_OK;
   }
   nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
 };
 
-bool
-nsInProcessTabChildGlobal::DoSendAsyncMessage(const nsAString& aMessage,
-                                              const StructuredCloneData& aData)
+bool SendAsyncMessageToParent(void* aCallbackData,
+                              const nsAString& aMessage,
+                              const StructuredCloneData& aData)
 {
+  nsInProcessTabChildGlobal* tabChild =
+    static_cast<nsInProcessTabChildGlobal*>(aCallbackData);
   nsCOMPtr<nsIRunnable> ev =
-    new nsAsyncMessageToParent(this, aMessage, aData);
-  mASyncMessages.AppendElement(ev);
+    new nsAsyncMessageToParent(tabChild, aMessage, aData);
+  tabChild->mASyncMessages.AppendElement(ev);
   NS_DispatchToCurrentThread(ev);
   return true;
 }
 
 nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
                                                      nsIContent* aOwner,
                                                      nsFrameMessageManager* aChrome)
 : mDocShell(aShell), mInitialized(false), mLoadingScript(false),
@@ -125,20 +130,23 @@ nsresult
 nsInProcessTabChildGlobal::Init()
 {
 #ifdef DEBUG
   nsresult rv =
 #endif
   InitTabChildGlobal();
   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
                    "Couldn't initialize nsInProcessTabChildGlobal");
-  mMessageManager = new nsFrameMessageManager(this,
+  mMessageManager = new nsFrameMessageManager(false, /* aChrome */
+                                              SendSyncMessageToParent,
+                                              SendAsyncMessageToParent,
                                               nullptr,
-                                              mCx,
-                                              mozilla::dom::ipc::MM_CHILD);
+                                              this,
+                                              nullptr,
+                                              mCx);
 
   // Set the location information for the new global, so that tools like
   // about:memory may use that information.
   JSObject *global;
   nsIURI* docURI = mOwner->OwnerDoc()->GetDocumentURI();
   if (mGlobal && NS_SUCCEEDED(mGlobal->GetJSObject(&global)) && docURI) {
     xpc::SetLocationForGlobal(global, docURI);
   }
--- a/content/base/src/nsInProcessTabChildGlobal.h
+++ b/content/base/src/nsInProcessTabChildGlobal.h
@@ -19,18 +19,17 @@
 #include "nsIDOMElement.h"
 #include "nsCOMArray.h"
 #include "nsThreadUtils.h"
 
 class nsInProcessTabChildGlobal : public nsDOMEventTargetHelper,
                                   public nsFrameScriptExecutor,
                                   public nsIInProcessContentFrameMessageManager,
                                   public nsIScriptObjectPrincipal,
-                                  public nsIScriptContextPrincipal,
-                                  public mozilla::dom::ipc::MessageManagerCallback
+                                  public nsIScriptContextPrincipal
 {
 public:
   nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
                             nsFrameMessageManager* aChrome);
   virtual ~nsInProcessTabChildGlobal();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
                                            nsDOMEventTargetHelper)
@@ -55,25 +54,16 @@ public:
   NS_IMETHOD PrivateNoteIntentionalCrash();
   NS_IMETHOD Btoa(const nsAString& aBinaryData,
                   nsAString& aAsciiBase64String);
   NS_IMETHOD Atob(const nsAString& aAsciiString,
                   nsAString& aBinaryData);
 
   NS_DECL_NSIINPROCESSCONTENTFRAMEMESSAGEMANAGER
 
-  /**
-   * MessageManagerCallback methods that we override.
-   */
-  virtual bool DoSendSyncMessage(const nsAString& aMessage,
-                                 const mozilla::dom::StructuredCloneData& aData,
-                                 InfallibleTArray<nsString>* aJSONRetVal);
-  virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                  const mozilla::dom::StructuredCloneData& aData);
-
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
   NS_IMETHOD AddEventListener(const nsAString& aType,
                               nsIDOMEventListener* aListener,
                               bool aUseCapture)
   {
     // By default add listeners only for trusted events!
     return nsDOMEventTargetHelper::AddEventListener(aType, aListener,
                                                     aUseCapture, false, 2);
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -566,27 +566,16 @@ MOCHITEST_FILES_B = \
 		test_XHR_parameters.html \
 		test_ipc_messagemanager_blob.html \
 		test_mixed_content_blocker.html \
 		file_mixed_content_main.html \
 		file_mixed_content_server.sjs \
 		test_bug789856.html \
 		$(NULL)
 
-# OOP tests don't work on Windows (bug 763081) or native-fennec
-# (see Bug 774939)
-ifneq ($(OS_ARCH),WINNT)
-ifndef MOZ_JAVA_COMPOSITOR
-MOCHITEST_FILES_B += \
-		test_messagemanager_assertpermission.html \
-		test_child_process_shutdown_message.html \
-		$(NULL)
-endif
-endif
-
 MOCHITEST_CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 MOCHITEST_FILES_PARTS = $(foreach s,A B,MOCHITEST_FILES_$(s))
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
deleted file mode 100644
--- a/content/base/test/test_child_process_shutdown_message.html
+++ /dev/null
@@ -1,136 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test that processes that are shutdown send a 'process-shutdown'
-         message to their process message manager.</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body onload="runTests();">
-<p id="display">
-</p>
-<div id="content" style="display: none">
-  
-</div>
-<pre id="test">
-<script class="testbody" type="application/javascript;version=1.8">
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = SpecialPowers.wrap(Components);
-
-const APP_URL = "http://example.org";
-const APP_MANIFEST = "http://example.org/manifest.webapp";
-const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
-
-let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-             .getService(Ci.nsIMessageBroadcaster);
-
-/**
- * Load the example.org app in an <iframe mozbrowser mozapp>
- */
-function loadApp(callback) {
-  let iframe = document.createElement("iframe");
-  iframe.setAttribute("mozapp", APP_MANIFEST);
-  iframe.mozbrowser = true;
-  iframe.src = APP_URL;
-  document.getElementById("content").appendChild(iframe);
-
-  iframe.addEventListener("mozbrowserloadend", function onloadend() {
-    iframe.removeEventListener("mozbrowserloadend", onloadend);
-    callback(iframe);
-  });
-}
-
-/**
- * Prepare the child process for an intentional crash. This is to keep
- * the leak automation tools happy.
- *
- * This also allows us to acquire the process message manaager that
- * corresponds to the process by sending a message to a frame script
- * in the content process and having it reply to us via the child
- * process message manager.
- */
-function prepareProcess(frameMM, callback) {
-  let frameScript = 'data:,\
-    privateNoteIntentionalCrash();\
-    var cpmm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]\
-                         .getService(Components.interfaces.nsISyncMessageSender);\
-    addMessageListener("TestChild:Ohai", function receiveMessage(msg) {\
-      cpmm.sendAsyncMessage("TestChild:Ohai");\
-    });';
-  frameMM.loadFrameScript(frameScript, false);
-  frameMM.sendAsyncMessage("TestChild:Ohai");
-  ppmm.addMessageListener("TestChild:Ohai", function receiveMessage(msg) {
-    ppmm.removeMessageListener("TestChild:Ohai", receiveMessage);
-    msg = SpecialPowers.wrap(msg);
-    callback(msg.target);
-  });
-}
-
-/**
- * Expects an OOP frame's process to shut down and report three
- * events/messages: an error event on the browser element, and a
- * 'child-process-shutdown' message on both the frame and process
- * message managers.
- */
-function expectFrameProcessShutdown(iframe, frameMM, processMM, callback) {
-  let msgCount = 0;
-  function countMessage() {
-    msgCount += 1;
-    if (msgCount == 3) {
-      ok(true, "Observed all three expected events.");
-      callback();
-    }
-  };
-
-  iframe.addEventListener("mozbrowsererror", function onerror(event) {
-    iframe.removeEventListener("mozbrowsererror", onerror);
-    is(event.detail.type, "fatal", "Observed fatal error event.");
-    countMessage();
-  });
-
-  processMM.addMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, function receiveMessage() {
-    processMM.removeMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, receiveMessage);
-    ok(true, "Received 'child-process-shutdown' message from process message manager.");
-    countMessage();
-  });
-
-  frameMM.addMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, function receiveMessage() {
-    frameMM.removeMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, receiveMessage);
-    ok(true, "Received 'child-process-shutdown' message from frame message manager.");
-    countMessage();
-  });
-}
-
-function runTests(callback) {
-  SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
-  SpecialPowers.setBoolPref("dom.ipc.browser_frames.oop_by_default", true);
-  SpecialPowers.addPermission("browser", true, window.document);
-
-  function tearDown() {
-    SpecialPowers.clearUserPref("dom.mozBrowserFramesEnabled");
-    SpecialPowers.clearUserPref("dom.ipc.browser_frames.oop_by_default");
-    SimpleTest.finish();
-  }
-
-  loadApp(function (iframe) {
-    // We want to make sure we get notified on both the frame and
-    // process message managers.
-    let frameMM = SpecialPowers.getBrowserFrameMessageManager(iframe);
-    prepareProcess(frameMM, function (processMM) {
-      // Let's kill the content process by asking for a permission
-      // that it doesn't have.
-      ok(!processMM.assertPermission("frobnaz"),
-         "Content child should not have this permission");
-      expectFrameProcessShutdown(iframe, frameMM, processMM, function () {
-        iframe.parentNode.removeChild(iframe);
-        tearDown();
-      });
-    });
-  });
-}
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/content/base/test/test_messagemanager_assertpermission.html
+++ /dev/null
@@ -1,196 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for the nsIPermissionChecker part of Message Managers</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body onload="runTests();">
-<p id="display">
-</p>
-<div id="content" style="display: none">
-  
-</div>
-<pre id="test">
-<script class="testbody" type="application/javascript;version=1.8">
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = SpecialPowers.wrap(Components);
-
-const APP_URL = "http://example.org";
-const APP_MANIFEST = "http://example.org/manifest.webapp";
-const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
-
-let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-             .getService(Ci.nsIMessageBroadcaster);
-let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-             .getService(Ci.nsISyncMessageSender);
-let gAppsService = Cc["@mozilla.org/AppsService;1"]
-                     .getService(Ci.nsIAppsService);
-
-function setUp() {
-  SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
-  SpecialPowers.setBoolPref("dom.ipc.browser_frames.oop_by_default", true);
-  SpecialPowers.addPermission("browser", true, window.document);
-
-  let appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
-  SpecialPowers.addPermission("foobar", true, { url: APP_URL,
-                                                appId: appId,
-                                                isInBrowserElement: false });
-  runNextTest();
-}
-
-/**
- * Load the example.org app in an <iframe mozbrowser mozapp>
- */
-function loadApp(callback) {
-  let iframe = document.createElement("iframe");
-  iframe.setAttribute("mozapp", APP_MANIFEST);
-  iframe.mozbrowser = true;
-  iframe.src = APP_URL;
-  document.getElementById("content").appendChild(iframe);
-
-  iframe.addEventListener("mozbrowserloadend", function onloadend() {
-    iframe.removeEventListener("mozbrowserloadend", onloadend);
-    callback(iframe);
-  });
-}
-
-/**
- * Prepare the child process for an intentional crash. This is to keep
- * the leak automation tools happy.
- *
- * This also allows us to acquire the process message manaager that
- * corresponds to the process by sending a message to a frame script
- * in the content process and having it reply to us via the child
- * process message manager.
- */
-function prepareProcess(frameMM, callback) {
-  let frameScript = 'data:,\
-    privateNoteIntentionalCrash();\
-    var cpmm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]\
-                         .getService(Components.interfaces.nsISyncMessageSender);\
-    addMessageListener("TestChild:Ohai", function receiveMessage(msg) {\
-      cpmm.sendAsyncMessage("TestChild:Ohai");\
-    });';
-  frameMM.loadFrameScript(frameScript, false);
-  frameMM.sendAsyncMessage("TestChild:Ohai");
-  ppmm.addMessageListener("TestChild:Ohai", function receiveMessage(msg) {
-    ppmm.removeMessageListener("TestChild:Ohai", receiveMessage);
-    msg = SpecialPowers.wrap(msg);
-    callback(msg.target);
-  });
-}
-
-/**
- * Expects an OOP frame's process to shut down and report three
- * events/messages: an error event on the browser element, and a
- * 'child-process-shutdown' message on both the frame and process
- * message managers.
- */
-function expectFrameProcessShutdown(iframe, frameMM, processMM, callback) {
-  let msgCount = 0;
-  function countMessage() {
-    msgCount += 1;
-    if (msgCount == 3) {
-      ok(true, "Observed all three expected events.");
-      callback();
-    }
-  };
-
-  iframe.addEventListener("mozbrowsererror", function onerror(event) {
-    iframe.removeEventListener("mozbrowsererror", onerror);
-    is(event.detail.type, "fatal", "Observed fatal error event.");
-    countMessage();
-  });
-
-  processMM.addMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, function receiveMessage() {
-    processMM.removeMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, receiveMessage);
-    ok(true, "Received 'child-process-shutdown' message from process message manager.");
-    countMessage();
-  });
-
-  frameMM.addMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, function receiveMessage() {
-    frameMM.removeMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, receiveMessage);
-    ok(true, "Received 'child-process-shutdown' message from frame message manager.");
-    countMessage();
-  });
-}
-
-function testSameProcess() {
-  // Assert permissions on the in-process child process message manager.
-  // It always has all permissions, including ones that were never
-  // assigned to anybody.
-
-  cpmm.sendAsyncMessage("TestPermission:InProcess");
-  ppmm.addMessageListener("TestPermission:InProcess", function receiveMessage(msg) {
-    ppmm.removeMessageListener("TestPermission:InProcess", receiveMessage);
-    msg = SpecialPowers.wrap(msg);
-
-    ok(msg.target.assertPermission("frobnaz"), "in-process cpmm always has all capabilities");
-    runNextTest();
-  });
-}
-
-function testFrameMessageManager() {
-  // Assert permissions on the frame message manager.
-
-  loadApp(function (iframe) {
-    let frameMM = SpecialPowers.getBrowserFrameMessageManager(iframe);
-    prepareProcess(frameMM, function (processMM) {
-      ok(frameMM.assertPermission("foobar"),
-         "Frame mm has assigned permission.");
-      ok(!frameMM.assertPermission("frobnaz"),
-         "Frame mm doesn't have non-existing permission.");
-      expectFrameProcessShutdown(iframe, frameMM, processMM, function () {
-        iframe.parentNode.removeChild(iframe);
-        runNextTest();
-      });
-    });
-  });
-}
-
-function testChildProcessMessageManager() {
-  // Assert permissions on the child process message manager.
-
-  loadApp(function (iframe) {
-    let frameMM = SpecialPowers.getBrowserFrameMessageManager(iframe);
-    prepareProcess(frameMM, function (processMM) {
-      ok(processMM.assertPermission("foobar"),
-         "Process mm has assigned permission.");
-      ok(!processMM.assertPermission("frobnaz"),
-         "Process mm doesn't have non-existing permission.");
-      expectFrameProcessShutdown(iframe, frameMM, processMM, function () {
-        iframe.parentNode.removeChild(iframe);
-        runNextTest();
-      });
-    });
-  });
-}
-
-function tearDown() {
-  SpecialPowers.clearUserPref("dom.mozBrowserFramesEnabled");
-  SpecialPowers.clearUserPref("dom.ipc.browser_frames.oop_by_default");
-  SimpleTest.finish();
-}
-
-let _tests = [
-  setUp,
-  testSameProcess,
-  testFrameMessageManager,
-  testChildProcessMessageManager,
-  tearDown
-]
-function runNextTest() {
-  SimpleTest.executeSoon(_tests.shift());
-}
-
-function runTests() {
-  SimpleTest.waitForExplicitFinish();
-  runNextTest();
-}
-
-</script>
-</pre>
-</body>
-</html>
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -49,17 +49,17 @@
 #include "nsDOMScriptObjectHolder.h"
 #include "nsDataHashtable.h"
 #include "nsCOMArray.h"
 #include "nsEventListenerService.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsJSEnvironment.h"
 #include "xpcpublic.h"
 #include "nsSandboxFlags.h"
-#include "mozilla/dom/time/TimeChangeObserver.h"
+#include "TimeChangeObserver.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
 #define EVENT_TYPE_EQUALS( ls, type, userType ) \
   (ls->mEventType == type && \
   (ls->mEventType != NS_USER_DEFINED_EVENT || ls->mTypeAtom == userType))
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -4345,17 +4345,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageBroadcaster, nsISupports)
     DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageBroadcaster)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageSender, nsISupports)
-    DOM_CLASSINFO_MAP_ENTRY(nsIPermissionChecker)
     DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(FormData, nsIDOMFormData)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMFormData)
   DOM_CLASSINFO_MAP_END
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -230,17 +230,16 @@
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDOMLeakPRLog;
 #endif
 
 static const char kStorageEnabled[] = "dom.storage.enabled";
 
 using namespace mozilla;
 using namespace mozilla::dom;
-using namespace mozilla::dom::ipc;
 using mozilla::TimeStamp;
 using mozilla::TimeDuration;
 
 nsGlobalWindow::WindowByIdTable *nsGlobalWindow::sWindowsById = nullptr;
 bool nsGlobalWindow::sWarnedAboutWindowInternal = false;
 bool nsGlobalWindow::sIdleObserversAPIFuzzTimeDisabled = false;
 
 static nsIEntropyCollector *gEntropyCollector          = nullptr;
@@ -11000,20 +10999,26 @@ nsGlobalChromeWindow::GetMessageManager(
   if (!mMessageManager) {
     nsIScriptContext* scx = GetContextInternal();
     NS_ENSURE_STATE(scx);
     JSContext* cx = scx->GetNativeContext();
     NS_ENSURE_STATE(cx);
     nsCOMPtr<nsIMessageBroadcaster> globalMM =
       do_GetService("@mozilla.org/globalmessagemanager;1");
     mMessageManager =
-      new nsFrameMessageManager(nullptr,
+      new nsFrameMessageManager(true, /* aChrome */
+                                nullptr,
+                                nullptr,
+                                nullptr,
+                                nullptr,
                                 static_cast<nsFrameMessageManager*>(globalMM.get()),
                                 cx,
-                                MM_CHROME | MM_BROADCASTER);
+                                false, /* aGlobal */
+                                false, /* aProcessManager */
+                                true /* aBroadcaster */);
     NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
   }
   CallQueryInterface(mMessageManager, aManager);
   return NS_OK;
 }
 
 // nsGlobalModalWindow implementation
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -568,22 +568,16 @@ struct DelayedDeleteContentParentTask : 
     nsRefPtr<ContentParent> mObj;
 };
 
 }
 
 void
 ContentParent::ActorDestroy(ActorDestroyReason why)
 {
-    nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
-    if (ppm) {
-      ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
-                          CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
-                          nullptr, nullptr, nullptr);
-    }
     nsCOMPtr<nsIThreadObserver>
         kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
         obs->RemoveObserver(static_cast<nsIObserver*>(this), "xpcom-shutdown");
         obs->RemoveObserver(static_cast<nsIObserver*>(this), "memory-pressure");
         obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-memory-reporter-request");
         obs->RemoveObserver(static_cast<nsIObserver*>(this), NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC);
@@ -1884,42 +1878,10 @@ ContentParent::RecvPrivateDocShellsExist
       obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
       delete gPrivateContent;
       gPrivateContent = NULL;
     }
   }
   return true;
 }
 
-bool
-ContentParent::DoSendAsyncMessage(const nsAString& aMessage,
-                                  const mozilla::dom::StructuredCloneData& aData)
-{
-  ClonedMessageData data;
-  SerializedStructuredCloneBuffer& buffer = data.data();
-  buffer.data = aData.mData;
-  buffer.dataLength = aData.mDataLength;
-  const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
-  if (!blobs.IsEmpty()) {
-    InfallibleTArray<PBlobParent*>& blobParents = data.blobsParent();
-    uint32_t length = blobs.Length();
-    blobParents.SetCapacity(length);
-    for (uint32_t i = 0; i < length; ++i) {
-      BlobParent* blobParent = GetOrCreateActorForBlob(blobs[i]);
-      if (!blobParent) {
-        return false;
-      }
-      blobParents.AppendElement(blobParent);
-    }
-  }
-
-  return SendAsyncMessage(nsString(aMessage), data);
-}
-
-bool
-ContentParent::CheckPermission(const nsAString& aPermission)
-{
-  return AssertAppProcessPermission(this, NS_ConvertUTF16toUTF8(aPermission).get());
-}
-
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -10,30 +10,28 @@
 #include "base/waitable_event_watcher.h"
 
 #include "mozilla/dom/PContentParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "mozilla/Attributes.h"
 
-#include "nsFrameMessageManager.h"
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
 #include "nsNetUtil.h"
 #include "nsIPermissionManager.h"
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIMemoryReporter.h"
 #include "nsCOMArray.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 
-#define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown")
-
 class mozIApplication;
+class nsFrameMessageManager;
 class nsIDOMBlob;
 
 namespace mozilla {
 
 namespace ipc {
 class OptionalURIParams;
 class URIParams;
 class TestShellParent;
@@ -48,17 +46,16 @@ namespace dom {
 class TabParent;
 class PStorageParent;
 class ClonedMessageData;
 
 class ContentParent : public PContentParent
                     , public nsIObserver
                     , public nsIThreadObserver
                     , public nsIDOMGeoPositionCallback
-                    , public mozilla::dom::ipc::MessageManagerCallback
 {
     typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
     typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
     typedef mozilla::ipc::TestShellParent TestShellParent;
     typedef mozilla::ipc::URIParams URIParams;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
@@ -85,23 +82,16 @@ public:
 
     static void GetAll(nsTArray<ContentParent*>& aArray);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
     NS_DECL_NSITHREADOBSERVER
     NS_DECL_NSIDOMGEOPOSITIONCALLBACK
 
-    /**
-     * MessageManagerCallback methods that we override.
-     */
-    virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                    const mozilla::dom::StructuredCloneData& aData);
-    virtual bool CheckPermission(const nsAString& aPermission);
-
     /** Notify that a tab was destroyed during normal operation. */
     void NotifyTabDestroyed(PBrowserParent* aTab);
 
     TestShellParent* CreateTestShell();
     bool DestroyTestShell(TestShellParent* aTestShell);
     TestShellParent* GetTestShellSingleton();
 
     void ReportChildAlreadyBlocked();
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -70,17 +70,16 @@
 #include "StructuredCloneUtils.h"
 #include "xpcpublic.h"
 
 #define BROWSER_ELEMENT_CHILD_SCRIPT \
     NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
 
 using namespace mozilla;
 using namespace mozilla::dom;
-using namespace mozilla::dom::ipc;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::widget;
 
 NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
@@ -1454,22 +1453,24 @@ TabChild::AllocPIndexedDB(const nsCStrin
 
 bool
 TabChild::DeallocPIndexedDB(PIndexedDBChild* aActor)
 {
   delete aActor;
   return true;
 }
 
-bool
-TabChild::DoSendSyncMessage(const nsAString& aMessage,
-                            const StructuredCloneData& aData,
-                            InfallibleTArray<nsString>* aJSONRetVal)
+static bool
+SendSyncMessageToParent(void* aCallbackData,
+                        const nsAString& aMessage,
+                        const StructuredCloneData& aData,
+                        InfallibleTArray<nsString>* aJSONRetVal)
 {
-  ContentChild* cc = static_cast<ContentChild*>(Manager());
+  TabChild* tabChild = static_cast<TabChild*>(aCallbackData);
+  ContentChild* cc = static_cast<ContentChild*>(tabChild->Manager());
   ClonedMessageData data;
   SerializedStructuredCloneBuffer& buffer = data.data();
   buffer.data = aData.mData;
   buffer.dataLength = aData.mDataLength;
 
   const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
   if (!blobs.IsEmpty()) {
     InfallibleTArray<PBlobChild*>& blobChildList = data.blobsChild();
@@ -1478,24 +1479,26 @@ TabChild::DoSendSyncMessage(const nsAStr
     for (uint32_t i = 0; i < length; ++i) {
       BlobChild* blobChild = cc->GetOrCreateActorForBlob(blobs[i]);
       if (!blobChild) {
         return false;
       }
       blobChildList.AppendElement(blobChild);
     }
   }
-  return SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
+  return tabChild->SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
 }
 
-bool
-TabChild::DoSendAsyncMessage(const nsAString& aMessage,
-                             const StructuredCloneData& aData)
+static bool
+SendAsyncMessageToParent(void* aCallbackData,
+                         const nsAString& aMessage,
+                         const StructuredCloneData& aData)
 {
-  ContentChild* cc = static_cast<ContentChild*>(Manager());
+  TabChild* tabChild = static_cast<TabChild*>(aCallbackData);
+  ContentChild* cc = static_cast<ContentChild*>(tabChild->Manager());
   ClonedMessageData data;
   SerializedStructuredCloneBuffer& buffer = data.data();
   buffer.data = aData.mData;
   buffer.dataLength = aData.mDataLength;
 
   const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
   if (!blobs.IsEmpty()) {
     InfallibleTArray<PBlobChild*>& blobChildList = data.blobsChild();
@@ -1505,33 +1508,36 @@ TabChild::DoSendAsyncMessage(const nsASt
       BlobChild* blobChild = cc->GetOrCreateActorForBlob(blobs[i]);
       if (!blobChild) {
         return false;
       }
       blobChildList.AppendElement(blobChild);
     }
   }
 
-  return SendAsyncMessage(nsString(aMessage), data);
+  return tabChild->SendAsyncMessage(nsString(aMessage), data);
 }
 
 
 TabChildGlobal::TabChildGlobal(TabChild* aTabChild)
 : mTabChild(aTabChild)
 {
 }
 
 void
 TabChildGlobal::Init()
 {
   NS_ASSERTION(!mMessageManager, "Re-initializing?!?");
-  mMessageManager = new nsFrameMessageManager(mTabChild,
+  mMessageManager = new nsFrameMessageManager(false, /* aChrome */
+                                              SendSyncMessageToParent,
+                                              SendAsyncMessageToParent,
                                               nullptr,
-                                              mTabChild->GetJSContext(),
-                                              MM_CHILD);
+                                              mTabChild,
+                                              nullptr,
+                                              mTabChild->GetJSContext());
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildGlobal)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildGlobal,
                                                 nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMessageManager)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -139,18 +139,17 @@ class TabChild : public PBrowserChild,
                  public nsIWebBrowserChrome2,
                  public nsIEmbeddingSiteWindow,
                  public nsIWebBrowserChromeFocus,
                  public nsIInterfaceRequestor,
                  public nsIWindowProvider,
                  public nsSupportsWeakReference,
                  public nsIDialogCreator,
                  public nsITabChild,
-                 public nsIObserver,
-                 public mozilla::dom::ipc::MessageManagerCallback
+                 public nsIObserver
 {
     typedef mozilla::layout::RenderFrameChild RenderFrameChild;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
     /** 
      * This is expected to be called off the critical path to content
      * startup.  This is an opportunity to load things that are slow
@@ -174,25 +173,16 @@ public:
     NS_DECL_NSIEMBEDDINGSITEWINDOW
     NS_DECL_NSIWEBBROWSERCHROMEFOCUS
     NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSIWINDOWPROVIDER
     NS_DECL_NSIDIALOGCREATOR
     NS_DECL_NSITABCHILD
     NS_DECL_NSIOBSERVER
 
-    /**
-     * MessageManagerCallback methods that we override.
-     */
-    virtual bool DoSendSyncMessage(const nsAString& aMessage,
-                                   const mozilla::dom::StructuredCloneData& aData,
-                                   InfallibleTArray<nsString>* aJSONRetVal);
-    virtual bool DoSendAsyncMessage(const nsAString& aMessage,
-                                    const mozilla::dom::StructuredCloneData& aData);
-
     virtual bool RecvLoadURL(const nsCString& uri);
     virtual bool RecvShow(const nsIntSize& size);
     virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
     virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
     virtual bool RecvHandleDoubleTap(const nsIntPoint& aPoint);
     virtual bool RecvHandleSingleTap(const nsIntPoint& aPoint);
     virtual bool RecvActivate();
     virtual bool RecvDeactivate();
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -127,17 +127,16 @@ TabParent::ActorDestroy(ActorDestroyReas
   if (sEventCapturer == this) {
     sEventCapturer = nullptr;
   }
   if (mIMETabParent == this) {
     mIMETabParent = nullptr;
   }
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   if (frameLoader) {
-    ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr);
     frameLoader->DestroyChild();
 
     if (why == AbnormalShutdown) {
       nsCOMPtr<nsIObserverService> os = services::GetObserverService();
       if (os) {
         os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, frameLoader),
                             "oop-frameloader-crashed", nullptr);
       }
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -35,49 +35,45 @@ const nsIAudioManager = Ci.nsIAudioManag
 const nsIRadioInterfaceLayer = Ci.nsIRadioInterfaceLayer;
 
 const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
 const kSmsReceivedObserverTopic          = "sms-received";
 const kSmsSentObserverTopic              = "sms-sent";
 const kSmsDeliveredObserverTopic         = "sms-delivered";
 const kMozSettingsChangedObserverTopic   = "mozsettings-changed";
 const kSysMsgListenerReadyObserverTopic  = "system-message-listener-ready";
-const kTimeNitzAutomaticUpdateEnabled    = "time.nitz.automatic-update.enabled";
 const DOM_SMS_DELIVERY_RECEIVED          = "received";
 const DOM_SMS_DELIVERY_SENT              = "sent";
 
-const RIL_IPC_TELEPHONY_MSG_NAMES = [
+const RIL_IPC_MSG_NAMES = [
+  "RIL:GetRilContext",
   "RIL:EnumerateCalls",
   "RIL:GetMicrophoneMuted",
   "RIL:SetMicrophoneMuted",
   "RIL:GetSpeakerEnabled",
   "RIL:SetSpeakerEnabled",
   "RIL:StartTone",
   "RIL:StopTone",
   "RIL:Dial",
   "RIL:DialEmergency",
   "RIL:HangUp",
   "RIL:AnswerCall",
   "RIL:RejectCall",
   "RIL:HoldCall",
   "RIL:ResumeCall",
-];
-
-const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
-  "RIL:GetRilContext",
   "RIL:GetAvailableNetworks",
   "RIL:SelectNetwork",
   "RIL:SelectNetworkAuto",
   "RIL:GetCardLock",
   "RIL:UnlockCardLock",
   "RIL:SetCardLock",
   "RIL:SendUSSD",
   "RIL:CancelUSSD",
   "RIL:SendStkResponse",
-  "RIL:SendStkMenuSelection",
+  "RIL:SendStkMenuSelection"
 ];
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSmsService",
                                    "@mozilla.org/sms/smsservice;1",
                                    "nsISmsService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSmsRequestManager",
                                    "@mozilla.org/sms/smsrequestmanager;1",
@@ -98,20 +94,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
 XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
                                    "@mozilla.org/system-message-internal;1",
                                    "nsISystemMessagesInternal");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
                                    "@mozilla.org/network/manager;1",
                                    "nsINetworkManager");
 
-XPCOMUtils.defineLazyServiceGetter(this, "gTimeService",
-                                   "@mozilla.org/time/timeservice;1",
-                                   "nsITimeService");
-
 XPCOMUtils.defineLazyGetter(this, "WAP", function () {
   let WAP = {};
   Cu.import("resource://gre/modules/WapPushManager.js", WAP);
   return WAP;
 });
 
 function convertRILCallState(state) {
   switch (state) {
@@ -239,26 +231,19 @@ function RadioInterfaceLayer() {
   lock.get("ril.supl.user", this);
   lock.get("ril.supl.passwd", this);
   lock.get("ril.supl.httpProxyHost", this);
   lock.get("ril.supl.httpProxyPort", this);
 
   // Read the desired setting of call waiting from the settings DB.
   lock.get("ril.callwaiting.enabled", this);
 
-  // Read the 'time.nitz.automatic-update.enabled' setting to see if
-  // we need to adjust the system clock time and time zone by NITZ.
-  lock.get(kTimeNitzAutomaticUpdateEnabled, this);
-
   this._messageManagerByRequest = {};
 
-  for (let msgname of RIL_IPC_TELEPHONY_MSG_NAMES) {
-    ppmm.addMessageListener(msgname, this);
-  }
-  for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) {
+  for each (let msgname in RIL_IPC_MSG_NAMES) {
     ppmm.addMessageListener(msgname, this);
   }
   Services.obs.addObserver(this, "xpcom-shutdown", false);
   Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
   Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false);
 
   this._sentSmsEnvelopes = {};
 
@@ -278,33 +263,16 @@ RadioInterfaceLayer.prototype = {
                                          Ci.nsIObserver,
                                          Ci.nsISettingsServiceCallback]),
 
   /**
    * Process a message from the content process.
    */
   receiveMessage: function receiveMessage(msg) {
     debug("Received '" + msg.name + "' message from content process");
-    if (RIL_IPC_TELEPHONY_MSG_NAMES.indexOf(msg.name) != -1) {
-      if (!msg.target.assertPermission("telephony")) {
-        debug("Telephony message " + msg.name +
-              " from a content process with no 'telephony' privileges.");
-        return null;
-      }
-    } else if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) {
-      if (!msg.target.assertPermission("mobileconnection")) {
-        debug("MobileConnection message " + msg.name +
-              " from a content process with no 'mobileconnection' privileges.");
-        return null;
-      }
-    } else {
-      debug("Ignoring unknown message type: " + msg.name);
-      return null;
-    }
-
     switch (msg.name) {
       case "RIL:GetRilContext":
         // This message is sync.
         return this.rilContext;
       case "RIL:EnumerateCalls":
         this.saveRequestTarget(msg);
         this.enumerateCalls(msg.json);
         break;
@@ -473,17 +441,27 @@ RadioInterfaceLayer.prototype = {
         return;
       case "datacallstatechange":
         this.handleDataCallState(message);
         break;
       case "datacalllist":
         this.handleDataCallList(message);
         break;
       case "nitzTime":
-        this.handleNitzTime(message);
+        // TODO bug 714349
+        // Send information to time manager to decide what to do with it
+        // Message contains networkTimeInSeconds, networkTimeZoneInMinutes,
+        // dstFlag,localTimeStampInMS
+        // indicating the time, daylight savings flag, and timezone
+        // sent from the network and a timestamp of when the message was received
+        // so an offset can be added if/when the time is actually set.
+        debug("nitzTime networkTime=" + message.networkTimeInSeconds +
+              " timezone=" + message.networkTimeZoneInMinutes +
+              " dst=" + message.dstFlag +
+              " timestamp=" + message.localTimeStampInMS);
         break;
       case "iccinfochange":
         this.handleICCInfoChange(message);
         break;
       case "iccGetCardLock":
       case "iccSetCardLock":
       case "iccUnlockCardLock":
         this.handleICCCardLockResult(message);
@@ -1216,45 +1194,16 @@ RadioInterfaceLayer.prototype = {
   /**
    * Handle data call list.
    */
   handleDataCallList: function handleDataCallList(message) {
     this._deliverDataCallCallback("receiveDataCallList",
                                   [message.datacalls, message.datacalls.length]);
   },
 
-  /**
-   * Handle the NITZ message.
-   */
-  handleNitzTime: function handleNitzTime(message) {
-    if (!this._nitzAutomaticUpdateEnabled) {
-      return;
-    }
-    // To set the system clock time. Note that there could be a time diff
-    // between when the NITZ was received and when the time is actually set.
-    gTimeService.set(
-      message.networkTimeInMS + (Date.now() - message.receiveTimeInMS));
-
-    // To set the sytem timezone. Note that we need to convert the time zone
-    // value to a UTC repesentation string in the format of "UTC(+/-)hh:mm".
-    // Ex, time zone -480 is "UTC-08:00"; time zone 630 is "UTC+10:30".
-    //
-    // We can unapply the DST correction if we want the raw time zone offset:
-    // message.networkTimeZoneInMinutes -= message.networkDSTInMinutes;
-    if (message.networkTimeZoneInMinutes != (new Date()).getTimezoneOffset()) {
-      let absTimeZoneInMinutes = Math.abs(message.networkTimeZoneInMinutes);
-      let timeZoneStr = "UTC";
-      timeZoneStr += (message.networkTimeZoneInMinutes >= 0 ? "+" : "-");
-      timeZoneStr += ("0" + Math.floor(absTimeZoneInMinutes / 60)).slice(-2);
-      timeZoneStr += ":";
-      timeZoneStr += ("0" + absTimeZoneInMinutes % 60).slice(-2);
-      gSettingsService.createLock().set("time.timezone", timeZoneStr, null);
-    }
-  },
-
   handleICCInfoChange: function handleICCInfoChange(message) {
     let oldIcc = this.rilContext.icc;
     this.rilContext.icc = message;
    
     let iccInfoChanged = !oldIcc ||
                          oldIcc.iccid != message.iccid ||
                          oldIcc.mcc != message.mcc || 
                          oldIcc.mnc != message.mnc;
@@ -1304,20 +1253,17 @@ RadioInterfaceLayer.prototype = {
         this._sysMsgListenerReady = true;
         this._ensureRadioState();
         break;
       case kMozSettingsChangedObserverTopic:
         let setting = JSON.parse(data);
         this.handle(setting.key, setting.value);
         break;
       case "xpcom-shutdown":
-        for (let msgname of RIL_IPC_TELEPHONY_MSG_NAMES) {
-          ppmm.removeMessageListener(msgname, this);
-        }
-        for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) {
+        for each (let msgname in RIL_IPC_MSG_NAMES) {
           ppmm.removeMessageListener(msgname, this);
         }
         // Shutdown all RIL network interfaces
         this.dataNetworkInterface.shutdown();
         this.mmsNetworkInterface.shutdown();
         this.suplNetworkInterface.shutdown();
         ppmm = null;
         Services.obs.removeObserver(this, "xpcom-shutdown");
@@ -1341,21 +1287,18 @@ RadioInterfaceLayer.prototype = {
 
   // APN data for making data calls.
   dataCallSettings: {},
   dataCallSettingsMMS: {},
   dataCallSettingsSUPL: {},
   _dataCallSettingsToRead: [],
   _oldRilDataEnabledState: null,
 
-  // Flag to determine whether to use NITZ. It corresponds to the
-  // 'time.nitz.automatic-update.enabled' setting from the UI.
-  _nitzAutomaticUpdateEnabled: null,
+  // nsISettingsServiceCallback
 
-  // nsISettingsServiceCallback
   handle: function handle(aName, aResult) {
     switch(aName) {
       case "ril.radio.disabled":
         debug("'ril.radio.disabled' is now " + aResult);
         this._radioEnabled = !aResult;
         this._ensureRadioState();
         break;
       case "ril.radio.preferredNetworkType":
@@ -1398,19 +1341,16 @@ RadioInterfaceLayer.prototype = {
       case "ril.supl.httpProxyPort":
         key = aName.slice(9);
         this.dataCallSettingsSUPL[key] = aResult;
         break;
       case "ril.callwaiting.enabled":
         this._callWaitingEnabled = aResult;
         this.setCallWaitingEnabled(this._callWaitingEnabled);
         break;
-      case kTimeNitzAutomaticUpdateEnabled:
-        this._nitzAutomaticUpdateEnabled = aResult;
-        break;
     };
   },
 
   handleError: function handleError(aErrorMessage) {
     debug("There was an error while reading RIL settings.");
 
     // Default radio to on.
     this._radioEnabled = true;
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -4523,34 +4523,32 @@ RIL[UNSOLICITED_NITZ_TIME_RECEIVED] = fu
   let now = Date.now();
 	
   let year = parseInt(dateString.substr(0, 2), 10);
   let month = parseInt(dateString.substr(3, 2), 10);
   let day = parseInt(dateString.substr(6, 2), 10);
   let hours = parseInt(dateString.substr(9, 2), 10);
   let minutes = parseInt(dateString.substr(12, 2), 10);
   let seconds = parseInt(dateString.substr(15, 2), 10);
-  // Note that |tz| is in 15-min units.
-  let tz = parseInt(dateString.substr(17, 3), 10);
-  // Note that |dst| is in 1-hour units and is already applied in |tz|.
-  let dst = parseInt(dateString.substr(21, 2), 10);
-
-  let timeInMS = Date.UTC(year + PDU_TIMESTAMP_YEAR_OFFSET, month - 1, day,
-                          hours, minutes, seconds);
-
-  if (isNaN(timeInMS)) {
+  let tz = parseInt(dateString.substr(17, 3), 10); // TZ is in 15 min. units
+  let dst = parseInt(dateString.substr(21, 2), 10); // DST already is in local time
+
+  let timeInSeconds = Date.UTC(year + PDU_TIMESTAMP_YEAR_OFFSET, month - 1, day,
+                               hours, minutes, seconds) / 1000;
+
+  if (isNaN(timeInSeconds)) {
     if (DEBUG) debug("NITZ failed to convert date");
     return;
   }
 
   this.sendDOMMessage({rilMessageType: "nitzTime",
-                       networkTimeInMS: timeInMS,
-                       networkTimeZoneInMinutes: -(tz * 15),
-                       networkDSTInMinutes: -(dst * 60),
-                       receiveTimeInMS: now});
+                       networkTimeInSeconds: timeInSeconds,
+                       networkTimeZoneInMinutes: tz * 15,
+                       dstFlag: dst,
+                       localTimeStampInMS: now});
 };
 
 RIL[UNSOLICITED_SIGNAL_STRENGTH] = function UNSOLICITED_SIGNAL_STRENGTH(length) {
   this[REQUEST_SIGNAL_STRENGTH](length, {rilRequestError: ERROR_SUCCESS});
 };
 RIL[UNSOLICITED_DATA_CALL_LIST_CHANGED] = function UNSOLICITED_DATA_CALL_LIST_CHANGED(length) {
   if (RILQUIRKS_V5_LEGACY) {
     this.getDataCallList();
--- a/dom/time/Makefile.in
+++ b/dom/time/Makefile.in
@@ -4,39 +4,33 @@
 
 DEPTH            = ../..
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE           = dom
 LIBRARY_NAME     = dom_time_s
 XPIDL_MODULE     = dom_time
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 FAIL_ON_WARNINGS := 1
 
 include $(topsrcdir)/dom/dom-config.mk
 
-EXPORTS_NAMESPACES = mozilla/dom/time
-
 CPPSRCS = \
   TimeManager.cpp \
-  TimeService.cpp \
   TimeChangeObserver.cpp \
   $(NULL)
 
-EXPORTS_mozilla/dom/time = \
-  TimeService.h \
+EXPORTS = \
   TimeChangeObserver.h \
   $(NULL)
 
 XPIDLSRCS = \
   nsIDOMNavigatorTime.idl \
   nsIDOMTimeManager.idl \
-  nsITimeService.idl \
   $(NULL)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
--- a/dom/time/TimeManager.cpp
+++ b/dom/time/TimeManager.cpp
@@ -1,17 +1,21 @@
 /* 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 "jsapi.h"
+#include "mozilla/Hal.h"
+#include "nsDOMEvent.h"
+#include "nsDOMEventTargetHelper.h"
 #include "nsIDOMClassInfo.h"
-#include "nsITimeService.h"
+#include "prtime.h"
 #include "TimeManager.h"
 
+using namespace mozilla::hal;
+
 DOMCI_DATA(MozTimeManager, mozilla::dom::time::TimeManager)
 
 namespace mozilla {
 namespace dom {
 namespace time {
 
 NS_INTERFACE_MAP_BEGIN(TimeManager)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozTimeManager)
@@ -19,16 +23,17 @@ NS_INTERFACE_MAP_BEGIN(TimeManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozTimeManager)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(TimeManager)
 NS_IMPL_RELEASE(TimeManager)
 
 nsresult
 TimeManager::Set(const JS::Value& date, JSContext* ctx) {
+  double nowMSec = JS_Now() / 1000;
   double dateMSec;
 
   if (date.isObject()) {
     JSObject* dateObj = JSVAL_TO_OBJECT(date);
 
     if (JS_ObjectIsDate(ctx, dateObj) && js_DateIsValid(ctx, dateObj)) {
       dateMSec = js_DateGetMsecSinceEpoch(ctx, dateObj);
     }
@@ -38,18 +43,15 @@ TimeManager::Set(const JS::Value& date, 
       return NS_ERROR_INVALID_ARG;
     }
   } else if (date.isNumber()) {
     dateMSec = date.toNumber();
   } else {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsCOMPtr<nsITimeService> timeService = do_GetService(TIMESERVICE_CONTRACTID);
-  if (timeService) {
-    return timeService->Set(dateMSec);
-  }
+  hal::AdjustSystemClock(dateMSec - nowMSec);
   return NS_OK;
 }
 
 } // namespace time
 } // namespace dom
 } // namespace mozilla
--- a/dom/time/TimeManager.h
+++ b/dom/time/TimeManager.h
@@ -1,22 +1,28 @@
 /* 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_dom_time_TimeManager_h
 #define mozilla_dom_time_TimeManager_h
 
+#include "mozilla/HalTypes.h"
 #include "nsIDOMTimeManager.h"
+#include "mozilla/Observer.h"
 #include "mozilla/Attributes.h"
 
+class nsPIDOMWindow;
+
 namespace mozilla {
+
+typedef Observer<hal::SystemTimeChange> SystemTimeObserver;
+
 namespace dom {
 namespace time {
-
 class TimeManager MOZ_FINAL : public nsIDOMMozTimeManager
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMMOZTIMEMANAGER
 };
 
 } // namespace time
deleted file mode 100644
--- a/dom/time/TimeService.cpp
+++ /dev/null
@@ -1,38 +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/. */
-
-#include "base/basictypes.h"
-#include "jsapi.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/Hal.h"
-#include "TimeService.h"
-
-namespace mozilla {
-namespace dom {
-namespace time {
-
-NS_IMPL_ISUPPORTS1(TimeService, nsITimeService)
-
-/* static */ StaticRefPtr<TimeService> TimeService::sSingleton;
-
-/* static */ already_AddRefed<TimeService>
-TimeService::GetInstance()
-{
-  if (!sSingleton) {
-    sSingleton = new TimeService();
-    ClearOnShutdown(&sSingleton);
-  }
-  nsRefPtr<TimeService> service = sSingleton.get();
-  return service.forget();
-}
-
-NS_IMETHODIMP
-TimeService::Set(int64_t aTimeInMS) {
-  hal::AdjustSystemClock(aTimeInMS - (JS_Now() / PR_USEC_PER_MSEC));
-  return NS_OK;
-}
-
-} // namespace time
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/time/TimeService.h
+++ /dev/null
@@ -1,35 +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/. */
-
-#ifndef mozilla_dom_time_TimeService_h
-#define mozilla_dom_time_TimeService_h
-
-#include "mozilla/StaticPtr.h"
-#include "nsITimeService.h"
-
-namespace mozilla {
-namespace dom {
-namespace time {
-
-/**
- * This class implements a service which lets us modify the system clock time.
- */
-class TimeService : public nsITimeService
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSITIMESERVICE
-
-  virtual ~TimeService() {};
-  static already_AddRefed<TimeService> GetInstance();
-
-private:
-  static StaticRefPtr<TimeService> sSingleton;
-};
-
-} // namespace time
-} // namespace dom
-} // namespace mozilla
-
-#endif //mozilla_dom_time_TimeService_h
deleted file mode 100644
--- a/dom/time/nsITimeService.idl
+++ /dev/null
@@ -1,20 +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/. */
-
-#include "nsISupports.idl"
-
-%{C++
-#define NS_TIMESERVICE_CID { 0x80d6f9cc, 0xf16d, 0x40c3, { 0xa5, 0x2e, 0xc4, 0xe6, 0x56, 0xe3, 0x65, 0xb4 } }
-#define TIMESERVICE_CONTRACTID "@mozilla.org/time/timeservice;1"
-%}
-
-[scriptable, builtinclass, uuid(1fc7fde2-0090-11e2-bdd6-0fea4b9f41f8)]
-interface nsITimeService : nsISupports
-{
-  /* Set the system time.
-   *
-   * The |aTimeInMS| argument is the time in milliseconds since the epoch.
-   */
-  void set(in int64_t aTimeInMS);
-};
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -236,27 +236,26 @@ static void Shutdown();
 #include "mozilla/dom/sms/SmsRequestManager.h"
 #include "mozilla/dom/sms/SmsServicesFactory.h"
 #include "nsIPowerManagerService.h"
 #include "nsIAlarmHalService.h"
 #include "nsMixedContentBlocker.h"
 
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/alarm/AlarmHalService.h"
-#include "mozilla/dom/time/TimeService.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::dom::file;
 using namespace mozilla::dom::sms;
 using mozilla::dom::alarm::AlarmHalService;
 using mozilla::dom::indexedDB::IndexedDatabaseManager;
 using mozilla::dom::power::PowerManagerService;
 using mozilla::dom::TCPSocketChild;
-using mozilla::dom::time::TimeService;
+
 
 // Transformiix
 /* 5d5d92cd-6bf8-11d9-bf4a-000a95dc234c */
 #define TRANSFORMIIX_NODESET_CID \
 { 0x5d5d92cd, 0x6bf8, 0x11d9, { 0xbf, 0x4a, 0x0, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
 
 #define TRANSFORMIIX_NODESET_CONTRACTID \
 "@mozilla.org/transformiix-nodeset;1"
@@ -311,18 +310,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHapticF
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ThirdPartyUtil, Init)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsService, SmsServicesFactory::CreateSmsService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsDatabaseService, SmsServicesFactory::CreateSmsDatabaseService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIPowerManagerService,
                                          PowerManagerService::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(SmsRequestManager)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIAlarmHalService,
                                          AlarmHalService::GetInstance)
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsITimeService,
-                                         TimeService::GetInstance)
 
 //-----------------------------------------------------------------------------
 
 // Per bug 209804, it is necessary to observe the "xpcom-shutdown" event and
 // perform shutdown of the layout modules at that time instead of waiting for
 // our module destructor to run.  If we do not do this, then we risk holding
 // references to objects in other component libraries that have already been
 // shutdown (and possibly unloaded if 60709 is ever fixed).
@@ -826,17 +823,16 @@ NS_DEFINE_NAMED_CID(NS_HAPTICFEEDBACK_CI
 #endif
 NS_DEFINE_NAMED_CID(SMS_SERVICE_CID);
 NS_DEFINE_NAMED_CID(SMS_DATABASE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(SMS_REQUEST_MANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_POWERMANAGERSERVICE_CID);
 NS_DEFINE_NAMED_CID(OSFILECONSTANTSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_ALARMHALSERVICE_CID);
 NS_DEFINE_NAMED_CID(TCPSOCKETCHILD_CID);
-NS_DEFINE_NAMED_CID(NS_TIMESERVICE_CID);
 
 static nsresult
 CreateWindowCommandTableConstructor(nsISupports *aOuter,
                                     REFNSIID aIID, void **aResult)
 {
   nsresult rv;
   nsCOMPtr<nsIControllerCommandTable> commandTable =
       do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
@@ -1106,17 +1102,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_DOMMUTATIONOBSERVER_CID, false, NULL, nsDOMMutationObserverConstructor },
   { &kSMS_SERVICE_CID, false, NULL, nsISmsServiceConstructor },
   { &kSMS_DATABASE_SERVICE_CID, false, NULL, nsISmsDatabaseServiceConstructor },
   { &kSMS_REQUEST_MANAGER_CID, false, NULL, SmsRequestManagerConstructor },
   { &kNS_POWERMANAGERSERVICE_CID, false, NULL, nsIPowerManagerServiceConstructor },
   { &kOSFILECONSTANTSSERVICE_CID, true, NULL, OSFileConstantsServiceConstructor },
   { &kNS_ALARMHALSERVICE_CID, false, NULL, nsIAlarmHalServiceConstructor },
   { &kTCPSOCKETCHILD_CID, false, NULL, TCPSocketChildConstructor },
-  { &kNS_TIMESERVICE_CID, false, NULL, nsITimeServiceConstructor },
   { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
   XPCONNECT_CONTRACTS
   { "@mozilla.org/layout/xul-boxobject;1", &kNS_BOXOBJECT_CID },
 #ifdef MOZ_XUL
   { "@mozilla.org/layout/xul-boxobject-listbox;1", &kNS_LISTBOXOBJECT_CID },
@@ -1251,17 +1246,16 @@ static const mozilla::Module::ContractID
   { NS_DOMMUTATIONOBSERVER_CONTRACTID, &kNS_DOMMUTATIONOBSERVER_CID },
   { SMS_SERVICE_CONTRACTID, &kSMS_SERVICE_CID },
   { SMS_DATABASE_SERVICE_CONTRACTID, &kSMS_DATABASE_SERVICE_CID },
   { SMS_REQUEST_MANAGER_CONTRACTID, &kSMS_REQUEST_MANAGER_CID },
   { POWERMANAGERSERVICE_CONTRACTID, &kNS_POWERMANAGERSERVICE_CID },
   { OSFILECONSTANTSSERVICE_CONTRACTID, &kOSFILECONSTANTSSERVICE_CID },
   { ALARMHALSERVICE_CONTRACTID, &kNS_ALARMHALSERVICE_CID },
   { "@mozilla.org/tcp-socket-child;1", &kTCPSOCKETCHILD_CID },
-  { TIMESERVICE_CONTRACTID, &kNS_TIMESERVICE_CID },
   { NULL }
 };
 
 static const mozilla::Module::CategoryEntry kLayoutCategories[] = {
   XPCONNECT_CATEGORIES
   { JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY, "Image", NS_HTMLIMGELEMENT_CONTRACTID },
   { JAVASCRIPT_GLOBAL_CONSTRUCTOR_PROTO_ALIAS_CATEGORY, "Image", "HTMLImageElement" },
   { JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY, "Option", NS_HTMLOPTIONELEMENT_CONTRACTID },