Bug 1574261 - Make nsDocShell::MaybeHandleSubFrameHistory work with session history in parent, r=peterv

This has couple of different pieces and one may want to focus on each of those separately when
reviewing. The first two as small changes.

- Moving mDynamicallyCreated from nsDocShell to be a sync'ed field on BrowsingContext.
  CanonicalBrowsingContext::CreateLoadingSessionHistoryEntryForLoad sets that on a newly created entry.
- Adding mActiveEntryIsLoadingFromSessionHistory. mLoadingEntry + mActiveEntryIsLoadingFromSessionHistory has roughly
  the same lifetime as mLSHE. mLoadingActiveEntry is needed so that child docshell can know whether its parent is loading from session history.
- The main part is in MaybeHandleSubframeHistory which checks if the parent docshell is loading from session history,
  and if so, asks for a LoadingSessionHistoryInfo. In the case of docshell living in a child process that operation is asynchronous,
  so when the data is back from the parent process, LoadURI is called again with the possibly updated data.
  One could possibly split the code to smaller methods and then deal with aContinueHandlingSubframeHistory only in LoadURI,
  but MaybeHandleSubframeHistory does have some early returns which would make that approach possibly hard to follow.

Differential Revision: https://phabricator.services.mozilla.com/D89685
This commit is contained in:
Olli Pettay 2020-09-17 18:22:08 +00:00
parent 490c700133
commit 208cca166b
11 changed files with 255 additions and 39 deletions

View File

@ -154,7 +154,8 @@ class WindowProxyHolder;
FIELD(IsSingleToplevelInHistory, bool) \
FIELD(UseErrorPages, bool) \
FIELD(PlatformOverride, nsString) \
FIELD(HasLoadedNonInitialDocument, bool)
FIELD(HasLoadedNonInitialDocument, bool) \
FIELD(CreatedDynamically, bool)
// BrowsingContext, in this context, is the cross process replicated
// environment in which information about documents is stored. In

View File

