Bug 1933119 - Fix non-remote frame focus after frameloader change too. r=Jamie,smaug

Differential Revision: https://phabricator.services.mozilla.com/D230097
This commit is contained in:
Emilio Cobos Álvarez
2024-11-26 12:13:30 +00:00
parent 6b634bd17b
commit ce8bfaf724
22 changed files with 156 additions and 83 deletions

View File

@@ -3832,9 +3832,8 @@ void BrowsingContext::HistoryGo(
RefPtr<CanonicalBrowsingContext> self = Canonical();
aResolver(self->HistoryGo(
aOffset, aHistoryEpoch, aRequireUserInteraction, aUserActivation,
Canonical()->GetContentParent()
? Some(Canonical()->GetContentParent()->ChildID())
: Nothing()));
self->GetContentParent() ? Some(self->GetContentParent()->ChildID())
: Nothing()));
}
}

View File

@@ -893,6 +893,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
std::tuple<nsCOMPtr<nsIPrincipal>, nsCOMPtr<nsIPrincipal>>
GetTriggeringAndInheritPrincipalsForCurrentLoad();
MOZ_CAN_RUN_SCRIPT
void HistoryGo(int32_t aOffset, uint64_t aHistoryEpoch,
bool aRequireUserInteraction, bool aUserActivation,
std::function<void(Maybe<int32_t>&&)>&& aResolver);

View File

