gecko-dev/dom/ipc/WindowGlobalChild.h
Nika Layzell 965f006a70 Bug 1576714 - Part 3: Initiate subframe process switches from the parent, r=kmag
This flips the direction in which the BrowserBridge actor is generally created
such that it is generally created in the parent and sent down to a child
process.

This is done by making the decision about what kind of switch to perform in the
parent, and sending messages down to child processes async to orchestrate these
process changes.

Process launching is changed to use an async `MozPromise`-returning API in this
patch, though the actual process launching still occurs synchronously. A future
patch will enable performing async process launching through the
NewOrUsedBrowserProcess mechanism.

I know of at least a few timing issues which exist with the new logic,
especially around the state of the BrowsingContext during the process
transition. I decided to not try to fix all of these issues in this patch, as
many are complex and will require changing how we manage the lifecycle of
BrowsingContext substantially. I do, however, think that the new logic is more
reliable and has fewer timing issues than the previous logic.

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

--HG--
extra : moz-landing-system : lando
2019-10-15 16:19:16 +00:00

158 lines
5.4 KiB
C++

/* -*- 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/. */
#ifndef mozilla_dom_WindowGlobalChild_h
#define mozilla_dom_WindowGlobalChild_h
#include "mozilla/RefPtr.h"
#include "mozilla/dom/PWindowGlobalChild.h"
#include "nsRefPtrHashtable.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/WindowGlobalActor.h"
class nsGlobalWindowInner;
class nsDocShell;
namespace mozilla {
namespace dom {
class BrowsingContext;
class WindowGlobalParent;
class JSWindowActorChild;
class JSWindowActorMessageMeta;
class BrowserChild;
/**
* Actor for a single nsGlobalWindowInner. This actor is used to communicate
* information to the parent process asynchronously.
*/
class WindowGlobalChild final : public WindowGlobalActor,
public PWindowGlobalChild {
friend class PWindowGlobalChild;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WindowGlobalChild,
WindowGlobalActor)
static already_AddRefed<WindowGlobalChild> GetByInnerWindowId(
uint64_t aInnerWindowId);
static already_AddRefed<WindowGlobalChild> GetByInnerWindowId(
const GlobalObject& aGlobal, uint64_t aInnerWindowId) {
return GetByInnerWindowId(aInnerWindowId);
}
dom::BrowsingContext* BrowsingContext() override { return mBrowsingContext; }
nsGlobalWindowInner* WindowGlobal() { return mWindowGlobal; }
// Has this actor been shut down
bool IsClosed() { return !CanSend(); }
void Destroy();
// Check if this actor is managed by PInProcess, as-in the document is loaded
// in the chrome process.
bool IsInProcess() { return XRE_IsParentProcess(); }
nsIURI* GetDocumentURI() override { return mDocumentURI; }
void SetDocumentURI(nsIURI* aDocumentURI);
nsIPrincipal* DocumentPrincipal() { return mDocumentPrincipal; }
// The Window ID for this WindowGlobal
uint64_t InnerWindowId() { return mInnerWindowId; }
uint64_t OuterWindowId() { return mOuterWindowId; }
uint64_t ContentParentId();
int64_t BeforeUnloadListeners() { return mBeforeUnloadListeners; }
void BeforeUnloadAdded();
void BeforeUnloadRemoved();
bool IsCurrentGlobal();
bool IsProcessRoot();
// 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> GetParentActor();
// Get this actor's manager if it is not an in-process actor. Returns
// |nullptr| if the actor has been torn down, or is in-process.
already_AddRefed<BrowserChild> GetBrowserChild();
void ReceiveRawMessage(const JSWindowActorMessageMeta& aMeta,
ipc::StructuredCloneData&& aData);
// Get a JS actor object by name.
already_AddRefed<JSWindowActorChild> GetActor(const nsAString& aName,
ErrorResult& aRv);
// Create and initialize the WindowGlobalChild object.
static already_AddRefed<WindowGlobalChild> Create(
nsGlobalWindowInner* aWindow);
WindowGlobalChild(const WindowGlobalInit& aInit,
nsGlobalWindowInner* aWindow);
void Init();
void InitWindowGlobal(nsGlobalWindowInner* aWindow);
nsISupports* GetParentObject();
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
protected:
const nsAString& GetRemoteType() override;
JSWindowActor::Type GetSide() override { return JSWindowActor::Type::Child; }
// IPC messages
mozilla::ipc::IPCResult RecvRawMessage(const JSWindowActorMessageMeta& aMeta,
const ClonedMessageData& aData);
mozilla::ipc::IPCResult RecvLoadURIInChild(nsDocShellLoadState* aLoadState,
bool aSetNavigating);
mozilla::ipc::IPCResult RecvDisplayLoadError(const nsAString& aURI);
mozilla::ipc::IPCResult RecvMakeFrameLocal(
dom::BrowsingContext* aFrameContext, uint64_t aPendingSwitchId);
mozilla::ipc::IPCResult RecvMakeFrameRemote(
dom::BrowsingContext* aFrameContext,
ManagedEndpoint<PBrowserBridgeChild>&& aEndpoint, const TabId& aTabId,
MakeFrameRemoteResolver&& aResolve);
mozilla::ipc::IPCResult RecvDrawSnapshot(const Maybe<IntRect>& aRect,
const float& aScale,
const nscolor& aBackgroundColor,
const uint32_t& aFlags,
DrawSnapshotResolver&& aResolve);
mozilla::ipc::IPCResult RecvGetSecurityInfo(
GetSecurityInfoResolver&& aResolve);
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
private:
~WindowGlobalChild();
RefPtr<nsGlobalWindowInner> mWindowGlobal;
RefPtr<dom::BrowsingContext> mBrowsingContext;
nsRefPtrHashtable<nsStringHashKey, JSWindowActorChild> mWindowActors;
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
nsCOMPtr<nsIURI> mDocumentURI;
uint64_t mInnerWindowId;
uint64_t mOuterWindowId;
int64_t mBeforeUnloadListeners;
};
} // namespace dom
} // namespace mozilla
#endif // !defined(mozilla_dom_WindowGlobalChild_h)