@ -309,6 +309,42 @@ void CanonicalBrowsingContext::AddLoadingSessionHistoryEntry(
mLoadingEntries.AppendElement(LoadingSessionHistoryEntry{aLoadId, aEntry});
}
void CanonicalBrowsingContext::GetLoadingSessionHistoryInfoFromParent(
Maybe<LoadingSessionHistoryInfo>& aLoadingInfo, int32_t* aRequestedIndex,
int32_t* aLength) {
*aRequestedIndex = -1;
*aLength = 0;
nsISHistory* shistory = GetSessionHistory();
if (!shistory || !GetParent()) {
return;
}
SessionHistoryEntry* parentSHE =
GetParent()->Canonical()->GetActiveSessionHistoryEntry();
if (parentSHE) {
int32_t index = -1;
for (BrowsingContext* sibling : GetParent()->Children()) {
++index;
if (sibling == this) {
nsCOMPtr<nsISHEntry> shEntry;
parentSHE->GetChildSHEntryIfHasNoDynamicallyAddedChild(
index, getter_AddRefs(shEntry));
nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(shEntry);
if (she) {
aLoadingInfo.emplace(she);
mLoadingEntries.AppendElement(LoadingSessionHistoryEntry{
aLoadingInfo.value().mLoadId, she.get()});
*aRequestedIndex = shistory->GetRequestedIndex();
*aLength = shistory->GetCount();
Unused << SetHistoryID(she->DocshellID());
}
break;
}
}
}
}
UniquePtr<LoadingSessionHistoryInfo>
CanonicalBrowsingContext::CreateLoadingSessionHistoryEntryForLoad(
nsDocShellLoadState* aLoadState, nsIChannel* aChannel) {
@ -320,6 +356,7 @@ CanonicalBrowsingContext::CreateLoadingSessionHistoryEntryForLoad(
} else {
entry = new SessionHistoryEntry(aLoadState, aChannel);
entry->SetDocshellID(GetHistoryID());
entry->SetIsDynamicallyAdded(GetCreatedDynamically());
entry->SetForInitialLoad(true);
}
MOZ_DIAGNOSTIC_ASSERT(entry);
@ -383,9 +420,16 @@ void CanonicalBrowsingContext::SessionHistoryCommit(uint64_t aLoadId,
// is one, need to figure out if that makes sense here (peterv
// doesn't think it would).
if (loadFromSessionHistory) {
oldActiveEntry->SyncTreesForSubframeNavigation(newActiveEntry, Top(),
this);
if (oldActiveEntry) {
// oldActiveEntry is null if we're loading iframes from session
// history while also parent page is loading from session history.
// In that case there isn't anything to sync.
oldActiveEntry->SyncTreesForSubframeNavigation(newActiveEntry,
Top(), this);
}
mActiveEntry = newActiveEntry;
// FIXME UpdateIndex() here may update index too early (but even the
// old implementation seems to have similar issues).
shistory->UpdateIndex();
} else if (oldActiveEntry) {
// AddChildSHEntryHelper does update the index of the session history!
@ -413,6 +457,7 @@ void CanonicalBrowsingContext::SessionHistoryCommit(uint64_t aLoadId,
return;
}
// XXX Should the loading entries before [i] be removed?
}
// FIXME Should we throw an error if we don't find an entry for
// aSessionHistoryEntryId?

View File

@ -224,6 +224,10 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void AddLoadingSessionHistoryEntry(uint64_t aLoadId,
SessionHistoryEntry* aEntry);
void GetLoadingSessionHistoryInfoFromParent(
Maybe<LoadingSessionHistoryInfo>& aLoadingInfo, int32_t* aRequestedIndex,
int32_t* aLength);
protected:
// Called when the browsing context is being discarded.
void CanonicalDiscard();

View File

@ -405,7 +405,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mIsExecutingOnLoadHandler(false),
mIsPrintingOrPP(false),
mSavingOldViewer(false),
mDynamicallyCreated(false),
mAffectPrivateSessionLifetime(true),
mInvisible(false),
mHasLoadedNonBlankURI(false),
@ -741,6 +740,12 @@ nsDocShell::SetCancelContentJSEpoch(int32_t aEpoch) {
NS_IMETHODIMP
nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
return LoadURI(aLoadState, aSetNavigating, false);
}
nsresult nsDocShell::LoadURI(nsDocShellLoadState* aLoadState,
bool aSetNavigating,
bool aContinueHandlingSubframeHistory) {
MOZ_ASSERT(aLoadState, "Must have a valid load state!");
MOZ_ASSERT(
(aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
@ -806,14 +811,20 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
("nsDocShell[%p]: loading %s with flags 0x%08x", this,
aLoadState->URI()->GetSpecOrDefault().get(), aLoadState->LoadFlags()));
if (!aLoadState->LoadIsFromSessionHistory() &&
!LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(),
LOAD_FLAGS_REPLACE_HISTORY)) {
if ((!aLoadState->LoadIsFromSessionHistory() &&
!LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(),
LOAD_FLAGS_REPLACE_HISTORY)) ||
aContinueHandlingSubframeHistory) {
// This is possibly a subframe, so handle it accordingly.
//
// If history exists, it will be loaded into the aLoadState object, and the
// LoadType will be changed.
MaybeHandleSubframeHistory(aLoadState);
if (MaybeHandleSubframeHistory(aLoadState,
aContinueHandlingSubframeHistory)) {
// MaybeHandleSubframeHistory returns true if we need to continue loading
// asynchronously.
return NS_OK;
}
}
if (aLoadState->LoadIsFromSessionHistory()) {
@ -874,22 +885,32 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
return NS_OK;
}
void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) {
bool nsDocShell::IsLoadingFromSessionHistory() {
return mActiveEntryIsLoadingFromSessionHistory;
}
bool nsDocShell::MaybeHandleSubframeHistory(
nsDocShellLoadState* aLoadState, bool aContinueHandlingSubframeHistory) {
// First, verify if this is a subframe.
// Note, it is ok to rely on docshell here and not browsing context since when
// an iframe is created, it has first in-process docshell.
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
GetInProcessSameTypeParent(getter_AddRefs(parentAsItem));
nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(parentAsItem));
if (!parentDS || parentDS == static_cast<nsIDocShell*>(this)) {
// This is the root docshell. If we got here while
// executing an onLoad Handler,this load will not go
// into session history.
bool inOnLoadHandler = false;
GetIsExecutingOnLoadHandler(&inOnLoadHandler);
if (inOnLoadHandler) {
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
if (mBrowsingContext && mBrowsingContext->IsTop()) {
// This is the root docshell. If we got here while
// executing an onLoad Handler,this load will not go
// into session history.
// XXX Why is this code in a method which deals with iframes!
bool inOnLoadHandler = false;
GetIsExecutingOnLoadHandler(&inOnLoadHandler);
if (inOnLoadHandler) {
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
}
}
return;
return false;
}
/* OK. It is a subframe. Checkout the parent's loadtype. If the parent was
@ -904,20 +925,79 @@ void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) {
uint32_t parentLoadType;
parentDS->GetLoadType(&parentLoadType);
// Get the ShEntry for the child from the parent
nsCOMPtr<nsISHEntry> currentSH;
bool oshe = false;
parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe);
bool dynamicallyAddedChild = mDynamicallyCreated;
if (!aContinueHandlingSubframeHistory) {
if (StaticPrefs::fission_sessionHistoryInParent()) {
if (nsDocShell::Cast(parentDS.get())->IsLoadingFromSessionHistory() &&
!GetCreatedDynamically()) {
if (XRE_IsContentProcess()) {
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
if (contentChild) {
RefPtr<Document> parentDoc = parentDS->GetDocument();
parentDoc->BlockOnload();
RefPtr<BrowsingContext> browsingContext = mBrowsingContext;
Maybe<uint64_t> currentLoadIdentifier =
mBrowsingContext->GetCurrentLoadIdentifier();
RefPtr<nsDocShellLoadState> loadState = aLoadState;
bool isNavigating = mIsNavigating;
if (!dynamicallyAddedChild && !oshe && currentSH) {
// Only use the old SHEntry, if we're sure enough that
// it wasn't originally for some other frame.
nsCOMPtr<nsISHEntry> shEntry;
currentSH->GetChildSHEntryIfHasNoDynamicallyAddedChild(
mChildOffset, getter_AddRefs(shEntry));
if (shEntry) {
aLoadState->SetSHEntry(shEntry);
auto resolve =
[currentLoadIdentifier, browsingContext, parentDoc, loadState,
isNavigating](Tuple<mozilla::Maybe<LoadingSessionHistoryInfo>,
int32_t, int32_t>&& aResult) {
if (currentLoadIdentifier ==
browsingContext->GetCurrentLoadIdentifier() &&
Get<0>(aResult).isSome()) {
loadState->SetLoadingSessionHistoryInfo(
Get<0>(aResult).value());
loadState->SetLoadIsFromSessionHistory(
Get<1>(aResult), Get<2>(aResult), false);
}
RefPtr<nsDocShell> docShell =
static_cast<nsDocShell*>(browsingContext->GetDocShell());
if (docShell) {
// We got the results back from the parent process, call
// LoadURI again with the possibly updated data.
docShell->LoadURI(loadState, isNavigating, true);
}
parentDoc->UnblockOnload(false);
};
auto reject = [parentDoc](mozilla::ipc::ResponseRejectReason) {
parentDoc->UnblockOnload(false);
};
contentChild->SendGetLoadingSessionHistoryInfoFromParent(
mBrowsingContext, std::move(resolve), std::move(reject));
return true;
}
} else {
Maybe<LoadingSessionHistoryInfo> info;
int32_t requestedIndex = -1;
int32_t sessionHistoryLength = 0;
mBrowsingContext->Canonical()->GetLoadingSessionHistoryInfoFromParent(
info, &requestedIndex, &sessionHistoryLength);
if (info.isSome()) {
aLoadState->SetLoadingSessionHistoryInfo(info.value());
aLoadState->SetLoadIsFromSessionHistory(
requestedIndex, sessionHistoryLength, false);
}
}
}
} else {
// Get the ShEntry for the child from the parent
nsCOMPtr<nsISHEntry> currentSH;
bool oshe = false;
parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe);
bool dynamicallyAddedChild = GetCreatedDynamically();
if (!dynamicallyAddedChild && !oshe && currentSH) {
// Only use the old SHEntry, if we're sure enough that
// it wasn't originally for some other frame.
nsCOMPtr<nsISHEntry> shEntry;
currentSH->GetChildSHEntryIfHasNoDynamicallyAddedChild(
mChildOffset, getter_AddRefs(shEntry));
if (shEntry) {
aLoadState->SetSHEntry(shEntry);
}
}
}
}
@ -929,10 +1009,12 @@ void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) {
// initial about:blank content viewer being created and mCurrentURI being
// set. To handle this case we check if mCurrentURI is about:blank and
// currentSHEntry is null.
bool oshe = false;
nsCOMPtr<nsISHEntry> currentChildEntry;
GetCurrentSHEntry(getter_AddRefs(currentChildEntry), &oshe);
if (mCurrentURI && (!NS_IsAboutBlank(mCurrentURI) || currentChildEntry)) {
if (mCurrentURI && (!NS_IsAboutBlank(mCurrentURI) || currentChildEntry ||
mLoadingEntry || mActiveEntry)) {
// This is a pre-existing subframe. If
// 1. The load of this frame was not originally initiated by session
// history directly (i.e. (!shEntry) condition succeeded, but it can
@ -950,7 +1032,7 @@ void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) {
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
aLoadState->ClearLoadIsFromSessionHistory();
}
return;
return false;
}
// This is a newly created frame. Check for exception cases first.
@ -999,6 +1081,8 @@ void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) {
// bypasses the cache and/or proxy
aLoadState->SetLoadType(parentLoadType);
}
return false;
}
/*
@ -3040,13 +3124,15 @@ nsresult nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry,
NS_IMETHODIMP
nsDocShell::SetCreatedDynamically(bool aDynamic) {
mDynamicallyCreated = aDynamic;
if (mBrowsingContext) {
Unused << mBrowsingContext->SetCreatedDynamically(aDynamic);
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetCreatedDynamically(bool* aDynamic) {
*aDynamic = mDynamicallyCreated;
*aDynamic = mBrowsingContext && mBrowsingContext->GetCreatedDynamically();
return NS_OK;
}
@ -4109,6 +4195,7 @@ nsDocShell::Stop(uint32_t aStopFlags) {
// Since error page loads never unset mLSHE, do so now
SetHistoryEntryAndUpdateBC(Some(nullptr), Some<nsISHEntry*>(mLSHE));
}
mActiveEntryIsLoadingFromSessionHistory = false;
mFailedChannel = nullptr;
mFailedURI = nullptr;
@ -5615,6 +5702,7 @@ nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer,
MOZ_LOG(gSHLog, LogLevel::Debug, ("document %p Embed", this));
mActiveEntry = nullptr;
mozilla::UniquePtr<mozilla::dom::LoadingSessionHistoryInfo> loadingEntry;
mActiveEntryIsLoadingFromSessionHistory = !!mLoadingEntry;
if (mLoadingEntry) {
mActiveEntry = MakeUnique<SessionHistoryInfo>(mLoadingEntry->mInfo);
mLoadingEntry.swap(loadingEntry);
@ -6429,6 +6517,8 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
// way or another.
SetHistoryEntryAndUpdateBC(Some(nullptr), Nothing());
}
mActiveEntryIsLoadingFromSessionHistory = false;
// if there's a refresh header in the channel, this method
// will set it up for us.
if (mBrowsingContext->GetIsActive() || !mDisableMetaRefreshWhenInactive)
@ -11372,7 +11462,7 @@ nsresult nsDocShell::AddToSessionHistory(
mContentTypeHint, // Content-type
triggeringPrincipal, // Channel or provided principal
principalToInherit, partitionedPrincipalToInherit, csp,
HistoryID(), mDynamicallyCreated, originalURI,
HistoryID(), GetCreatedDynamically(), originalURI,
resultPrincipalURI, loadReplace, referrerInfo, srcdoc,
srcdocEntry, baseURI, saveLayoutState, expired);

View File

@ -523,6 +523,9 @@ class nsDocShell final : public nsDocLoader,
return mBrowsingContext->GetChildSessionHistory();
}
// This returns true only when using session history in parent.
bool IsLoadingFromSessionHistory();
private: // member functions
friend class nsDSURIContentListener;
friend class FramingChecker;
@ -1032,7 +1035,9 @@ class nsDocShell final : public nsDocLoader,
// loadType may need to reflect the loadType of the parent document, or in
// some cases (like reloads), the history load may need to be cancelled. See
// function comments for in-depth logic descriptions.
void MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState);
// Returns true if the method itself deals with the load.
bool MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState,
bool aContinueHandlingSubframeHistory);
// If we are passed a named target during InternalLoad, this method handles
// moving the load to the browsing context the target name resolves to.
@ -1087,6 +1092,9 @@ class nsDocShell final : public nsDocLoader,
void SetCacheKeyOnHistoryEntry(nsISHEntry* aSHEntry, uint32_t aCacheKey);
nsresult LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating,
bool aContinueHandlingSubframeHistory);
private: // data members
nsID mHistoryID;
nsString mTitle;
@ -1150,6 +1158,8 @@ class nsDocShell final : public nsDocLoader,
// These are only set when fission.sessionHistoryInParent is set.
mozilla::UniquePtr<mozilla::dom::SessionHistoryInfo> mActiveEntry;
bool mActiveEntryIsLoadingFromSessionHistory = false;
// mLoadingEntry is set when we're about to start loading.
mozilla::UniquePtr<mozilla::dom::LoadingSessionHistoryInfo> mLoadingEntry;
// Holds a weak pointer to a RestorePresentationEvent object if any that
@ -1286,8 +1296,6 @@ class nsDocShell final : public nsDocLoader,
// should be passed a SHEntry to save itself into.
bool mSavingOldViewer : 1;
// @see nsIDocShellHistory::createdDynamically
bool mDynamicallyCreated : 1;
bool mAffectPrivateSessionLifetime : 1;
bool mInvisible : 1;
bool mHasLoadedNonBlankURI : 1;

View File

@ -913,6 +913,11 @@ SessionHistoryEntry::IsDynamicallyAdded() {
return SharedInfo()->mDynamicallyCreated;
}
void SessionHistoryEntry::SetIsDynamicallyAdded(bool aDynamic) {
MOZ_ASSERT_IF(SharedInfo()->mDynamicallyCreated, aDynamic);
SharedInfo()->mDynamicallyCreated = aDynamic;
}
NS_IMETHODIMP
SessionHistoryEntry::HasDynamicallyAddedChild(bool* aHasDynamicallyAddedChild) {
for (const auto& child : mChildren) {
@ -1113,7 +1118,38 @@ SessionHistoryEntry::GetChildAt(int32_t aIndex, nsISHEntry** aChild) {
NS_IMETHODIMP_(void)
SessionHistoryEntry::GetChildSHEntryIfHasNoDynamicallyAddedChild(
int32_t aChildOffset, nsISHEntry** aChild) {
MOZ_CRASH("Need to implement this");
*aChild = nullptr;
bool dynamicallyAddedChild = false;
HasDynamicallyAddedChild(&dynamicallyAddedChild);
if (dynamicallyAddedChild) {
return;
}
// If the user did a shift-reload on this frameset page,
// we don't want to load the subframes from history.
if (IsForceReloadType(mInfo->mLoadType) || mInfo->mLoadType == LOAD_REFRESH) {
return;
}
/* Before looking for the subframe's url, check
* the expiration status of the parent. If the parent
* has expired from cache, then subframes will not be
* loaded from history in certain situations.
* If the user pressed reload and the parent frame has expired
* from cache, we do not want to load the child frame from history.
*/
if (SharedInfo()->mExpired && (mInfo->mLoadType == LOAD_RELOAD_NORMAL)) {
// The parent has expired. Return null.
*aChild = nullptr;
return;
}
// Get the child subframe from session history.
GetChildAt(aChildOffset, aChild);
if (*aChild) {
// Set the parent's Load Type on the child
(*aChild)->SetLoadType(mInfo->mLoadType);
}
}
NS_IMETHODIMP

View File

@ -245,6 +245,8 @@ class SessionHistoryEntry : public nsISHEntry {
const nsID& DocshellID() const;
void SetIsDynamicallyAdded(bool aDynamic);
// Get an entry based on LoadingSessionHistoryInfo's mLoadId. Parent process
// only.
static SessionHistoryEntry* GetByLoadId(uint64_t aLoadId);

View File

@ -6954,6 +6954,26 @@ mozilla::ipc::IPCResult ContentParent::RecvSessionHistoryEntryCacheKey(
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvGetLoadingSessionHistoryInfoFromParent(
const MaybeDiscarded<BrowsingContext>& aContext,
GetLoadingSessionHistoryInfoFromParentResolver&& aResolver) {
if (aContext.IsNullOrDiscarded()) {
return IPC_OK();
}
Maybe<LoadingSessionHistoryInfo> info;
int32_t requestedIndex = -1;
int32_t sessionHistoryLength = 0;
aContext.get_canonical()->GetLoadingSessionHistoryInfoFromParent(
info, &requestedIndex, &sessionHistoryLength);
aResolver(
Tuple<const mozilla::Maybe<LoadingSessionHistoryInfo>&, const int32_t&,
const int32_t&>(info, requestedIndex, sessionHistoryLength));
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvSetActiveSessionHistoryEntryForTop(
const MaybeDiscarded<BrowsingContext>& aContext,
const Maybe<nsPoint>& aPreviousScrollPos, SessionHistoryInfo&& aInfo,

View File

@ -1342,6 +1342,10 @@ class ContentParent final
RecvSessionHistoryEntryStoreWindowNameInContiguousEntries(
const MaybeDiscarded<BrowsingContext>& aContext, const nsString& aName);
mozilla::ipc::IPCResult RecvGetLoadingSessionHistoryInfoFromParent(
const MaybeDiscarded<BrowsingContext>& aContext,
GetLoadingSessionHistoryInfoFromParentResolver&& aResolver);
mozilla::ipc::IPCResult RecvSetActiveSessionHistoryEntryForTop(
const MaybeDiscarded<BrowsingContext>& aContext,
const Maybe<nsPoint>& aPreviousScrollPos, SessionHistoryInfo&& aInfo,

View File

@ -289,6 +289,8 @@ struct DocShellLoadStateInit
bool ChannelInitialized;
bool TryToReplaceWithSessionHistoryLoad;
LoadingSessionHistoryInfo? loadingSessionHistoryInfo;
};

View File

@ -130,6 +130,7 @@ using mozilla::PermissionDelegateHandler::DelegatedPermissionList from "mozilla/
using refcounted class nsILayoutHistoryState from "nsILayoutHistoryState.h";
using class mozilla::dom::SessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h";
using nsPoint from "mozilla/GfxMessageUtils.h";
using struct mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h";
union ChromeRegistryItem
{
@ -944,6 +945,9 @@ parent:
async SessionHistoryEntryStoreWindowNameInContiguousEntries(MaybeDiscardedBrowsingContext aContext,
nsString aName);
async GetLoadingSessionHistoryInfoFromParent(MaybeDiscardedBrowsingContext aContext)
returns (LoadingSessionHistoryInfo? aLoadingInfo, int32_t aRequestedIndex, int32_t aLength);
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
async CreateGMPService();