@@ -1758,7 +1758,8 @@ void CanonicalBrowsingContext::PendingRemotenessChange::ProcessLaunched() {
auto found = mTarget->FindUnloadingHost(mContentParentKeepAlive->ChildID());
if (found != mTarget->mUnloadingHosts.end()) {
found->mCallbacks.AppendElement(
[self = RefPtr{this}]() { self->ProcessReady(); });
[self = RefPtr{this}]()
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA { self->ProcessReady(); });
return;
}
}
@@ -1863,8 +1864,10 @@ nsresult CanonicalBrowsingContext::PendingRemotenessChange::FinishTopContent() {
// The process has been created, hand off to nsFrameLoaderOwner to finish
// the process switch.
ErrorResult error;
frameLoaderOwner->ChangeRemotenessToProcess(mContentParentKeepAlive.get(),
mOptions, mSpecificGroup, error);
RefPtr keepAlive = mContentParentKeepAlive.get();
RefPtr specificGroup = mSpecificGroup;
frameLoaderOwner->ChangeRemotenessToProcess(keepAlive, mOptions,
specificGroup, error);
if (error.Failed()) {
return error.StealNSResult();
}
@@ -2216,10 +2219,11 @@ CanonicalBrowsingContext::ChangeRemoteness(
if (blocker && blocker->State() != Promise::PromiseState::Resolved) {
change->mWaitingForPrepareToChange = true;
blocker->AddCallbacksWithCycleCollectedArgs(
[change](JSContext*, JS::Handle<JS::Value>, ErrorResult&) {
change->mWaitingForPrepareToChange = false;
change->MaybeFinish();
},
[change](JSContext*, JS::Handle<JS::Value>, ErrorResult&)
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA {
change->mWaitingForPrepareToChange = false;
change->MaybeFinish();
},
[change](JSContext*, JS::Handle<JS::Value> aValue, ErrorResult&) {
change->Cancel(
Promise::TryExtractNSResultFromRejectionValue(aValue));
@@ -2299,9 +2303,10 @@ CanonicalBrowsingContext::ChangeRemoteness(
/* aBrowserId */ BrowserId())
->Then(
GetMainThreadSerialEventTarget(), __func__,
[change](UniqueContentParentKeepAlive) {
change->ProcessLaunched();
},
[change](UniqueContentParentKeepAlive)
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA {
change->ProcessLaunched();
},
[change]() { change->Cancel(NS_ERROR_FAILURE); });
} else {
change->ProcessLaunched();

View File

@@ -187,9 +187,9 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void RemoveFromSessionHistory(const nsID& aChangeID);
Maybe<int32_t> HistoryGo(int32_t aOffset, uint64_t aHistoryEpoch,
bool aRequireUserInteraction, bool aUserActivation,
Maybe<ContentParentId> aContentId);
MOZ_CAN_RUN_SCRIPT Maybe<int32_t> HistoryGo(
int32_t aOffset, uint64_t aHistoryEpoch, bool aRequireUserInteraction,
bool aUserActivation, Maybe<ContentParentId> aContentId);
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
@@ -229,12 +229,16 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void LoadURI(nsIURI* aURI, const LoadURIOptions& aOptions,
ErrorResult& aError);
MOZ_CAN_RUN_SCRIPT
void GoBack(const Optional<int32_t>& aCancelContentJSEpoch,
bool aRequireUserInteraction, bool aUserActivation);
MOZ_CAN_RUN_SCRIPT
void GoForward(const Optional<int32_t>& aCancelContentJSEpoch,
bool aRequireUserInteraction, bool aUserActivation);
MOZ_CAN_RUN_SCRIPT
void GoToIndex(int32_t aIndex, const Optional<int32_t>& aCancelContentJSEpoch,
bool aUserActivation);
MOZ_CAN_RUN_SCRIPT
void Reload(uint32_t aReloadFlags);
void Stop(uint32_t aStopFlags);
@@ -251,6 +255,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
// A NOT_REMOTE_TYPE aRemoteType argument will perform a process switch into
// the parent process, and the method will resolve with a null BrowserParent.
using RemotenessPromise = MozPromise<RefPtr<BrowserParent>, nsresult, false>;
MOZ_CAN_RUN_SCRIPT
RefPtr<RemotenessPromise> ChangeRemoteness(
const NavigationIsolationOptions& aOptions, uint64_t aPendingSwitchId);
@@ -383,6 +388,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void AddPageAwakeRequest();
void RemovePageAwakeRequest();
MOZ_CAN_RUN_SCRIPT
void CloneDocumentTreeInto(CanonicalBrowsingContext* aSource,
const nsACString& aRemoteType,
embedding::PrintData&& aPrintData);
@@ -446,11 +452,15 @@ class CanonicalBrowsingContext final : public BrowsingContext {
friend class CanonicalBrowsingContext;
~PendingRemotenessChange();
MOZ_CAN_RUN_SCRIPT
void ProcessLaunched();
MOZ_CAN_RUN_SCRIPT
void ProcessReady();
MOZ_CAN_RUN_SCRIPT
void MaybeFinish();
void Clear();
MOZ_CAN_RUN_SCRIPT
nsresult FinishTopContent();
nsresult FinishSubframe();

View File

@@ -70,6 +70,7 @@ interface nsIWebNavigation : nsISupports
* Indicates that the call was unexpected at this time, which implies
* that canGoBack is false.
*/
[can_run_script]
void goBack([optional] in boolean aRequireUserInteraction, [optional] in boolean aUserActivation);
/**
@@ -94,6 +95,7 @@ interface nsIWebNavigation : nsISupports
* Indicates that the call was unexpected at this time, which implies
* that canGoForward is false.
*/
[can_run_script]
void goForward([optional] in boolean aRequireUserInteraction, [optional] in boolean aUserActivation);
/**
@@ -107,6 +109,7 @@ interface nsIWebNavigation : nsISupports
* Indicates that the call was unexpected at this time, which implies
* that session history entry at the given index does not exist.
*/
[can_run_script]
void gotoIndex(in long index, [optional] in boolean aUserActivation);
/****************************************************************************

View File

@@ -55,9 +55,8 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
int32_t Count();
int32_t Index();
/**
* Reload the current entry in the session history.
*/
/** Reload the current entry in the session history. */
MOZ_CAN_RUN_SCRIPT
void Reload(uint32_t aReloadFlags, ErrorResult& aRv);
/**
@@ -66,12 +65,14 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
* backwards.
*/
bool CanGo(int32_t aOffset);
MOZ_CAN_RUN_SCRIPT
void Go(int32_t aOffset, bool aRequireUserInteraction, bool aUserActivation,
ErrorResult& aRv);
void AsyncGo(int32_t aOffset, bool aRequireUserInteraction,
bool aUserActivation, CallerType aCallerType, ErrorResult& aRv);
// aIndex is the new index, and aOffset is the offset between new and current.
MOZ_CAN_RUN_SCRIPT
void GotoIndex(int32_t aIndex, int32_t aOffset, bool aRequireUserInteraction,
bool aUserActivation, ErrorResult& aRv);
@@ -109,7 +110,7 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
mUserActivation(aUserActivation),
mOffset(aOffset) {}
NS_IMETHOD Run() override {
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
if (isInList()) {
remove();
mHistory->Go(mOffset, mRequireUserInteraction, mUserActivation,
@@ -119,7 +120,7 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
}
private:
RefPtr<ChildSHistory> mHistory;
const RefPtr<ChildSHistory> mHistory;
bool mRequireUserInteraction;
bool mUserActivation;
int32_t mOffset;

View File

@@ -124,12 +124,13 @@ interface nsISHistory: nsISupports
*/
void removeSHistoryListener(in nsISHistoryListener aListener);
[can_run_script]
void reloadCurrentEntry();
/**
* Load the entry at the particular index.
*/
[noscript]
[noscript, can_run_script]
void gotoIndex(in long aIndex, in boolean aUserActivation);
/**
@@ -268,7 +269,7 @@ interface nsISHistory: nsISupports
[noscript, notxpcom]
void RemoveFrameEntries(in nsISHEntry aEntry);
void reload(in unsigned long aReloadFlags);
[can_run_script] void reload(in unsigned long aReloadFlags);
[notxpcom] void EnsureCorrectEntryAtCurrIndex(in nsISHEntry aEntry);

View File

@@ -1222,6 +1222,7 @@ nsSHistory::EvictAllDocumentViewers() {
return NS_OK;
}
MOZ_CAN_RUN_SCRIPT
static void FinishRestore(CanonicalBrowsingContext* aBrowsingContext,
nsDocShellLoadState* aLoadState,
SessionHistoryEntry* aEntry,
@@ -1372,22 +1373,24 @@ void nsSHistory::LoadURIOrBFCache(LoadEntryResult& aLoadEntry) {
currentFrameLoader->GetMaybePendingBrowsingContext()
->Canonical()
->GetCurrentWindowGlobal()) {
wgp->PermitUnload([canonicalBC, loadState, she, frameLoader,
currentFrameLoader, canSave](bool aAllow) {
if (aAllow && !canonicalBC->IsReplaced()) {
FinishRestore(canonicalBC, loadState, she, frameLoader,
canSave && canonicalBC->AllowedInBFCache(
Nothing(), nullptr));
} else if (currentFrameLoader->GetMaybePendingBrowsingContext()) {
nsISHistory* shistory =
currentFrameLoader->GetMaybePendingBrowsingContext()
->Canonical()
->GetSessionHistory();
if (shistory) {
shistory->InternalSetRequestedIndex(-1);
}
}
});
wgp->PermitUnload(
[canonicalBC, loadState, she, frameLoader, currentFrameLoader,
canSave](bool aAllow) MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA {
if (aAllow && !canonicalBC->IsReplaced()) {
FinishRestore(canonicalBC, loadState, she, frameLoader,
canSave && canonicalBC->AllowedInBFCache(
Nothing(), nullptr));
} else if (currentFrameLoader
->GetMaybePendingBrowsingContext()) {
nsISHistory* shistory =
currentFrameLoader->GetMaybePendingBrowsingContext()
->Canonical()
->GetSessionHistory();
if (shistory) {
shistory->InternalSetRequestedIndex(-1);
}
}
});
return;
}
}

View File

@@ -155,7 +155,9 @@ class nsSHistory : public mozilla::LinkedListElement<nsSHistory>,
RefPtr<nsDocShellLoadState> mLoadState;
};
MOZ_CAN_RUN_SCRIPT
static void LoadURIs(nsTArray<LoadEntryResult>& aLoadResults);
MOZ_CAN_RUN_SCRIPT
static void LoadURIOrBFCache(LoadEntryResult& aLoadEntry);
// If this doesn't return an error then either aLoadResult is set to nothing,

View File

@@ -2542,6 +2542,18 @@ void nsFocusManager::ActivateRemoteFrameIfNeeded(Element& aElement,
}
}
void nsFocusManager::FixUpFocusAfterFrameLoaderChange(Element& aElement) {
MOZ_ASSERT(mFocusedElement == &aElement);
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
if (GetContentWindow(&aElement)) {
// This will focus the content window.
SetFocusInner(&aElement, 0, false, false);
} else {
// If we're remote, activate the frame.
ActivateRemoteFrameIfNeeded(aElement, GenerateFocusActionId());
}
}
void nsFocusManager::Focus(
nsPIDOMWindowOuter* aWindow, Element* aElement, uint32_t aFlags,
bool aIsNewDocument, bool aFocusChanged, bool aWindowRaised,

View File

@@ -220,11 +220,9 @@ class nsFocusManager final : public nsIFocusManager,
MOZ_CAN_RUN_SCRIPT nsresult SetFocusedWindowWithCallerType(
mozIDOMWindowProxy* aWindowToFocus, mozilla::dom::CallerType aCallerType);
/**
* Given an element, which must be the focused element, activate the remote
* frame it embeds, if any.
*/
void ActivateRemoteFrameIfNeeded(mozilla::dom::Element&, uint64_t aActionId);
/** Given a focused frame loader owner, fix up the focus to be consistent */
MOZ_CAN_RUN_SCRIPT void FixUpFocusAfterFrameLoaderChange(
mozilla::dom::Element&);
/**
* Raises the top-level window aWindow at the widget level.
@@ -760,6 +758,12 @@ class nsFocusManager final : public nsIFocusManager,
nsIContent** aFocusedContent);
private:
/**
* Given an element, which must be the focused element, activate the remote
* frame it embeds, if any.
*/
void ActivateRemoteFrameIfNeeded(mozilla::dom::Element&, uint64_t aActionId);
// Notify that the focus state of aElement has changed. Note that we need to
// pass in whether the window should show a focus ring before the
// SetFocusedNode call on it happened when losing focus and after the

View File

@@ -231,10 +231,9 @@ void nsFrameLoaderOwner::UpdateFocusAndMouseEnterStateAfterFrameLoaderChange(
Element* aOwner) {
// If the element is focused, or the current mouse over target then
// we need to update that state for the new BrowserParent too.
if (nsFocusManager* fm = nsFocusManager::GetFocusManager()) {
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
if (fm->GetFocusedElement() == aOwner) {
fm->ActivateRemoteFrameIfNeeded(*aOwner,
nsFocusManager::GenerateFocusActionId());
fm->FixUpFocusAfterFrameLoaderChange(*aOwner);
}
}

View File

@@ -58,12 +58,14 @@ class nsFrameLoaderOwner : public nsISupports {
// BrowsingContexts across process switches during navigation.
//
// See the WebIDL definition for more details.
MOZ_CAN_RUN_SCRIPT
void ChangeRemoteness(const mozilla::dom::RemotenessOptions& aOptions,
mozilla::ErrorResult& rv);
// Like `ChangeRemoteness` but switches to an already-created
// `BrowserBridgeChild`. This method is used when performing remote subframe
// process switches.
MOZ_CAN_RUN_SCRIPT
void ChangeRemotenessWithBridge(mozilla::dom::BrowserBridgeChild* aBridge,
mozilla::ErrorResult& rv);
@@ -73,15 +75,18 @@ class nsFrameLoaderOwner : public nsISupports {
//
// If `aReplaceBrowsingContext` is set, BrowsingContext preservation will be
// disabled for this process switch.
MOZ_CAN_RUN_SCRIPT
void ChangeRemotenessToProcess(
mozilla::dom::ContentParent* aContentParent,
const mozilla::dom::NavigationIsolationOptions& aOptions,
mozilla::dom::BrowsingContextGroup* aGroup, mozilla::ErrorResult& rv);
MOZ_CAN_RUN_SCRIPT
void SubframeCrashed();
void RestoreFrameLoaderFromBFCache(nsFrameLoader* aNewFrameLoader);
MOZ_CAN_RUN_SCRIPT
void UpdateFocusAndMouseEnterStateAfterFrameLoaderChange();
void AttachFrameLoader(nsFrameLoader* aFrameLoader);
@@ -108,6 +113,7 @@ class nsFrameLoaderOwner : public nsISupports {
ChangeRemotenessContextType ShouldPreserveBrowsingContext(
bool aIsRemote, bool aReplaceBrowsingContext);
MOZ_CAN_RUN_SCRIPT
void ChangeRemotenessCommon(
const ChangeRemotenessContextType& aContextType,
const mozilla::dom::NavigationIsolationOptions& aOptions,
@@ -118,6 +124,7 @@ class nsFrameLoaderOwner : public nsISupports {
void ChangeFrameLoaderCommon(mozilla::dom::Element* aOwner,
bool aRetainPaint);
MOZ_CAN_RUN_SCRIPT
void UpdateFocusAndMouseEnterStateAfterFrameLoaderChange(
mozilla::dom::Element* aOwner);

View File

@@ -1048,6 +1048,7 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver {
void DoScrollText(ScrollContainerFrame* aScrollContainerFrame,
WidgetWheelEvent* aEvent);
MOZ_CAN_RUN_SCRIPT
void DoScrollHistory(int32_t direction);
void DoScrollZoom(nsIFrame* aTargetFrame, int32_t adjustment);
void ChangeZoom(bool aIncrease);

View File

@@ -93,6 +93,7 @@ class BrowserBridgeChild : public PBrowserBridgeChild {
const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
const int32_t& aAppUnitsPerDevPixel);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvSubFrameCrashed();
void ActorDestroy(ActorDestroyReason aWhy) override;

View File

@@ -730,17 +730,21 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvDisplayLoadError(
const MaybeDiscarded<BrowsingContext>& aContext, const nsAString& aURI);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvGoBack(
const MaybeDiscarded<BrowsingContext>& aContext,
const Maybe<int32_t>& aCancelContentJSEpoch, bool aRequireUserInteraction,
bool aUserActivation);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvGoForward(
const MaybeDiscarded<BrowsingContext>& aContext,
const Maybe<int32_t>& aCancelContentJSEpoch, bool aRequireUserInteraction,
bool aUserActivation);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvGoToIndex(
const MaybeDiscarded<BrowsingContext>& aContext, const int32_t& aIndex,
const Maybe<int32_t>& aCancelContentJSEpoch, bool aUserActivation);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvReload(
const MaybeDiscarded<BrowsingContext>& aContext,
const uint32_t aReloadFlags);

View File

@@ -4079,8 +4079,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCloneDocumentTreeInto(
return IPC_OK();
}
auto* source = aSource.get_canonical();
auto* target = aTarget.get_canonical();
RefPtr source = aSource.get_canonical();
RefPtr target = aTarget.get_canonical();
if (!CloneIsLegal(this, *source, *target)) {
return IPC_FAIL(this, "Illegal subframe clone");

View File

@@ -879,6 +879,7 @@ class ContentParent final : public PContentParent,
bool DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent*);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvCloneDocumentTreeInto(
const MaybeDiscarded<BrowsingContext>& aSource,
const MaybeDiscarded<BrowsingContext>& aTarget, PrintData&& aPrintData);
@@ -1306,6 +1307,7 @@ class ContentParent final : public PContentParent,
const bool& aCloneEntryChildren, const bool& aChannelExpired,
const uint32_t& aCacheKey);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvHistoryGo(
const MaybeDiscarded<BrowsingContext>& aContext, int32_t aOffset,
uint64_t aHistoryEpoch, bool aRequireUserInteraction,
@@ -1359,6 +1361,7 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvRemoveFromSessionHistory(
const MaybeDiscarded<BrowsingContext>& aContext, const nsID& aChangeID);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvHistoryReload(
const MaybeDiscarded<BrowsingContext>& aContext,
const uint32_t aReloadFlags);

View File

@@ -159,10 +159,12 @@ class WindowGlobalChild final : public WindowGlobalActor,
const JSActorMessageMeta& aMeta, const Maybe<ClonedMessageData>& aData,
const Maybe<ClonedMessageData>& aStack);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvMakeFrameLocal(
const MaybeDiscarded<dom::BrowsingContext>& aFrameContext,
uint64_t aPendingSwitchId);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvMakeFrameRemote(
const MaybeDiscarded<dom::BrowsingContext>& aFrameContext,
ManagedEndpoint<PBrowserBridgeChild>&& aEndpoint, const TabId& aTabId,

View File

@@ -2009,20 +2009,22 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
->Then(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this},
options](const RefPtr<BrowsingContext>& aBrowsingContext) mutable {
if (aBrowsingContext->IsDiscarded()) {
MOZ_LOG(
gProcessIsolationLog, LogLevel::Error,
("Process Switch: Got invalid new-tab BrowsingContext"));
self->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
return;
}
options](const RefPtr<BrowsingContext>& aBrowsingContext)
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable {
if (aBrowsingContext->IsDiscarded()) {
MOZ_LOG(gProcessIsolationLog, LogLevel::Error,
("Process Switch: Got invalid new-tab "
"BrowsingContext"));
self->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
return;
}
MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose,
("Process Switch: Redirected load to new tab"));
self->TriggerProcessSwitch(aBrowsingContext->Canonical(), options,
/* aIsNewTab */ true);
},
MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose,
("Process Switch: Redirected load to new tab"));
self->TriggerProcessSwitch(
MOZ_KnownLive(aBrowsingContext->Canonical()), options,
/* aIsNewTab */ true);
},
[self = RefPtr{this}](const CopyableErrorResult&) {
MOZ_LOG(gProcessIsolationLog, LogLevel::Error,
("Process Switch: SwitchToNewTab failed"));
@@ -2049,30 +2051,32 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
mObjectUpgradeHandler->UpgradeObjectLoad()->Then(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this}, options, parentWindow](
const RefPtr<CanonicalBrowsingContext>& aBrowsingContext) mutable {
if (aBrowsingContext->IsDiscarded() ||
parentWindow != aBrowsingContext->GetParentWindowContext()) {
MOZ_LOG(gProcessIsolationLog, LogLevel::Error,
[self = RefPtr{this}, options,
parentWindow](const RefPtr<CanonicalBrowsingContext>& aBrowsingContext)
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable {
if (aBrowsingContext->IsDiscarded() ||
parentWindow != aBrowsingContext->GetParentWindowContext()) {
MOZ_LOG(
gProcessIsolationLog, LogLevel::Error,
("Process Switch: Got invalid BrowsingContext from object "
"upgrade!"));
self->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
return;
}
self->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
return;
}
// At this point the element has stored the container feature policy in
// the new browsing context, but we need to make sure that we copy it
// over to the load info.
nsCOMPtr<nsILoadInfo> loadInfo = self->mChannel->LoadInfo();
if (aBrowsingContext->GetContainerFeaturePolicy()) {
loadInfo->SetContainerFeaturePolicyInfo(
*aBrowsingContext->GetContainerFeaturePolicy());
}
// At this point the element has stored the container feature policy
// in the new browsing context, but we need to make sure that we
// copy it over to the load info.
nsCOMPtr<nsILoadInfo> loadInfo = self->mChannel->LoadInfo();
if (aBrowsingContext->GetContainerFeaturePolicy()) {
loadInfo->SetContainerFeaturePolicyInfo(
*aBrowsingContext->GetContainerFeaturePolicy());
}
MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose,
("Process Switch: Upgraded Object to Document Load"));
self->TriggerProcessSwitch(aBrowsingContext, options);
},
MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose,
("Process Switch: Upgraded Object to Document Load"));
self->TriggerProcessSwitch(aBrowsingContext, options);
},
[self = RefPtr{this}](nsresult aStatusCode) {
MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error");
self->RedirectToRealChannelFinished(aStatusCode);
@@ -2507,6 +2511,10 @@ bool DocumentLoadListener::MaybeHandleLoadErrorWithURIFixup(nsresult aStatus) {
NS_IMETHODIMP
DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
return DoOnStartRequest(aRequest);
}
nsresult DocumentLoadListener::DoOnStartRequest(nsIRequest* aRequest) {
LOG(("DocumentLoadListener OnStartRequest [this=%p]", this));
nsCOMPtr<nsIMultiPartChannel> multiPartChannel = do_QueryInterface(aRequest);

View File

@@ -367,11 +367,17 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// by us, and resumes the underlying source channel.
void FinishReplacementChannelSetup(nsresult aResult);
// TODO: Make nsIRequestObserver MOZ_CAN_RUN_SCRIPT, then remove this. It's a
// scriptable interface so it should be the right thing to do.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
nsresult DoOnStartRequest(nsIRequest*);
// Called from `OnStartRequest` to make the decision about whether or not to
// change process. This method will return `nullptr` if the current target
// process is appropriate.
// aWillSwitchToRemote is set to true if we initiate a process switch,
// and that the new remote type will be something other than NOT_REMOTE
MOZ_CAN_RUN_SCRIPT
bool MaybeTriggerProcessSwitch(bool* aWillSwitchToRemote);
// Called when the process switch is going to happen, potentially
@@ -384,6 +390,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// If `aIsNewTab` is specified, the navigation in the original process will be
// aborted immediately, rather than waiting for a process switch to happen and
// the previous page to be unloaded or hidden.
MOZ_CAN_RUN_SCRIPT
void TriggerProcessSwitch(dom::CanonicalBrowsingContext* aContext,
const dom::NavigationIsolationOptions& aOptions,
bool aIsNewTab = false);

View File

@@ -308,7 +308,7 @@ class WindowlessBrowser final : public nsIWindowlessBrowser,
}
NS_DECL_ISUPPORTS
NS_DECL_NSIWINDOWLESSBROWSER
NS_FORWARD_SAFE_NSIWEBNAVIGATION(mWebNavigation)
NS_FORWARD_SAFE_NSIWEBNAVIGATION(RefPtr{mWebNavigation.get()})
NS_FORWARD_SAFE_NSIINTERFACEREQUESTOR(mInterfaceRequestor)
private: