Skip to content

Commit

Permalink
Bug 1487249 - Part 3: Add the WindowGlobal actor representing a singl…
Browse files Browse the repository at this point in the history
…e window global, r=bzbarsky

This actor can be used for communicating with individual frames, without
depending on walking the tree in the content process.

This is not yet complete. No tests have been written for it, the
WindowGlobalParent objects need to be exposed to chrome JS, and a form of JS
actors should be installed under them.

In addition, BrowsingContextChrome objects should be updated to allow access to
the current WindowGlobalParent in that context.

Differential Revision: https://phabricator.services.mozilla.com/D4623
  • Loading branch information
mystor committed Dec 5, 2018
1 parent 5070302 commit 79164ea
Show file tree
Hide file tree
Showing 22 changed files with 573 additions and 3 deletions.
9 changes: 9 additions & 0 deletions dom/base/nsDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@

#include "mozilla/DocLoadingTimelineMarker.h"

#include "mozilla/dom/WindowGlobalChild.h"

#include "nsISpeculativeConnect.h"

#include "mozilla/MediaManager.h"
Expand Down Expand Up @@ -2897,6 +2899,13 @@ void nsIDocument::SetDocumentURI(nsIURI* aURI) {
if (!equalBases) {
RefreshLinkHrefs();
}

// Tell our WindowGlobalParent that the document's URI has been changed.
nsPIDOMWindowInner* inner = GetInnerWindow();
WindowGlobalChild* wgc = inner ? inner->GetWindowGlobalChild() : nullptr;
if (wgc) {
Unused << wgc->SendUpdateDocumentURI(mDocumentURI);
}
}

static void GetFormattedTimeString(PRTime aTime,
Expand Down
16 changes: 16 additions & 0 deletions dom/base/nsGlobalWindowInner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@
#include "mozilla/dom/ClientSource.h"
#include "mozilla/dom/ClientState.h"

#include "mozilla/dom/WindowGlobalChild.h"

// Apple system headers seem to have a check() macro. <sigh>
#ifdef check
class nsIScriptTimeoutHandler;
Expand Down Expand Up @@ -1266,6 +1268,11 @@ void nsGlobalWindowInner::FreeInnerObjects(bool aForDocumentOpen) {
}
}

if (mWindowGlobalChild && !mWindowGlobalChild->IsClosed()) {
mWindowGlobalChild->Send__delete__(mWindowGlobalChild);
}
mWindowGlobalChild = nullptr;

mIntlUtils = nullptr;
}

Expand Down Expand Up @@ -1635,6 +1642,15 @@ void nsGlobalWindowInner::InnerSetNewDocument(JSContext* aCx,
// out of sync.
ClearDocumentDependentSlots(aCx);

// FIXME: Currently, devtools can crete a fallback webextension window global
// in the content process which does not have a corresponding TabChild actor.
// This means we have no actor to be our parent. (Bug 1498293)
MOZ_DIAGNOSTIC_ASSERT(!mWindowGlobalChild,
"Shouldn't have created WindowGlobalChild yet!");
if (XRE_IsParentProcess() || mTabChild) {
mWindowGlobalChild = WindowGlobalChild::Create(this);
}

#ifdef DEBUG
mLastOpenedURI = aDocument->GetDocumentURI();
#endif
Expand Down
11 changes: 11 additions & 0 deletions dom/base/nsPIDOMWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class ServiceWorker;
class ServiceWorkerDescriptor;
class Timeout;
class TimeoutManager;
class WindowGlobalChild;
class CustomElementRegistry;
enum class CallerType : uint32_t;
} // namespace dom
Expand Down Expand Up @@ -378,6 +379,10 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
return mDoc;
}

mozilla::dom::WindowGlobalChild* GetWindowGlobalChild() {
return mWindowGlobalChild;
}

virtual PopupControlState GetPopupControlState() const = 0;

// Determine if the window is suspended or frozen. Outer windows
Expand Down Expand Up @@ -695,6 +700,12 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
// also set as permissions, but it could happen that we need to access them
// synchronously in this context, and for this, we need a copy here.
nsTArray<nsCString> mStorageAccessGranted;

// The WindowGlobalChild actor for this window.
//
// This will be non-null during the full lifetime of the window, initialized
// during SetNewDocument, and cleared during FreeInnerObjects.
RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild;
};

NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
Expand Down
9 changes: 6 additions & 3 deletions dom/ipc/ContentChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,9 +890,6 @@ nsresult ContentChild::ProvideWindowCommon(
TabContext newTabContext = aTabOpener ? *aTabOpener : TabContext();
RefPtr<TabChild> newChild =
new TabChild(this, tabId, tabGroup, newTabContext, aChromeFlags);
if (NS_FAILED(newChild->Init(aParent))) {
return NS_ERROR_ABORT;
}

if (aTabOpener) {
MOZ_ASSERT(ipcContext->type() == IPCTabContext::TPopupIPCTabContext);
Expand All @@ -908,6 +905,12 @@ nsresult ContentChild::ProvideWindowCommon(
RefPtr<TabChild>(newChild).forget().take(), tabId, TabId(0), *ipcContext,
aChromeFlags, GetID(), IsForBrowser());

// Now that |newChild| has had its IPC link established, call |Init| to set it
// up.
if (NS_FAILED(newChild->Init(aParent))) {
return NS_ERROR_ABORT;
}

nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
if (aParent) {
nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
Expand Down
8 changes: 8 additions & 0 deletions dom/ipc/DOMTypes.ipdlh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ using CSSSize from "Units.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using hal::ScreenOrientation from "mozilla/HalScreenConfiguration.h";
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
using refcounted class nsIPrincipal from "mozilla/dom/PermissionMessageUtils.h";
using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";


namespace mozilla {
Expand Down Expand Up @@ -183,5 +185,11 @@ struct PerformanceInfo
CategoryDispatch[] items;
};

struct WindowGlobalInit
{
nsIPrincipal principal;
BrowsingContextId browsingContextId;
};

} // namespace dom
} // namespace mozilla
9 changes: 9 additions & 0 deletions dom/ipc/PBrowser.ipdl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ include protocol PParentToChildStream;
include protocol PFileDescriptorSet;
include protocol PIPCBlobInputStream;
include protocol PPaymentRequest;
include protocol PWindowGlobal;

include DOMTypes;
include IPCBlob;
Expand Down Expand Up @@ -86,6 +87,7 @@ using class mozilla::NativeEventData from "ipc/nsGUIEventIPC.h";
using mozilla::FontRange from "ipc/nsGUIEventIPC.h";
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";

namespace mozilla {
namespace dom {
Expand Down Expand Up @@ -118,6 +120,7 @@ nested(upto inside_cpow) sync protocol PBrowser
manages PIndexedDBPermissionRequest;
manages PPluginWidget;
manages PPaymentRequest;
manages PWindowGlobal;

both:
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
Expand All @@ -144,6 +147,12 @@ parent:

async PPaymentRequest();

/**
* Construct a new WindowGlobal actor for a window global in the given
* BrowsingContext and with the given principal.
*/
async PWindowGlobal(WindowGlobalInit init);

/**
* Sends an NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW to be adopted by the
* widget's shareable window on the chrome side. Only used on Windows.
Expand Down
35 changes: 35 additions & 0 deletions dom/ipc/PWindowGlobal.ipdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* 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 protocol PBrowser;
include protocol PInProcess;

include DOMTypes;

using refcounted class nsIURI from "mozilla/ipc/URIUtils.h";

namespace mozilla {
namespace dom {

/**
* A PWindowGlobal actor has a lifetime matching that of a single Window Global,
* specifically a |nsGlobalWindowInner|. These actors will form a parent/child
* link either between the chrome/content process, or will be in-process, for
* documents which are loaded in the chrome process.
*/
async protocol PWindowGlobal
{
manager PBrowser or PInProcess;

parent:
/// Update the URI of the document in this WindowGlobal.
async UpdateDocumentURI(nsIURI aUri);

async __delete__();
};

} // namespace dom
} // namespace mozilla
12 changes: 12 additions & 0 deletions dom/ipc/TabChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
#include "mozilla/Telemetry.h"
#include "nsDocShellLoadState.h"
#include "nsWebBrowser.h"
#include "mozilla/dom/WindowGlobalChild.h"

#ifdef XP_WIN
#include "mozilla/plugins/PluginWidgetChild.h"
Expand Down Expand Up @@ -3137,6 +3138,17 @@ bool TabChild::DeallocPPaymentRequestChild(PPaymentRequestChild* actor) {
return true;
}

PWindowGlobalChild* TabChild::AllocPWindowGlobalChild(const WindowGlobalInit&) {
MOZ_CRASH("We should never be manually allocating PWindowGlobalChild actors");
return nullptr;
}

bool TabChild::DeallocPWindowGlobalChild(PWindowGlobalChild* aActor) {
// This reference was added in WindowGlobalChild::Create.
static_cast<WindowGlobalChild*>(aActor)->Release();
return true;
}

ScreenIntSize TabChild::GetInnerSize() {
LayoutDeviceIntSize innerSize =
RoundedToInt(mUnscaledInnerSize * mPuppetWidget->GetDefaultScale());
Expand Down
5 changes: 5 additions & 0 deletions dom/ipc/TabChild.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,11 @@ class TabChild final : public TabChildBase,
protected:
virtual ~TabChild();

virtual PWindowGlobalChild* AllocPWindowGlobalChild(
const WindowGlobalInit& aInit) override;

virtual bool DeallocPWindowGlobalChild(PWindowGlobalChild* aActor) override;

virtual mozilla::ipc::IPCResult RecvDestroy() override;

virtual mozilla::ipc::IPCResult RecvSetDocShellIsActive(
Expand Down
19 changes: 19 additions & 0 deletions dom/ipc/TabParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
#include "ProcessPriorityManager.h"
#include "nsString.h"
#include "IHistory.h"
#include "mozilla/dom/WindowGlobalParent.h"

#ifdef XP_WIN
#include "mozilla/plugins/PluginWidgetParent.h"
Expand Down Expand Up @@ -988,6 +989,24 @@ bool TabParent::DeallocPIndexedDBPermissionRequestParent(
aActor);
}

IPCResult TabParent::RecvPWindowGlobalConstructor(
PWindowGlobalParent* aActor, const WindowGlobalInit& aInit) {
static_cast<WindowGlobalParent*>(aActor)->Init();
return IPC_OK();
}

PWindowGlobalParent* TabParent::AllocPWindowGlobalParent(
const WindowGlobalInit& aInit) {
// Reference freed in DeallocPWindowGlobalParent.
return do_AddRef(new WindowGlobalParent(aInit, /* inproc */ false)).take();
}

bool TabParent::DeallocPWindowGlobalParent(PWindowGlobalParent* aActor) {
// Free reference from AllocPWindowGlobalParent.
static_cast<WindowGlobalParent*>(aActor)->Release();
return true;
}

void TabParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
int32_t aButton, int32_t aClickCount,
int32_t aModifiers,
Expand Down
8 changes: 8 additions & 0 deletions dom/ipc/TabParent.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,14 @@ class TabParent final : public PBrowserParent,
*/
a11y::DocAccessibleParent* GetTopLevelDocAccessible() const;

virtual PWindowGlobalParent* AllocPWindowGlobalParent(
const WindowGlobalInit& aInit) override;

virtual bool DeallocPWindowGlobalParent(PWindowGlobalParent* aActor) override;

virtual mozilla::ipc::IPCResult RecvPWindowGlobalConstructor(
PWindowGlobalParent* aActor, const WindowGlobalInit& aInit) override;

void LoadURL(nsIURI* aURI);

void InitRendering();
Expand Down
81 changes: 81 additions & 0 deletions dom/ipc/WindowGlobalChild.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* 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 "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/ipc/InProcessChild.h"
#include "mozilla/dom/BrowsingContext.h"

namespace mozilla {
namespace dom {

WindowGlobalChild::WindowGlobalChild(nsGlobalWindowInner* aWindow, dom::BrowsingContext* aBrowsingContext)
: mWindowGlobal(aWindow)
, mBrowsingContext(aBrowsingContext)
, mIPCClosed(false)
{
}

already_AddRefed<WindowGlobalChild>
WindowGlobalChild::Create(nsGlobalWindowInner* aWindow)
{
nsCOMPtr<nsIPrincipal> principal = aWindow->GetPrincipal();
MOZ_ASSERT(principal);

RefPtr<nsDocShell> docshell = nsDocShell::Cast(aWindow->GetDocShell());
MOZ_ASSERT(docshell);

// Initalize our WindowGlobalChild object.
RefPtr<dom::BrowsingContext> bc = docshell->GetBrowsingContext();
RefPtr<WindowGlobalChild> wgc = new WindowGlobalChild(aWindow, bc);

WindowGlobalInit init(principal, BrowsingContextId(wgc->BrowsingContext()->Id()));

// Send the link constructor over PInProcessChild or PBrowser.
if (XRE_IsParentProcess()) {
InProcessChild* ipc = InProcessChild::Singleton();
if (!ipc) {
return nullptr;
}

// Note: ref is released in DeallocPWindowGlobalChild
ipc->SendPWindowGlobalConstructor(do_AddRef(wgc).take(), init);
} else {
RefPtr<TabChild> tabChild = TabChild::GetFrom(static_cast<mozIDOMWindow*>(aWindow));
MOZ_ASSERT(tabChild);

// Note: ref is released in DeallocPWindowGlobalChild
tabChild->SendPWindowGlobalConstructor(do_AddRef(wgc).take(), init);
}

return wgc.forget();
}

already_AddRefed<WindowGlobalParent>
WindowGlobalChild::GetOtherSide()
{
if (mIPCClosed) {
return nullptr;
}
IProtocol* otherSide = InProcessChild::ParentActorFor(this);
return do_AddRef(static_cast<WindowGlobalParent*>(otherSide));
}

void
WindowGlobalChild::ActorDestroy(ActorDestroyReason aWhy)
{
mIPCClosed = true;
}

WindowGlobalChild::~WindowGlobalChild()
{
}

NS_IMPL_CYCLE_COLLECTION(WindowGlobalChild, mWindowGlobal, mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WindowGlobalChild, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WindowGlobalChild, Release)

} // namespace dom
} // namespace mozilla
Loading

0 comments on commit 79164ea

Please sign in to comment.