Bug 1581925 - Part 1: Capture parent process JSWindowActor events at InProcessBrowserChildMessageManager, r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D46864

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2019-10-07 19:35:06 +00:00
Родитель ecf163cc61
Коммит ed104ffa03
6 изменённых файлов: 58 добавлений и 38 удалений

Просмотреть файл

@ -23,11 +23,30 @@
#include "mozilla/dom/SameProcessMessageQueue.h"
#include "mozilla/dom/ScriptLoader.h"
#include "mozilla/dom/WindowProxyHolder.h"
#include "mozilla/dom/JSWindowActorService.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::ipc;
/* static */
already_AddRefed<InProcessBrowserChildMessageManager>
InProcessBrowserChildMessageManager::Create(nsDocShell* aShell,
nsIContent* aOwner,
nsFrameMessageManager* aChrome) {
RefPtr<InProcessBrowserChildMessageManager> mm =
new InProcessBrowserChildMessageManager(aShell, aOwner, aChrome);
NS_ENSURE_TRUE(mm->Init(), nullptr);
if (XRE_IsParentProcess()) {
RefPtr<JSWindowActorService> wasvc = JSWindowActorService::GetSingleton();
wasvc->RegisterChromeEventTarget(mm);
}
return mm.forget();
}
bool InProcessBrowserChildMessageManager::DoSendBlockingMessage(
JSContext* aCx, const nsAString& aMessage, StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows, nsIPrincipal* aPrincipal,
@ -101,6 +120,10 @@ InProcessBrowserChildMessageManager::InProcessBrowserChildMessageManager(
}
InProcessBrowserChildMessageManager::~InProcessBrowserChildMessageManager() {
if (XRE_IsParentProcess()) {
JSWindowActorService::UnregisterChromeEventTarget(this);
}
mAnonymousGlobalScopes.Clear();
mozilla::DropJSObjects(this);
}

Просмотреть файл

@ -47,14 +47,7 @@ class InProcessBrowserChildMessageManager final
public:
static already_AddRefed<InProcessBrowserChildMessageManager> Create(
nsDocShell* aShell, nsIContent* aOwner, nsFrameMessageManager* aChrome) {
RefPtr<InProcessBrowserChildMessageManager> mm =
new InProcessBrowserChildMessageManager(aShell, aOwner, aChrome);
NS_ENSURE_TRUE(mm->Init(), nullptr);
return mm.forget();
}
nsDocShell* aShell, nsIContent* aOwner, nsFrameMessageManager* aChrome);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(

Просмотреть файл

@ -44,7 +44,9 @@ nsWindowRoot::~nsWindowRoot() {
mListenerManager->Disconnect();
}
JSWindowActorService::UnregisterWindowRoot(this);
if (XRE_IsContentProcess()) {
JSWindowActorService::UnregisterChromeEventTarget(this);
}
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsWindowRoot, mWindow, mListenerManager,
@ -320,9 +322,9 @@ void nsWindowRoot::EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg) {
already_AddRefed<EventTarget> NS_NewWindowRoot(nsPIDOMWindowOuter* aWindow) {
nsCOMPtr<EventTarget> result = new nsWindowRoot(aWindow);
RefPtr<JSWindowActorService> wasvc = JSWindowActorService::GetSingleton();
if (wasvc) {
wasvc->RegisterWindowRoot(result);
if (XRE_IsContentProcess()) {
RefPtr<JSWindowActorService> wasvc = JSWindowActorService::GetSingleton();
wasvc->RegisterChromeEventTarget(result);
}
return result.forget();

Просмотреть файл

@ -156,6 +156,8 @@ dictionary WindowActorChildOptions : WindowActorSidedOptions {
* Events which this actor wants to be listening to. When these events fire,
* it will trigger actor creation, and then forward the event to the actor.
*
* NOTE: Listeners are not attached for windows loaded in chrome docshells.
*
* NOTE: `once` option is not support due to we register listeners in a shared
* location.
*/

Просмотреть файл

@ -243,8 +243,8 @@ NS_IMETHODIMP JSWindowActorProtocol::Observe(nsISupports* aSubject,
return NS_OK;
}
void JSWindowActorProtocol::RegisterListenersFor(EventTarget* aRoot) {
EventListenerManager* elm = aRoot->GetOrCreateListenerManager();
void JSWindowActorProtocol::RegisterListenersFor(EventTarget* aTarget) {
EventListenerManager* elm = aTarget->GetOrCreateListenerManager();
for (auto& event : mChild.mEvents) {
elm->AddEventListenerByType(EventListenerHolder(this), event.mName,
@ -252,8 +252,8 @@ void JSWindowActorProtocol::RegisterListenersFor(EventTarget* aRoot) {
}
}
void JSWindowActorProtocol::UnregisterListenersFor(EventTarget* aRoot) {
EventListenerManager* elm = aRoot->GetOrCreateListenerManager();
void JSWindowActorProtocol::UnregisterListenersFor(EventTarget* aTarget) {
EventListenerManager* elm = aTarget->GetOrCreateListenerManager();
for (auto& event : mChild.mEvents) {
elm->RemoveEventListenerByType(EventListenerHolder(this), event.mName,
@ -388,9 +388,9 @@ void JSWindowActorService::RegisterWindowActor(
Unused << cp->SendInitJSWindowActorInfos(ipcInfos);
}
// Register event listeners for any existing window roots.
for (EventTarget* root : mRoots) {
proto->RegisterListenersFor(root);
// Register event listeners for any existing chrome targets.
for (EventTarget* target : mChromeEventTargets) {
proto->RegisterListenersFor(target);
}
// Add observers to the protocol.
@ -410,9 +410,9 @@ void JSWindowActorService::UnregisterWindowActor(const nsAString& aName) {
}
}
// Remove listeners for this actor from each of our window roots.
for (EventTarget* root : mRoots) {
proto->UnregisterListenersFor(root);
// Remove listeners for this actor from each of our chrome targets.
for (EventTarget* target : mChromeEventTargets) {
proto->UnregisterListenersFor(target);
}
// Remove observers for this actor from observer serivce.
@ -431,9 +431,9 @@ void JSWindowActorService::LoadJSWindowActorInfos(
JSWindowActorProtocol::FromIPC(aInfos[i]);
mDescriptors.Put(aInfos[i].name(), proto);
// Register listeners for each window root.
for (EventTarget* root : mRoots) {
proto->RegisterListenersFor(root);
// Register listeners for each chrome target.
for (EventTarget* target : mChromeEventTargets) {
proto->RegisterListenersFor(target);
}
// Add observers for each actor.
@ -451,21 +451,21 @@ void JSWindowActorService::GetJSWindowActorInfos(
}
}
void JSWindowActorService::RegisterWindowRoot(EventTarget* aRoot) {
MOZ_ASSERT(!mRoots.Contains(aRoot));
mRoots.AppendElement(aRoot);
void JSWindowActorService::RegisterChromeEventTarget(EventTarget* aTarget) {
MOZ_ASSERT(!mChromeEventTargets.Contains(aTarget));
mChromeEventTargets.AppendElement(aTarget);
// Register event listeners on the newly added Window Root.
for (auto iter = mDescriptors.Iter(); !iter.Done(); iter.Next()) {
iter.Data()->RegisterListenersFor(aRoot);
iter.Data()->RegisterListenersFor(aTarget);
}
}
/* static */
void JSWindowActorService::UnregisterWindowRoot(EventTarget* aRoot) {
void JSWindowActorService::UnregisterChromeEventTarget(EventTarget* aTarget) {
if (gJSWindowActorService) {
// NOTE: No need to unregister listeners here, as the root is going away.
gJSWindowActorService->mRoots.RemoveElement(aRoot);
// NOTE: No need to unregister listeners here, as the target is going away.
gJSWindowActorService->mChromeEventTargets.RemoveElement(aTarget);
}
}

Просмотреть файл

@ -70,8 +70,8 @@ class JSWindowActorProtocol final : public nsIObserver,
const ParentSide& Parent() const { return mParent; }
const ChildSide& Child() const { return mChild; }
void RegisterListenersFor(EventTarget* aRoot);
void UnregisterListenersFor(EventTarget* aRoot);
void RegisterListenersFor(EventTarget* aTarget);
void UnregisterListenersFor(EventTarget* aTarget);
void AddObservers();
void RemoveObservers();
bool Matches(BrowsingContext* aBrowsingContext, nsIURI* aURI,
@ -114,11 +114,11 @@ class JSWindowActorService final {
// from mDescriptors to JSWindowActorInfos.
void GetJSWindowActorInfos(nsTArray<JSWindowActorInfo>& aInfos);
// Register or unregister a WindowRoot object from this JSWindowActorService.
void RegisterWindowRoot(EventTarget* aRoot);
// Register or unregister a chrome event target.
void RegisterChromeEventTarget(EventTarget* aTarget);
// NOTE: This method is static, as it may be called during shutdown.
static void UnregisterWindowRoot(EventTarget* aRoot);
static void UnregisterChromeEventTarget(EventTarget* aTarget);
already_AddRefed<JSWindowActorProtocol> GetProtocol(const nsAString& aName);
@ -126,7 +126,7 @@ class JSWindowActorService final {
JSWindowActorService();
~JSWindowActorService();
nsTArray<EventTarget*> mRoots;
nsTArray<EventTarget*> mChromeEventTargets;
nsRefPtrHashtable<nsStringHashKey, JSWindowActorProtocol> mDescriptors;
};