diff --git a/dom/base/ChromeMessageBroadcaster.cpp b/dom/base/ChromeMessageBroadcaster.cpp index 677f8a793126..0d7a3141111b 100644 --- a/dom/base/ChromeMessageBroadcaster.cpp +++ b/dom/base/ChromeMessageBroadcaster.cpp @@ -7,12 +7,13 @@ #include "mozilla/dom/ChromeMessageBroadcaster.h" #include "AccessCheck.h" #include "mozilla/HoldDropJSObjects.h" +#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/MessageManagerBinding.h" namespace mozilla { namespace dom { -ChromeMessageBroadcaster::ChromeMessageBroadcaster(nsFrameMessageManager* aParentManager, +ChromeMessageBroadcaster::ChromeMessageBroadcaster(ChromeMessageBroadcaster* aParentManager, MessageManagerFlags aFlags) : MessageListenerManager(nullptr, aParentManager, aFlags | @@ -43,5 +44,28 @@ ChromeMessageBroadcaster::WrapObject(JSContext* aCx, return ChromeMessageBroadcasterBinding::Wrap(aCx, this, aGivenProto); } +void +ChromeMessageBroadcaster::ReleaseCachedProcesses() +{ + ContentParent::ReleaseCachedProcesses(); +} + +void +ChromeMessageBroadcaster::AddChildManager(MessageListenerManager* aManager) +{ + mChildManagers.AppendElement(aManager); + + RefPtr kungfuDeathGrip = this; + RefPtr kungfuDeathGrip2 = aManager; + + LoadPendingScripts(this, aManager); +} + +void +ChromeMessageBroadcaster::RemoveChildManager(MessageListenerManager* aManager) +{ + mChildManagers.RemoveElement(aManager); +} + } // namespace dom } // namespace mozilla diff --git a/dom/base/ChromeMessageBroadcaster.h b/dom/base/ChromeMessageBroadcaster.h index 742ada06819f..9f7a09460ec7 100644 --- a/dom/base/ChromeMessageBroadcaster.h +++ b/dom/base/ChromeMessageBroadcaster.h @@ -22,14 +22,21 @@ public: MessageManagerFlags::MM_PROCESSMANAGER | MessageManagerFlags::MM_OWNSCALLBACK))); } - explicit ChromeMessageBroadcaster(nsFrameMessageManager* aParentManager) + explicit ChromeMessageBroadcaster(ChromeMessageBroadcaster* aParentManager) : ChromeMessageBroadcaster(aParentManager, MessageManagerFlags::MM_NONE) {} + static ChromeMessageBroadcaster* From(nsFrameMessageManager* aManager) + { + if (aManager->IsBroadcaster() && aManager->IsChrome()) { + return static_cast(aManager); + } + return nullptr; + } + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - using nsFrameMessageManager::BroadcastAsyncMessage; void BroadcastAsyncMessage(JSContext* aCx, const nsAString& aMessageName, JS::Handle aObj, JS::Handle aObjects, @@ -42,12 +49,11 @@ public: { return mChildManagers.Length(); } - using nsFrameMessageManager::GetChildAt; MessageListenerManager* GetChildAt(uint32_t aIndex) { return mChildManagers.SafeElementAt(aIndex); } - // XPCOM ReleaseCachedProcesses is OK + void ReleaseCachedProcesses(); // ProcessScriptLoader void LoadProcessScript(const nsAString& aUrl, bool aAllowDelayedLoad, @@ -86,8 +92,11 @@ public: GetDelayedScripts(aCx, aScripts, aError); } + void AddChildManager(MessageListenerManager* aManager); + void RemoveChildManager(MessageListenerManager* aManager); + private: - ChromeMessageBroadcaster(nsFrameMessageManager* aParentManager, + ChromeMessageBroadcaster(ChromeMessageBroadcaster* aParentManager, MessageManagerFlags aFlags); virtual ~ChromeMessageBroadcaster(); }; diff --git a/dom/base/ChromeMessageSender.cpp b/dom/base/ChromeMessageSender.cpp index cb617913fcd7..6505015e97b8 100644 --- a/dom/base/ChromeMessageSender.cpp +++ b/dom/base/ChromeMessageSender.cpp @@ -11,7 +11,7 @@ namespace mozilla { namespace dom { ChromeMessageSender::ChromeMessageSender(ipc::MessageManagerCallback* aCallback, - nsFrameMessageManager* aParentManager, + ChromeMessageBroadcaster* aParentManager, MessageManagerFlags aFlags) : MessageSender(aCallback, aParentManager, aFlags | MessageManagerFlags::MM_CHROME) { diff --git a/dom/base/ChromeMessageSender.h b/dom/base/ChromeMessageSender.h index aa9793346747..25f85e0b2ecd 100644 --- a/dom/base/ChromeMessageSender.h +++ b/dom/base/ChromeMessageSender.h @@ -12,11 +12,13 @@ namespace mozilla { namespace dom { +class ChromeMessageBroadcaster; + class ChromeMessageSender final : public MessageSender { public: ChromeMessageSender(ipc::MessageManagerCallback* aCallback, - nsFrameMessageManager* aParentManager, + ChromeMessageBroadcaster* aParentManager, MessageManagerFlags aFlags=MessageManagerFlags::MM_NONE); virtual JSObject* WrapObject(JSContext* aCx, diff --git a/dom/base/MessageListenerManager.cpp b/dom/base/MessageListenerManager.cpp index 413afb00969c..3ddf444da36a 100644 --- a/dom/base/MessageListenerManager.cpp +++ b/dom/base/MessageListenerManager.cpp @@ -10,7 +10,7 @@ namespace mozilla { namespace dom { MessageListenerManager::MessageListenerManager(ipc::MessageManagerCallback* aCallback, - nsFrameMessageManager* aParentManager, + ChromeMessageBroadcaster* aParentManager, ipc::MessageManagerFlags aFlags) : nsFrameMessageManager(aCallback, aFlags), mParentManager(aParentManager) diff --git a/dom/base/MessageListenerManager.h b/dom/base/MessageListenerManager.h index fc632c5a11aa..8a6442e16649 100644 --- a/dom/base/MessageListenerManager.h +++ b/dom/base/MessageListenerManager.h @@ -22,12 +22,12 @@ public: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MessageListenerManager, nsFrameMessageManager) - nsISupports* GetParentObject() + ChromeMessageBroadcaster* GetParentObject() { - return ToSupports(mParentManager.get()); + return mParentManager; } - virtual nsFrameMessageManager* GetParentManager() override + virtual ChromeMessageBroadcaster* GetParentManager() override { return mParentManager; } @@ -40,11 +40,11 @@ public: protected: MessageListenerManager(ipc::MessageManagerCallback* aCallback, - nsFrameMessageManager* aParentManager, + ChromeMessageBroadcaster* aParentManager, MessageManagerFlags aFlags); virtual ~MessageListenerManager(); - RefPtr mParentManager; + RefPtr mParentManager; }; } // namespace dom diff --git a/dom/base/MessageSender.h b/dom/base/MessageSender.h index 3ad1c7905e7c..96d7a74ecb3c 100644 --- a/dom/base/MessageSender.h +++ b/dom/base/MessageSender.h @@ -19,7 +19,7 @@ public: protected: MessageSender(ipc::MessageManagerCallback* aCallback, - nsFrameMessageManager* aParentManager, + ChromeMessageBroadcaster* aParentManager, MessageManagerFlags aFlags) : MessageListenerManager(aCallback, aParentManager, aFlags) {} diff --git a/dom/base/nsCCUncollectableMarker.cpp b/dom/base/nsCCUncollectableMarker.cpp index 7f0140988819..91fb989dbe88 100644 --- a/dom/base/nsCCUncollectableMarker.cpp +++ b/dom/base/nsCCUncollectableMarker.cpp @@ -86,21 +86,20 @@ nsCCUncollectableMarker::Init() } static void -MarkChildMessageManagers(nsIMessageBroadcaster* aMM) +MarkChildMessageManagers(ChromeMessageBroadcaster* aMM) { aMM->MarkForCC(); - uint32_t tabChildCount = 0; - aMM->GetChildCount(&tabChildCount); + uint32_t tabChildCount = aMM->ChildCount(); for (uint32_t j = 0; j < tabChildCount; ++j) { - nsCOMPtr childMM; - aMM->GetChildAt(j, getter_AddRefs(childMM)); + RefPtr childMM = aMM->GetChildAt(j); if (!childMM) { continue; } - nsCOMPtr strongNonLeafMM = do_QueryInterface(childMM); - nsIMessageBroadcaster* nonLeafMM = strongNonLeafMM; + RefPtr strongNonLeafMM = + ChromeMessageBroadcaster::From(childMM); + ChromeMessageBroadcaster* nonLeafMM = strongNonLeafMM; nsCOMPtr strongTabMM = do_QueryInterface(childMM); nsIMessageSender* tabMM = strongTabMM; @@ -150,27 +149,25 @@ MarkMessageManagers() if (!XRE_IsParentProcess()) { return; } - nsCOMPtr strongGlobalMM = - do_GetService("@mozilla.org/globalmessagemanager;1"); + RefPtr strongGlobalMM = + nsFrameMessageManager::GetGlobalMessageManager(); if (!strongGlobalMM) { return; } - nsIMessageBroadcaster* globalMM = strongGlobalMM; + ChromeMessageBroadcaster* globalMM = strongGlobalMM; strongGlobalMM = nullptr; MarkChildMessageManagers(globalMM); if (nsFrameMessageManager::sParentProcessManager) { nsFrameMessageManager::sParentProcessManager->MarkForCC(); - uint32_t childCount = 0; - nsFrameMessageManager::sParentProcessManager->GetChildCount(&childCount); + uint32_t childCount = nsFrameMessageManager::sParentProcessManager->ChildCount(); for (uint32_t i = 0; i < childCount; ++i) { - nsCOMPtr childMM; - nsFrameMessageManager::sParentProcessManager-> - GetChildAt(i, getter_AddRefs(childMM)); + RefPtr childMM = + nsFrameMessageManager::sParentProcessManager->GetChildAt(i); if (!childMM) { continue; } - nsIMessageListenerManager* child = childMM; + MessageListenerManager* child = childMM; childMM = nullptr; child->MarkForCC(); } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 7cb03fdf6d28..3a7e16166219 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7771,20 +7771,18 @@ nsContentUtils::GetHostOrIPv6WithBrackets(nsIURI* aURI, nsAString& aHost) } bool -nsContentUtils::CallOnAllRemoteChildren(nsIMessageBroadcaster* aManager, +nsContentUtils::CallOnAllRemoteChildren(ChromeMessageBroadcaster* aManager, CallOnRemoteChildFunction aCallback, void* aArg) { - uint32_t tabChildCount = 0; - aManager->GetChildCount(&tabChildCount); + uint32_t tabChildCount = aManager->ChildCount(); for (uint32_t j = 0; j < tabChildCount; ++j) { - nsCOMPtr childMM; - aManager->GetChildAt(j, getter_AddRefs(childMM)); + RefPtr childMM = aManager->GetChildAt(j); if (!childMM) { continue; } - nsCOMPtr nonLeafMM = do_QueryInterface(childMM); + RefPtr nonLeafMM = ChromeMessageBroadcaster::From(childMM); if (nonLeafMM) { if (CallOnAllRemoteChildren(nonLeafMM, aCallback, aArg)) { return true; @@ -7815,10 +7813,9 @@ nsContentUtils::CallOnAllRemoteChildren(nsPIDOMWindowOuter* aWindow, CallOnRemoteChildFunction aCallback, void* aArg) { - nsCOMPtr chromeWindow(do_QueryInterface(aWindow)); - if (chromeWindow) { - nsCOMPtr windowMM; - chromeWindow->GetMessageManager(getter_AddRefs(windowMM)); + nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(aWindow); + if (window->IsChromeWindow()) { + RefPtr windowMM = window->GetMessageManager(); if (windowMM) { CallOnAllRemoteChildren(windowMM, aCallback, aArg); } diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 668e59b63b40..227e2697ad06 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -82,7 +82,6 @@ class nsIInterfaceRequestor; class nsIIOService; class nsILoadInfo; class nsILoadGroup; -class nsIMessageBroadcaster; class nsNameSpaceManager; class nsIObserver; class nsIParser; @@ -129,6 +128,7 @@ class EventListenerManager; class HTMLEditor; namespace dom { +class ChromeMessageBroadcaster; struct CustomElementDefinition; class DocumentFragment; class Element; @@ -3343,7 +3343,7 @@ private: mozilla::dom::AutocompleteInfo& aInfo, bool aGrantAllValidValue = false); - static bool CallOnAllRemoteChildren(nsIMessageBroadcaster* aManager, + static bool CallOnAllRemoteChildren(mozilla::dom::ChromeMessageBroadcaster* aManager, CallOnRemoteChildFunction aCallback, void* aArg); diff --git a/dom/base/nsFocusManager.h b/dom/base/nsFocusManager.h index 767525368819..efebdfa7b132 100644 --- a/dom/base/nsFocusManager.h +++ b/dom/base/nsFocusManager.h @@ -24,7 +24,6 @@ class nsIContent; class nsIDocShellTreeItem; class nsPIDOMWindowOuter; -class nsIMessageBroadcaster; namespace mozilla { namespace dom { @@ -178,12 +177,6 @@ protected: */ void EnsureCurrentWidgetFocused(); - /** - * Iterate over the children of the message broadcaster and notify them - * of the activation change. - */ - void ActivateOrDeactivateChildren(nsIMessageBroadcaster* aManager, bool aActive); - /** * Activate or deactivate the window and send the activate/deactivate events. */ diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 2f700a205756..73e46509a8d6 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -2909,28 +2909,27 @@ nsFrameLoader::EnsureMessageManager() return NS_OK; } - nsCOMPtr chromeWindow = - do_QueryInterface(GetOwnerDoc()->GetWindow()); - nsCOMPtr parentManager; + RefPtr window = + nsGlobalWindowOuter::Cast(GetOwnerDoc()->GetWindow()); + RefPtr parentManager; - if (chromeWindow) { + if (window && window->IsChromeWindow()) { nsAutoString messagemanagergroup; if (mOwnerContent->IsXULElement() && mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::messagemanagergroup, messagemanagergroup)) { - chromeWindow->GetGroupMessageManager(messagemanagergroup, getter_AddRefs(parentManager)); + parentManager = window->GetGroupMessageManager(messagemanagergroup); } if (!parentManager) { - chromeWindow->GetMessageManager(getter_AddRefs(parentManager)); + parentManager = window->GetMessageManager(); } } else { - parentManager = do_GetService("@mozilla.org/globalmessagemanager;1"); + parentManager = nsFrameMessageManager::GetGlobalMessageManager(); } - mMessageManager = new ChromeMessageSender(nullptr, - static_cast(parentManager.get())); + mMessageManager = new ChromeMessageSender(nullptr, parentManager); if (!IsRemoteFrame()) { nsresult rv = MaybeCreateDocShell(); if (NS_FAILED(rv)) { diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index e1d7d734ed8c..7115eb70adbd 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -29,6 +29,7 @@ #include "nsIProtocolHandler.h" #include "nsIScriptSecurityManager.h" #include "xpcpublic.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/CycleCollectedJSContext.h" #include "mozilla/Preferences.h" #include "mozilla/ScriptPreloader.h" @@ -132,23 +133,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameMessageManager) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentFrameMessageManager) - /* nsFrameMessageManager implements nsIMessageSender and nsIMessageBroadcaster, - * both of which descend from nsIMessageListenerManager. QI'ing to - * nsIMessageListenerManager is therefore ambiguous and needs explicit casts - * depending on which child interface applies. */ - NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIMessageListenerManager, - (mIsBroadcaster ? - static_cast( - static_cast(this)) : - static_cast( - static_cast(this)))) + NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager) /* Message managers in child process implement nsIMessageSender. Message managers in the chrome process are either broadcasters (if they have subordinate/child message managers) or they're simple message senders. */ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMessageSender, !mChrome || !mIsBroadcaster) - NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMessageBroadcaster, mChrome && mIsBroadcaster) /* nsIContentFrameMessageManager is accessible only in TabChildGlobal. */ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIContentFrameMessageManager, @@ -750,46 +741,6 @@ nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName, } -// nsIMessageBroadcaster - -NS_IMETHODIMP -nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName, - JS::Handle aJSON, - JS::Handle aObjects, - JSContext* aCx, - uint8_t aArgc) -{ - return DispatchAsyncMessage(aMessageName, aJSON, aObjects, nullptr, - JS::UndefinedHandleValue, aCx, aArgc); -} - -NS_IMETHODIMP -nsFrameMessageManager::GetChildCount(uint32_t* aChildCount) -{ - *aChildCount = mChildManagers.Length(); - return NS_OK; -} - -NS_IMETHODIMP -nsFrameMessageManager::GetChildAt(uint32_t aIndex, - nsIMessageListenerManager** aMM) -{ - MessageListenerManager* mm = mChildManagers.SafeElementAt(aIndex); - if (mm) { - CallQueryInterface(mm, aMM); - } else { - *aMM = nullptr; - } - return NS_OK; -} - -NS_IMETHODIMP -nsFrameMessageManager::ReleaseCachedProcesses() -{ - ContentParent::ReleaseCachedProcesses(); - return NS_OK; -} - class MMListenerRemover { public: @@ -1044,23 +995,6 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget, return NS_OK; } -void -nsFrameMessageManager::AddChildManager(MessageListenerManager* aManager) -{ - mChildManagers.AppendElement(aManager); - - RefPtr kungfuDeathGrip = this; - RefPtr kungfuDeathGrip2 = aManager; - - LoadPendingScripts(this, aManager); -} - -void -nsFrameMessageManager::RemoveChildManager(MessageListenerManager* aManager) -{ - mChildManagers.RemoveElement(aManager); -} - void nsFrameMessageManager::LoadPendingScripts(nsFrameMessageManager* aManager, nsFrameMessageManager* aChildMM) @@ -1352,20 +1286,16 @@ ReportReferentCount(const char* aManagerType, #undef REPORT } +static StaticRefPtr sGlobalMessageManager; + NS_IMETHODIMP MessageManagerReporter::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) { - if (XRE_IsParentProcess()) { - nsCOMPtr globalmm = - do_GetService("@mozilla.org/globalmessagemanager;1"); - if (globalmm) { - RefPtr mm = - static_cast(globalmm.get()); - MessageManagerReferentCount count; - CountReferents(mm, &count); - ReportReferentCount("global-manager", count, aHandleReport, aData); - } + if (XRE_IsParentProcess() && sGlobalMessageManager) { + MessageManagerReferentCount count; + CountReferents(sGlobalMessageManager, &count); + ReportReferentCount("global-manager", count, aHandleReport, aData); } if (nsFrameMessageManager::sParentProcessManager) { @@ -1386,15 +1316,25 @@ MessageManagerReporter::CollectReports(nsIHandleReportCallback* aHandleReport, } // namespace dom } // namespace mozilla -nsresult -NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult) +already_AddRefed +nsFrameMessageManager::GetGlobalMessageManager() { - NS_ENSURE_TRUE(XRE_IsParentProcess(), - NS_ERROR_NOT_AVAILABLE); - RefPtr mm = - new ChromeMessageBroadcaster(MessageManagerFlags::MM_GLOBAL); - RegisterStrongMemoryReporter(new MessageManagerReporter()); - mm.forget(aResult); + RefPtr mm; + if (sGlobalMessageManager) { + mm = sGlobalMessageManager; + } else { + sGlobalMessageManager = mm = + new ChromeMessageBroadcaster(MessageManagerFlags::MM_GLOBAL); + ClearOnShutdown(&sGlobalMessageManager); + RegisterStrongMemoryReporter(new MessageManagerReporter()); + } + return mm.forget(); +} + +nsresult +NS_NewGlobalMessageManager(nsISupports** aResult) +{ + *aResult = nsFrameMessageManager::GetGlobalMessageManager().take(); return NS_OK; } @@ -1644,7 +1584,7 @@ nsMessageManagerScriptExecutor::MarkScopesForCC() NS_IMPL_ISUPPORTS(nsScriptCacheCleaner, nsIObserver) ChildProcessMessageManager* nsFrameMessageManager::sChildProcessManager = nullptr; -nsFrameMessageManager* nsFrameMessageManager::sParentProcessManager = nullptr; +ChromeMessageBroadcaster* nsFrameMessageManager::sParentProcessManager = nullptr; nsFrameMessageManager* nsFrameMessageManager::sSameProcessParentManager = nullptr; class nsAsyncMessageToSameProcessChild : public nsSameProcessAsyncMessageBase, @@ -1860,11 +1800,11 @@ public: // This creates the global parent process message manager. nsresult -NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult) +NS_NewParentProcessMessageManager(nsISupports** aResult) { NS_ASSERTION(!nsFrameMessageManager::sParentProcessManager, "Re-creating sParentProcessManager"); - RefPtr mm = + RefPtr mm = new ChromeMessageBroadcaster(MessageManagerFlags::MM_PROCESSMANAGER); nsFrameMessageManager::sParentProcessManager = mm; nsFrameMessageManager::NewProcessMessageManager(false); // Create same process message manager. @@ -1877,7 +1817,7 @@ ChromeMessageSender* nsFrameMessageManager::NewProcessMessageManager(bool aIsRemote) { if (!nsFrameMessageManager::sParentProcessManager) { - nsCOMPtr dummy = + nsCOMPtr dummy = do_GetService("@mozilla.org/parentprocessmessagemanager;1"); } diff --git a/dom/base/nsFrameMessageManager.h b/dom/base/nsFrameMessageManager.h index a76b2a2e7dd0..5d3507c89dd3 100644 --- a/dom/base/nsFrameMessageManager.h +++ b/dom/base/nsFrameMessageManager.h @@ -42,6 +42,7 @@ namespace dom { class nsIContentParent; class nsIContentChild; class ChildProcessMessageManager; +class ChromeMessageBroadcaster; class ChromeMessageSender; class ClonedMessageData; class MessageListener; @@ -172,8 +173,7 @@ private: JS::Rooted mObj; }; -class nsFrameMessageManager : public nsIContentFrameMessageManager, - public nsIMessageBroadcaster +class nsFrameMessageManager : public nsIContentFrameMessageManager { friend class mozilla::dom::MessageManagerReporter; typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData; @@ -252,7 +252,6 @@ public: NS_DECL_NSIMESSAGELISTENERMANAGER NS_DECL_NSIMESSAGESENDER - NS_DECL_NSIMESSAGEBROADCASTER NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER static mozilla::dom::ChromeMessageSender* @@ -264,8 +263,6 @@ public: mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal, nsTArray* aRetVal); - void AddChildManager(mozilla::dom::MessageListenerManager* aManager); - void RemoveChildManager(mozilla::dom::MessageListenerManager* aManager); void Disconnect(bool aRemoveFromParent = true); void Close(); @@ -291,8 +288,12 @@ public: nsIPrincipal* aPrincipal); bool IsGlobal() { return mGlobal; } bool IsBroadcaster() { return mIsBroadcaster; } + bool IsChrome() { return mChrome; } - static nsFrameMessageManager* GetParentProcessManager() + // GetGlobalMessageManager creates the global message manager if it hasn't been yet. + static already_AddRefed + GetGlobalMessageManager(); + static mozilla::dom::ChromeMessageBroadcaster* GetParentProcessManager() { return sParentProcessManager; } @@ -312,7 +313,7 @@ public: protected: friend class MMListenerRemover; - virtual nsFrameMessageManager* GetParentManager() + virtual mozilla::dom::ChromeMessageBroadcaster* GetParentManager() { return nullptr; } @@ -389,7 +390,7 @@ protected: void LoadPendingScripts(nsFrameMessageManager* aManager, nsFrameMessageManager* aChildMM); public: - static nsFrameMessageManager* sParentProcessManager; + static mozilla::dom::ChromeMessageBroadcaster* sParentProcessManager; static nsFrameMessageManager* sSameProcessParentManager; static nsTArray >* sPendingSameProcessAsyncMessages; private: diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 609bbd561b01..d388c9266746 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -7768,49 +7768,27 @@ nsGlobalWindowInner::NotifyDefaultButtonLoaded(Element& aDefaultButton, #endif } -NS_IMETHODIMP -nsGlobalWindowInner::GetMessageManager(nsIMessageBroadcaster** aManager) -{ - ErrorResult rv; - NS_IF_ADDREF(*aManager = GetMessageManager(rv)); - return rv.StealNSResult(); -} - ChromeMessageBroadcaster* -nsGlobalWindowInner::GetMessageManager(ErrorResult& aError) +nsGlobalWindowInner::MessageManager() { MOZ_ASSERT(IsChromeWindow()); if (!mChromeFields.mMessageManager) { - nsCOMPtr globalMM = - do_GetService("@mozilla.org/globalmessagemanager;1"); - mChromeFields.mMessageManager = - new ChromeMessageBroadcaster(static_cast(globalMM.get())); + RefPtr globalMM = + nsFrameMessageManager::GetGlobalMessageManager(); + mChromeFields.mMessageManager = new ChromeMessageBroadcaster(globalMM); } return mChromeFields.mMessageManager; } -NS_IMETHODIMP -nsGlobalWindowInner::GetGroupMessageManager(const nsAString& aGroup, - nsIMessageBroadcaster** aManager) -{ - MOZ_RELEASE_ASSERT(IsChromeWindow()); - ErrorResult rv; - NS_IF_ADDREF(*aManager = GetGroupMessageManager(aGroup, rv)); - return rv.StealNSResult(); -} - ChromeMessageBroadcaster* -nsGlobalWindowInner::GetGroupMessageManager(const nsAString& aGroup, - ErrorResult& aError) +nsGlobalWindowInner::GetGroupMessageManager(const nsAString& aGroup) { MOZ_ASSERT(IsChromeWindow()); RefPtr messageManager = mChromeFields.mGroupMessageManagers.LookupForAdd(aGroup).OrInsert( - [this, &aError] () { - nsFrameMessageManager* parent = GetMessageManager(aError); - - return new ChromeMessageBroadcaster(parent); + [this] () { + return new ChromeMessageBroadcaster(MessageManager()); }); return messageManager; } diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index 59775241be6c..2545bf1ae6db 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -947,11 +947,8 @@ public: void Restore(); void NotifyDefaultButtonLoaded(mozilla::dom::Element& aDefaultButton, mozilla::ErrorResult& aError); - mozilla::dom::ChromeMessageBroadcaster* - GetMessageManager(mozilla::ErrorResult& aError); - mozilla::dom::ChromeMessageBroadcaster* - GetGroupMessageManager(const nsAString& aGroup, - mozilla::ErrorResult& aError); + mozilla::dom::ChromeMessageBroadcaster* MessageManager(); + mozilla::dom::ChromeMessageBroadcaster* GetGroupMessageManager(const nsAString& aGroup); void BeginWindowMove(mozilla::dom::Event& aMouseDownEvent, mozilla::dom::Element* aPanel, mozilla::ErrorResult& aError); diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index c0699223e236..5b8e3e3c3602 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -7534,18 +7534,24 @@ nsGlobalWindowOuter::SetBrowserDOMWindowOuter(nsIBrowserDOMWindow* aBrowserWindo mChromeFields.mBrowserDOMWindow = aBrowserWindow; } -NS_IMETHODIMP -nsGlobalWindowOuter::GetMessageManager(nsIMessageBroadcaster** aManager) +ChromeMessageBroadcaster* +nsGlobalWindowOuter::GetMessageManager() { - FORWARD_TO_INNER(GetMessageManager, (aManager), NS_ERROR_UNEXPECTED); + if (!mInnerWindow) { + NS_WARNING("No inner window available!"); + return nullptr; + } + return GetCurrentInnerWindowInternal()->MessageManager(); } -NS_IMETHODIMP -nsGlobalWindowOuter::GetGroupMessageManager(const nsAString& aGroup, - nsIMessageBroadcaster** aManager) +ChromeMessageBroadcaster* +nsGlobalWindowOuter::GetGroupMessageManager(const nsAString& aGroup) { - MOZ_RELEASE_ASSERT(IsChromeWindow()); - FORWARD_TO_INNER(GetGroupMessageManager, (aGroup, aManager), NS_ERROR_UNEXPECTED); + if (!mInnerWindow) { + NS_WARNING("No inner window available!"); + return nullptr; + } + return GetCurrentInnerWindowInternal()->GetGroupMessageManager(aGroup); } void diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index d1b19d804230..ca258e1ff7b8 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -265,6 +265,9 @@ public: // nsIDOMChromeWindow (only implemented on chrome windows) NS_DECL_NSIDOMCHROMEWINDOW + mozilla::dom::ChromeMessageBroadcaster* GetMessageManager(); + mozilla::dom::ChromeMessageBroadcaster* GetGroupMessageManager(const nsAString& aGroup); + nsresult OpenJS(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, nsPIDOMWindowOuter **_retval); diff --git a/dom/base/nsIMessageManager.idl b/dom/base/nsIMessageManager.idl index c69a506371d0..29ea88fb8564 100644 --- a/dom/base/nsIMessageManager.idl +++ b/dom/base/nsIMessageManager.idl @@ -306,46 +306,6 @@ interface nsIMessageSender : nsIMessageListenerManager readonly attribute AString remoteType; }; -/** - * Message "broadcasters" don't have a single "other side" that they - * send messages to, but rather a set of subordinate message managers. - * For example, broadcasting a message through a window message - * manager will broadcast the message to all frame message managers - * within its window. - */ -[uuid(4d7d62ad-4725-4f39-86cf-8fb22bf9c1d8)] -interface nsIMessageBroadcaster : nsIMessageListenerManager -{ - /** - * Like |sendAsyncMessage()|, but also broadcasts this message to - * all "child" message managers of this message manager. See long - * comment above for details. - * - * WARNING: broadcasting messages can be very expensive and leak - * sensitive data. Use with extreme caution. - */ - [implicit_jscontext, optional_argc] - void broadcastAsyncMessage([optional] in AString messageName, - [optional] in jsval obj, - [optional] in jsval objects); - - /** - * Number of subordinate message managers. - */ - readonly attribute unsigned long childCount; - - /** - * Return a single subordinate message manager. - */ - nsIMessageListenerManager getChildAt(in unsigned long aIndex); - - /** - * Some processes are kept alive after their last tab/window are closed for testing - * (see dom.ipc.keepProcessesAlive). This function releases those. - */ - void releaseCachedProcesses(); -}; - [uuid(694e367c-aa25-4446-8499-2c527c4bd838)] interface nsIContentFrameMessageManager : nsIMessageSender { diff --git a/dom/chrome-webidl/MessageManager.webidl b/dom/chrome-webidl/MessageManager.webidl index f0a5ce1400b9..9477f77c55e5 100644 --- a/dom/chrome-webidl/MessageManager.webidl +++ b/dom/chrome-webidl/MessageManager.webidl @@ -333,6 +333,12 @@ interface ContentProcessMessageManager // WebIDL spec. ContentProcessMessageManager implements MessageManagerGlobal; +/** + * Message "broadcasters" don't have a single "other side" that they send messages to, but + * rather a set of subordinate message managers. For example, broadcasting a message + * through a window message manager will broadcast the message to all frame message + * managers within its window. + */ [ChromeOnly] interface ChromeMessageBroadcaster : MessageListenerManager { diff --git a/dom/interfaces/base/nsIDOMChromeWindow.idl b/dom/interfaces/base/nsIDOMChromeWindow.idl index 2fd15fa3174f..4df7110f3e1e 100644 --- a/dom/interfaces/base/nsIDOMChromeWindow.idl +++ b/dom/interfaces/base/nsIDOMChromeWindow.idl @@ -8,7 +8,6 @@ interface nsIBrowserDOMWindow; interface nsIDOMElement; interface nsIDOMEvent; -interface nsIMessageBroadcaster; interface mozIDOMWindowProxy; // Scriptable only so Components.interfaces.nsIDOMChromeWindow works. @@ -22,14 +21,4 @@ interface nsIDOMChromeWindow : nsISupports */ [noscript] readonly attribute nsIBrowserDOMWindow browserDOMWindow; - - [noscript] - readonly attribute nsIMessageBroadcaster messageManager; - - /** - * Returns the message manager identified by the given group name that - * manages all frame loaders belonging to that group. - */ - [noscript] - nsIMessageBroadcaster getGroupMessageManager(in AString group); }; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 70255bdfd73d..cbcdcf75629e 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -157,6 +157,7 @@ #include "nsThread.h" #include "nsWindowWatcher.h" #include "nsIXULRuntime.h" +#include "mozilla/dom/ChromeMessageBroadcaster.h" #include "mozilla/dom/nsMixedContentBlocker.h" #include "nsMemoryInfoDumper.h" #include "nsMemoryReporterManager.h" @@ -2270,7 +2271,7 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority) if (ssm) { ssm->CloneDomainPolicy(&xpcomInit.domainPolicy()); - if (nsFrameMessageManager* mm = nsFrameMessageManager::sParentProcessManager) { + if (ChromeMessageBroadcaster* mm = nsFrameMessageManager::sParentProcessManager) { AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) { MOZ_CRASH(); diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index c5bc1b8bfa93..28c2690789b1 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -430,14 +430,14 @@ partial interface Window { [Throws, Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"] void notifyDefaultButtonLoaded(Element defaultButton); - [Throws, Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"] + [Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"] readonly attribute ChromeMessageBroadcaster messageManager; /** * Returns the message manager identified by the given group name that * manages all frame loaders belonging to that group. */ - [Throws, Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"] + [Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"] ChromeMessageBroadcaster getGroupMessageManager(DOMString aGroup); /** diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 456956b22020..aff0efecda1c 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -16,6 +16,7 @@ #include "nsDataDocumentContentPolicy.h" #include "nsNoDataProtocolContentPolicy.h" #include "nsDOMCID.h" +#include "nsFrameMessageManager.h" #include "nsHTMLContentSerializer.h" #include "nsHTMLParts.h" #include "nsIComponentManager.h" @@ -318,8 +319,8 @@ nsresult NS_NewTextEncoder(nsIDocumentEncoder** aResult); nsresult NS_NewContentPolicy(nsIContentPolicy** aResult); nsresult NS_NewEventListenerService(nsIEventListenerService** aResult); -nsresult NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult); -nsresult NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult); +nsresult NS_NewGlobalMessageManager(nsISupports** aResult); +nsresult NS_NewParentProcessMessageManager(nsISupports** aResult); nsresult NS_NewChildProcessMessageManager(nsIMessageSender** aResult); nsresult NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult); @@ -396,8 +397,8 @@ MAKE_CTOR(CreateXULDocument, nsIDocument, NS_NewXUL #endif MAKE_CTOR(CreateContentDLF, nsIDocumentLoaderFactory, NS_NewContentDocumentLoaderFactory) MAKE_CTOR(CreateEventListenerService, nsIEventListenerService, NS_NewEventListenerService) -MAKE_CTOR(CreateGlobalMessageManager, nsIMessageBroadcaster, NS_NewGlobalMessageManager) -MAKE_CTOR(CreateParentMessageManager, nsIMessageBroadcaster, NS_NewParentProcessMessageManager) +MAKE_CTOR(CreateGlobalMessageManager, nsISupports, NS_NewGlobalMessageManager) +MAKE_CTOR(CreateParentMessageManager, nsISupports, NS_NewParentProcessMessageManager) MAKE_CTOR(CreateChildMessageManager, nsIMessageSender, NS_NewChildProcessMessageManager) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDataDocumentContentPolicy) NS_GENERIC_FACTORY_CONSTRUCTOR(nsNoDataProtocolContentPolicy)