Skip to content

Commit

Permalink
Bug 1523638 - Part 9: Use provided 'WindowGlobalChild' actors to crea…
Browse files Browse the repository at this point in the history
…te the initial about:blank document, r=kmag

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

--HG--
extra : moz-landing-system : lando
  • Loading branch information
mystor committed Aug 8, 2019
1 parent 15f2abf commit 143941e
Show file tree
Hide file tree
Showing 19 changed files with 169 additions and 62 deletions.
59 changes: 49 additions & 10 deletions docshell/base/nsDocShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,10 @@ static void DecreasePrivateDocShellCount() {
}
}

nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext)
nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
uint64_t aContentWindowID)
: nsDocLoader(),
mContentWindowID(nsContentUtils::GenerateWindowId()),
mContentWindowID(aContentWindowID),
mBrowsingContext(aBrowsingContext),
mForcedCharset(nullptr),
mParentCharset(nullptr),
Expand Down Expand Up @@ -394,6 +395,11 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext)

nsContentUtils::GenerateUUIDInPlace(mHistoryID);

// If no outer window ID was provided, generate a new one.
if (aContentWindowID == 0) {
mContentWindowID = nsContentUtils::GenerateWindowId();
}

if (gDocShellCount++ == 0) {
NS_ASSERTION(sURIFixup == nullptr,
"Huh, sURIFixup not null in first nsDocShell ctor!");
Expand Down Expand Up @@ -460,11 +466,11 @@ nsDocShell::~nsDocShell() {

/* static */
already_AddRefed<nsDocShell> nsDocShell::Create(
BrowsingContext* aBrowsingContext) {
BrowsingContext* aBrowsingContext, uint64_t aContentWindowID) {
MOZ_ASSERT(aBrowsingContext, "DocShell without a BrowsingContext!");

nsresult rv;
RefPtr<nsDocShell> ds = new nsDocShell(aBrowsingContext);
RefPtr<nsDocShell> ds = new nsDocShell(aBrowsingContext, aContentWindowID);

// Initialize the underlying nsDocLoader.
rv = ds->nsDocLoader::Init();
Expand Down Expand Up @@ -518,6 +524,7 @@ already_AddRefed<nsDocShell> nsDocShell::Create(

// Make |ds| the primary DocShell for the given context.
aBrowsingContext->SetDocShell(ds);

return ds.forget();
}

Expand Down Expand Up @@ -6243,12 +6250,13 @@ nsresult nsDocShell::RefreshURIFromQueue() {
return NS_OK;
}

nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer) {
nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer,
WindowGlobalChild* aWindowActor) {
// Save the LayoutHistoryState of the previous document, before
// setting up new document
PersistLayoutHistoryState();

nsresult rv = SetupNewViewer(aContentViewer);
nsresult rv = SetupNewViewer(aContentViewer, aWindowActor);
NS_ENSURE_SUCCESS(rv, rv);

// XXX What if SetupNewViewer fails?
Expand Down Expand Up @@ -6884,6 +6892,7 @@ nsresult nsDocShell::EnsureContentViewer() {
nsCOMPtr<nsIURI> baseURI;
nsIPrincipal* principal = GetInheritedPrincipal(false);
nsIPrincipal* storagePrincipal = GetInheritedPrincipal(false, true);

nsCOMPtr<nsIDocShellTreeItem> parentItem;
GetInProcessSameTypeParent(getter_AddRefs(parentItem));
if (parentItem) {
Expand Down Expand Up @@ -6925,11 +6934,14 @@ nsresult nsDocShell::EnsureContentViewer() {
nsresult nsDocShell::CreateAboutBlankContentViewer(
nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal,
nsIContentSecurityPolicy* aCSP, nsIURI* aBaseURI,
bool aTryToSaveOldPresentation, bool aCheckPermitUnload) {
bool aTryToSaveOldPresentation, bool aCheckPermitUnload,
WindowGlobalChild* aActor) {
RefPtr<Document> blankDoc;
nsCOMPtr<nsIContentViewer> viewer;
nsresult rv = NS_ERROR_FAILURE;

MOZ_ASSERT_IF(aActor, aActor->DocumentPrincipal() == aPrincipal);

/* mCreatingDocument should never be true at this point. However, it's
a theoretical possibility. We want to know about it and make it stop,
and this sounds like a job for an assertion. */
Expand Down Expand Up @@ -7058,7 +7070,7 @@ nsresult nsDocShell::CreateAboutBlankContentViewer(
// hook 'em up
if (viewer) {
viewer->SetContainer(this);
rv = Embed(viewer);
rv = Embed(viewer, aActor);
NS_ENSURE_SUCCESS(rv, rv);

SetCurrentURI(blankDoc->GetDocumentURI(), nullptr, true, 0);
Expand Down Expand Up @@ -7088,6 +7100,32 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
nullptr);
}

nsresult nsDocShell::CreateContentViewerForActor(
WindowGlobalChild* aWindowActor) {
MOZ_ASSERT(aWindowActor);

// FIXME: WindowGlobalChild should provide the StoragePrincipal.
nsresult rv = CreateAboutBlankContentViewer(
aWindowActor->DocumentPrincipal(), aWindowActor->DocumentPrincipal(),
/* aCsp */ nullptr,
/* aBaseURI */ nullptr,
/* aTryToSaveOldPresentation */ true,
/* aCheckPermitUnload */ true, aWindowActor);
if (NS_SUCCEEDED(rv)) {
RefPtr<Document> doc(GetDocument());
MOZ_ASSERT(
doc,
"Should have a document if CreateAboutBlankContentViewer succeeded");
MOZ_ASSERT(doc->GetOwnerGlobal() == aWindowActor->WindowGlobal(),
"New document should be in the same global as our actor");

// FIXME: We may want to support non-initial documents here.
doc->SetIsInitialDocument(true);
}

return rv;
}

bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
nsIRequest* aNewRequest,
Document* aNewDocument) {
Expand Down Expand Up @@ -8293,7 +8331,8 @@ nsresult nsDocShell::NewContentViewerObj(const nsACString& aContentType,
return NS_OK;
}

nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) {
nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer,
WindowGlobalChild* aWindowActor) {
MOZ_ASSERT(!mIsBeingDestroyed);

//
Expand Down Expand Up @@ -8417,7 +8456,7 @@ nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) {

mContentViewer->SetNavigationTiming(mTiming);

if (NS_FAILED(mContentViewer->Init(widget, bounds))) {
if (NS_FAILED(mContentViewer->Init(widget, bounds, aWindowActor))) {
mContentViewer = nullptr;
NS_WARNING("ContentViewer Initialization failed");
return NS_ERROR_FAILURE;
Expand Down
29 changes: 19 additions & 10 deletions docshell/base/nsDocShell.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ class nsDocShell final : public nsDocLoader,

// Create a new nsDocShell object, initializing it.
static already_AddRefed<nsDocShell> Create(
mozilla::dom::BrowsingContext* aBrowsingContext);
mozilla::dom::BrowsingContext* aBrowsingContext,
uint64_t aContentWindowID = 0);

NS_IMETHOD Stop() override {
// Need this here because otherwise nsIWebNavigation::Stop
Expand Down Expand Up @@ -470,6 +471,11 @@ class nsDocShell final : public nsDocLoader,
mSkipBrowsingContextDetachOnDestroy = true;
}

// Create a content viewer within this nsDocShell for the given
// `WindowGlobalChild` actor.
nsresult CreateContentViewerForActor(
mozilla::dom::WindowGlobalChild* aWindowActor);

private: // member functions
friend class nsDSURIContentListener;
friend class FramingChecker;
Expand All @@ -494,7 +500,8 @@ class nsDocShell final : public nsDocLoader,
friend void mozilla::TimelineConsumers::PopMarkers(
nsDocShell*, JSContext*, nsTArray<dom::ProfileTimelineMarker>&);

explicit nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext);
nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext,
uint64_t aContentWindowID);

// Security checks to prevent frameset spoofing. See comments at
// implementation sites.
Expand Down Expand Up @@ -548,12 +555,11 @@ class nsDocShell final : public nsDocLoader,
// aPrincipal can be passed in if the caller wants. If null is
// passed in, the about:blank principal will end up being used.
// aCSP, if any, will be used for the new about:blank load.
nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
nsIPrincipal* aStoragePrincipal,
nsIContentSecurityPolicy* aCSP,
nsIURI* aBaseURI,
bool aTryToSaveOldPresentation = true,
bool aCheckPermitUnload = true);
nsresult CreateAboutBlankContentViewer(
nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal,
nsIContentSecurityPolicy* aCSP, nsIURI* aBaseURI,
bool aTryToSaveOldPresentation = true, bool aCheckPermitUnload = true,
mozilla::dom::WindowGlobalChild* aActor = nullptr);

nsresult CreateContentViewer(const nsACString& aContentType,
nsIRequest* aRequest,
Expand All @@ -564,7 +570,9 @@ class nsDocShell final : public nsDocLoader,
nsIStreamListener** aContentHandler,
nsIContentViewer** aViewer);

nsresult SetupNewViewer(nsIContentViewer* aNewViewer);
nsresult SetupNewViewer(
nsIContentViewer* aNewViewer,
mozilla::dom::WindowGlobalChild* aWindowActor = nullptr);

//
// Session History
Expand Down Expand Up @@ -977,7 +985,8 @@ class nsDocShell final : public nsDocLoader,
nsresult EnsureFind();
nsresult EnsureCommandHandler();
nsresult RefreshURIFromQueue();
nsresult Embed(nsIContentViewer* aContentViewer);
nsresult Embed(nsIContentViewer* aContentViewer,
mozilla::dom::WindowGlobalChild* aWindowActor = nullptr);
nsPresContext* GetEldestPresContext();
nsresult CheckLoadingPermissions();
nsresult PersistLayoutHistoryState();
Expand Down
9 changes: 7 additions & 2 deletions docshell/base/nsIContentViewer.idl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class nsDOMNavigationTiming;
namespace mozilla {
class Encoding;
class PresShell;
}
namespace dom {
class WindowGlobalChild;
} // namespace dom
} // namespace mozilla
%}

[ptr] native nsIWidgetPtr(nsIWidget);
Expand All @@ -32,12 +35,14 @@ class PresShell;
[ref] native nsIContentViewerTArray(nsTArray<nsCOMPtr<nsIContentViewer> >);
[ptr] native Encoding(const mozilla::Encoding);
[ptr] native PresShellPtr(mozilla::PresShell);
[ptr] native WindowGlobalChildPtr(mozilla::dom::WindowGlobalChild);

[scriptable, builtinclass, uuid(2da17016-7851-4a45-a7a8-00b360e01595)]
interface nsIContentViewer : nsISupports
{
[noscript] void init(in nsIWidgetPtr aParentWidget,
[const] in nsIntRectRef aBounds);
[const] in nsIntRectRef aBounds,
in WindowGlobalChildPtr aWindowActor);

attribute nsIDocShell container;

Expand Down
2 changes: 1 addition & 1 deletion dom/base/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ nsresult ExternalResourceMap::AddExternalResource(nsIURI* aURI,
// Make sure that hiding our viewer will tear down its presentation.
aViewer->SetSticky(false);

rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0), nullptr);
if (NS_SUCCEEDED(rv)) {
rv = aViewer->Open(nullptr, nullptr);
}
Expand Down
35 changes: 25 additions & 10 deletions dom/base/nsGlobalWindowInner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -839,8 +839,9 @@ class PromiseDocumentFlushedResolver final {
//*** nsGlobalWindowInner: Object Management
//*****************************************************************************

nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow)
: nsPIDOMWindowInner(aOuterWindow),
nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
WindowGlobalChild* aActor)
: nsPIDOMWindowInner(aOuterWindow, aActor),
mozilla::webgpu::InstanceProvider(this),
mWasOffline(false),
mHasHadSlowScript(false),
Expand Down Expand Up @@ -1606,9 +1607,7 @@ void nsGlobalWindowInner::InnerSetNewDocument(JSContext* aCx,
// FIXME: Currently, devtools can crete a fallback webextension window global
// in the content process which does not have a corresponding BrowserChild
// 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() || mBrowserChild) {
if (!mWindowGlobalChild && (XRE_IsParentProcess() || mBrowserChild)) {
mWindowGlobalChild = WindowGlobalChild::Create(this);
}

Expand Down Expand Up @@ -7107,13 +7106,19 @@ mozilla::dom::TabGroup* nsPIDOMWindowInner::TabGroup() {

/* static */
already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
nsGlobalWindowOuter* aOuterWindow, bool aIsChrome) {
RefPtr<nsGlobalWindowInner> window = new nsGlobalWindowInner(aOuterWindow);
nsGlobalWindowOuter* aOuterWindow, bool aIsChrome,
WindowGlobalChild* aActor) {
RefPtr<nsGlobalWindowInner> window =
new nsGlobalWindowInner(aOuterWindow, aActor);
if (aIsChrome) {
window->mIsChrome = true;
window->mCleanMessageManager = true;
}

if (aActor) {
aActor->InitWindowGlobal(window);
}

window->InitWasOffline();
return window.forget();
}
Expand Down Expand Up @@ -7166,7 +7171,8 @@ bool nsPIDOMWindowInner::HasStorageAccessGranted(
return mStorageAccessGranted.Contains(aPermissionKey);
}

nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow)
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
WindowGlobalChild* aActor)
: mMutationBits(0),
mActivePeerConnections(0),
mIsDocumentLoaded(false),
Expand All @@ -7178,15 +7184,24 @@ nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow)
mMayHavePointerEnterLeaveEventListener(false),
mMayHaveTextEventListenerInDefaultGroup(false),
mOuterWindow(aOuterWindow),
mWindowID(nsContentUtils::GenerateWindowId()),
mWindowID(0),
mHasNotifiedGlobalCreated(false),
mMarkedCCGeneration(0),
mHasTriedToCacheTopInnerWindow(false),
mNumOfIndexedDBDatabases(0),
mNumOfOpenWebSockets(0),
mEvent(nullptr) {
mEvent(nullptr),
mWindowGlobalChild(aActor) {
MOZ_ASSERT(aOuterWindow);
mBrowsingContext = aOuterWindow->GetBrowsingContext();

if (mWindowGlobalChild) {
mWindowID = aActor->InnerWindowId();

MOZ_ASSERT(mWindowGlobalChild->BrowsingContext() == mBrowsingContext);
} else {
mWindowID = nsContentUtils::GenerateWindowId();
}
}

void nsPIDOMWindowInner::RegisterReportingObserver(ReportingObserver* aObserver,
Expand Down
6 changes: 4 additions & 2 deletions dom/base/nsGlobalWindowInner.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
}

static already_AddRefed<nsGlobalWindowInner> Create(
nsGlobalWindowOuter* aOuter, bool aIsChrome);
nsGlobalWindowOuter* aOuter, bool aIsChrome,
mozilla::dom::WindowGlobalChild* aActor);

