Bug 1500944 - Part 2: Expose WindowGlobal actors to Chrome JS, r=farre

This serves 2 purposes:
1. Provides an object corresponding to an inner window which Chrome JS can hold onto.
2. Provides the object to JS which Chrome JS per-window actors will be attached to.
3. Provides useful information to Chrome JS in the parent process.

Differential Revision: https://phabricator.services.mozilla.com/D9394
This commit is contained in:
Nika Layzell 2018-10-19 19:02:56 -04:00
parent 8407efd877
commit c3a800be72
10 changed files with 119 additions and 13 deletions

View File

@ -124,8 +124,8 @@ public:
nsTArray<RefPtr<BrowsingContext>>& aBrowsingContexts);
nsISupports* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(BrowsingContext)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContext)

View File

@ -63,6 +63,15 @@ ChromeBrowsingContext::Cast(const BrowsingContext* aContext)
return static_cast<const ChromeBrowsingContext*>(aContext);
}
void
ChromeBrowsingContext::GetWindowGlobals(nsTArray<RefPtr<WindowGlobalParent>>& aWindows)
{
aWindows.SetCapacity(mWindowGlobals.Count());
for (auto iter = mWindowGlobals.Iter(); !iter.Done(); iter.Next()) {
aWindows.AppendElement(iter.Get()->GetKey());
}
}
void
ChromeBrowsingContext::RegisterWindowGlobal(WindowGlobalParent* aGlobal)
{
@ -77,6 +86,13 @@ ChromeBrowsingContext::UnregisterWindowGlobal(WindowGlobalParent* aGlobal)
mWindowGlobals.RemoveEntry(aGlobal);
}
JSObject*
ChromeBrowsingContext::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return ChromeBrowsingContext_Binding::Wrap(aCx, this, aGivenProto);
}
void
ChromeBrowsingContext::Traverse(nsCycleCollectionTraversalCallback& cb)
{

View File

@ -38,10 +38,15 @@ public:
return mProcessId == aProcessId;
}
void GetWindowGlobals(nsTArray<RefPtr<WindowGlobalParent>>& aWindows);
// Called by WindowGlobalParent to register and unregister window globals.
void RegisterWindowGlobal(WindowGlobalParent* aGlobal);
void UnregisterWindowGlobal(WindowGlobalParent* aGlobal);
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
protected:
void Traverse(nsCycleCollectionTraversalCallback& cb);
void Unlink();

View File

@ -17,3 +17,8 @@ interface BrowsingContext {
readonly attribute BrowsingContext? opener;
};
[Exposed=Window, ChromeOnly]
interface ChromeBrowsingContext : BrowsingContext {
sequence<WindowGlobalParent> getWindowGlobals();
};

View File

@ -0,0 +1,33 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
interface Principal;
interface URI;
interface nsIDocShell;
[Exposed=Window, ChromeOnly]
interface WindowGlobalParent {
readonly attribute boolean isClosed;
readonly attribute boolean isInProcess;
readonly attribute ChromeBrowsingContext browsingContext;
// XXX(nika): We would want to expose this, but |FrameLoader| isn't exposed on System.
// readonly attribute FrameLoader? rootFrameLoader; // Embedded (browser) only
readonly attribute WindowGlobalChild? childActor; // in-process only
// Information about the currently loaded document.
readonly attribute Principal documentPrincipal;
readonly attribute URI? documentURI;
};
[Exposed=Window, ChromeOnly]
interface WindowGlobalChild {
readonly attribute boolean isClosed;
readonly attribute boolean isInProcess;
readonly attribute BrowsingContext browsingContext;
readonly attribute WindowGlobalParent? parentActor; // in-process only
};

View File

