Backout be95f234ff6e (bug 776832) for various mochitest-1 failures
authorEd Morley <emorley@mozilla.com>
Wed, 26 Sep 2012 10:31:19 +0100
changeset 108124 eb8a3fd355ba5b364c611e662ad65002394068c9
parent 108123 55ccbc8d52e69b020f2ba493e92ad2e214388df0
child 108125 71192a9431a74baf053bb127f2c61d2455a20590
push id23539
push userryanvm@gmail.com
push dateWed, 26 Sep 2012 22:55:55 +0000
treeherdermozilla-central@ec079fd92224 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs776832
milestone18.0a1
backs outbe95f234ff6e36bcd6b04d40668239684f7f3a70
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout be95f234ff6e (bug 776832) for various mochitest-1 failures
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_messagemanager_assertpermission.html
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
--- 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)
@@ -1254,23 +1252,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);
@@ -2152,37 +2150,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;
   }
 
@@ -2205,21 +2204,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;
@@ -2239,33 +2239,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;
@@ -2336,17 +2331,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();
@@ -2355,30 +2350,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),
@@ -116,20 +121,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
@@ -564,17 +564,16 @@ MOCHITEST_FILES_B = \
 		file_XHR_anon.sjs \
 		test_XHR_system.html \
 		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 \
-		test_messagemanager_assertpermission.html \
 		$(NULL)
 
 MOCHITEST_CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 MOCHITEST_FILES_PARTS = $(foreach s,A B,MOCHITEST_FILES_$(s))
 
deleted file mode 100644
--- a/content/base/test/test_messagemanager_assertpermission.html
+++ /dev/null
@@ -1,153 +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";
-
-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();
-}
-
-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);
-  });
-}
-
-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);
-    ok(frameMM.assertPermission("foobar"), "Frame mm has assigned permission.");
-    ok(!frameMM.assertPermission("frobnaz"), "Frame mm doesn't have non-existing permission.");
-
-    // The last permission check will result in the content process
-    // being killed.
-    iframe.addEventListener("mozbrowsererror", function onerror(event) {
-      iframe.removeEventListener("mozbrowsererror", onerror);
-      ok(event.detail.type, "fatal");
-
-      iframe.parentNode.removeChild(iframe);
-      runNextTest();
-    });
-  });
-}
-
-function testChildProcessMessageManager() {
-  // Assert permissions on the child process message manager. We get
-  // one by sending a message to a frame script in the content process
-  // and having it reply to us via the child process message manager.
-
-  let frameScript = 'data:,\
-    var cpmm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]\
-                         .getService(Components.interfaces.nsISyncMessageSender);\
-    addMessageListener("TestPermission:OutOfProcess", function receiveMessage(msg) {\
-      cpmm.sendAsyncMessage("TestPermission:OutOfProcess");\
-    });';
-
-  loadApp(function (iframe) {
-    let frameMM = SpecialPowers.getBrowserFrameMessageManager(iframe);
-    frameMM.loadFrameScript(frameScript, false);
-
-    frameMM.sendAsyncMessage("TestPermission:OutOfProcess");
-    ppmm.addMessageListener("TestPermission:OutOfProcess", function receiveMessage(msg) {
-      ppmm.removeMessageListener("TestPermission:OutOfProcess", receiveMessage);
-      msg = SpecialPowers.wrap(msg);
-
-      let mm = msg.target;
-      ok(mm.assertPermission("foobar"), "Process mm has assigned permission.");
-      ok(!mm.assertPermission("frobnaz"), "Process mm doesn't have non-existing permission.");
-
-      // The last permission check will result in the content process
-      // being killed.
-      iframe.addEventListener("mozbrowsererror", function onerror(event) {
-        iframe.removeEventListener("mozbrowsererror", onerror);
-        ok(event.detail.type, "fatal");
-
-        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/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;
@@ -10985,20 +10984,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
@@ -1878,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,28 +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"
 
 class mozIApplication;
+class nsFrameMessageManager;
 class nsIDOMBlob;
 
 namespace mozilla {
 
 namespace ipc {
 class OptionalURIParams;
 class URIParams;
 class TestShellParent;
@@ -46,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:
@@ -83,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();