// nsISupports
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
Expand Down Expand Up @@ -615,7 +616,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
mozilla::ErrorResult& aError);

protected:
explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow);
explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
mozilla::dom::WindowGlobalChild* aActor);
// Initializes the mWasOffline member variable
void InitWasOffline();

Expand Down
5 changes: 3 additions & 2 deletions dom/base/nsGlobalWindowOuter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1873,7 +1873,8 @@ static nsresult CreateNativeGlobalForInner(JSContext* aCx,

nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
nsISupports* aState,
bool aForceReuseInnerWindow) {
bool aForceReuseInnerWindow,
WindowGlobalChild* aActor) {
MOZ_ASSERT(mDocumentPrincipal == nullptr,
"mDocumentPrincipal prematurely set!");
MOZ_ASSERT(mDocumentStoragePrincipal == nullptr,
Expand Down Expand Up @@ -2006,7 +2007,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
newInnerWindow = wsh->GetInnerWindow();
newInnerGlobal = newInnerWindow->GetWrapper();
} else {
newInnerWindow = nsGlobalWindowInner::Create(this, thisChrome);
newInnerWindow = nsGlobalWindowInner::Create(this, thisChrome, aActor);
if (StaticPrefs::dom_timeout_defer_during_load()) {
// ensure the initial loading state is known
newInnerWindow->SetActiveLoadingState(
Expand Down
5 changes: 3 additions & 2 deletions dom/base/nsGlobalWindowOuter.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,9 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,

void DetachFromDocShell();

virtual nsresult SetNewDocument(Document* aDocument, nsISupports* aState,
bool aForceReuseInnerWindow) override;
virtual nsresult SetNewDocument(
Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow,
mozilla::dom::WindowGlobalChild* aActor = nullptr) override;

// Outer windows only.
static void PrepareForProcessChange(JSObject* aProxy);
Expand Down
Loading

0 comments on commit 143941e

Please sign in to comment.