@ -54,6 +54,7 @@ WEBIDL_FILES = [
'TelemetryStopwatch.webidl',
'WebExtensionContentScript.webidl',
'WebExtensionPolicy.webidl',
'WindowGlobalActors.webidl',
'XULFrameElement.webidl',
'XULMenuElement.webidl',
'XULScrollElement.webidl',

View File

@ -7,6 +7,7 @@
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/ipc/InProcessChild.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/WindowGlobalActorsBinding.h"
namespace mozilla {
namespace dom {
@ -54,7 +55,7 @@ WindowGlobalChild::Create(nsGlobalWindowInner* aWindow)
}
already_AddRefed<WindowGlobalParent>
WindowGlobalChild::GetOtherSide()
WindowGlobalChild::GetParentActor()
{
if (mIPCClosed) {
return nullptr;
@ -73,7 +74,23 @@ WindowGlobalChild::~WindowGlobalChild()
{
}
NS_IMPL_CYCLE_COLLECTION(WindowGlobalChild, mWindowGlobal, mBrowsingContext)
JSObject*
WindowGlobalChild::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return WindowGlobalChild_Binding::Wrap(aCx, this, aGivenProto);
}
nsISupports*
WindowGlobalChild::GetParentObject()
{
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WindowGlobalChild,
mWindowGlobal,
mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WindowGlobalChild, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WindowGlobalChild, Release)

View File

@ -9,6 +9,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/dom/PWindowGlobalChild.h"
#include "nsWrapperCache.h"
class nsGlobalWindowInner;
class nsDocShell;
@ -23,11 +24,12 @@ class WindowGlobalParent;
* Actor for a single nsGlobalWindowInner. This actor is used to communicate
* information to the parent process asynchronously.
*/
class WindowGlobalChild : public PWindowGlobalChild
class WindowGlobalChild : public nsWrapperCache
, public PWindowGlobalChild
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WindowGlobalChild)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WindowGlobalChild)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WindowGlobalChild)
dom::BrowsingContext* BrowsingContext() { return mBrowsingContext; }
nsGlobalWindowInner* WindowGlobal() { return mWindowGlobal; }
@ -41,12 +43,16 @@ public:
// Get the other side of this actor if it is an in-process actor. Returns
// |nullptr| if the actor has been torn down, or is not in-process.
already_AddRefed<WindowGlobalParent> GetOtherSide();
already_AddRefed<WindowGlobalParent> GetParentActor();
// Create and initialize the WindowGlobalChild object.
static already_AddRefed<WindowGlobalChild>
Create(nsGlobalWindowInner* aWindow);
nsISupports* GetParentObject();
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
protected:
virtual void ActorDestroy(ActorDestroyReason aWhy) override;

View File

@ -7,6 +7,7 @@
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/ipc/InProcessParent.h"
#include "mozilla/dom/ChromeBrowsingContext.h"
#include "mozilla/dom/WindowGlobalActorsBinding.h"
using namespace mozilla::ipc;
@ -59,7 +60,7 @@ WindowGlobalParent::Init(const WindowGlobalInit& aInit)
// In the in-process case, we can get it from the other side's
// WindowGlobalChild.
MOZ_ASSERT(Manager()->GetProtocolTypeId() == PInProcessMsgStart);
RefPtr<WindowGlobalChild> otherSide = GetOtherSide();
RefPtr<WindowGlobalChild> otherSide = GetChildActor();
if (otherSide && otherSide->WindowGlobal()) {
// Get the toplevel window from the other side.
RefPtr<nsDocShell> docShell = nsDocShell::Cast(otherSide->WindowGlobal()->GetDocShell());
@ -82,7 +83,7 @@ WindowGlobalParent::Init(const WindowGlobalInit& aInit)
}
already_AddRefed<WindowGlobalChild>
WindowGlobalParent::GetOtherSide()
WindowGlobalParent::GetChildActor()
{
if (mIPCClosed) {
return nullptr;
@ -111,7 +112,23 @@ WindowGlobalParent::~WindowGlobalParent()
{
}
NS_IMPL_CYCLE_COLLECTION(WindowGlobalParent, mFrameLoader, mBrowsingContext)
JSObject*
WindowGlobalParent::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return WindowGlobalParent_Binding::Wrap(aCx, this, aGivenProto);
}
nsISupports*
WindowGlobalParent::GetParentObject()
{
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WindowGlobalParent,
mFrameLoader,
mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WindowGlobalParent, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WindowGlobalParent, Release)

View File

@ -9,6 +9,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/dom/PWindowGlobalParent.h"
#include "nsWrapperCache.h"
class nsIPrincipal;
class nsIURI;
@ -23,11 +24,12 @@ class WindowGlobalChild;
/**
* A handle in the parent process to a specific nsGlobalWindowInner object.
*/
class WindowGlobalParent final : public PWindowGlobalParent
class WindowGlobalParent final : public nsWrapperCache
, public PWindowGlobalParent
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WindowGlobalParent)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WindowGlobalParent)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WindowGlobalParent)
// Has this actor been shut down
bool IsClosed() { return mIPCClosed; }
@ -38,7 +40,7 @@ public:
// Get the other side of this actor if it is an in-process actor. Returns
// |nullptr| if the actor has been torn down, or is not in-process.
already_AddRefed<WindowGlobalChild> GetOtherSide();
already_AddRefed<WindowGlobalChild> GetChildActor();
// The principal of this WindowGlobal. This value will not change over the
// lifetime of the WindowGlobal object, even to reflect changes in
@ -65,6 +67,10 @@ public:
// be called after setting the Manager actor.
void Init(const WindowGlobalInit& aInit);
nsISupports* GetParentObject();
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
protected:
// IPC messages
mozilla::ipc::IPCResult RecvUpdateDocumentURI(nsIURI* aURI) override;