Bug 1663757 - Part 1: Include BrowsingContext info in WebProgressData, r=mattwoodrow

This change allows associating individual web progress events with which frame
they originate from, rather than only recording the `isToplevel` information as
we were before, which is necessary in order to use the OnLocationChange events
from content to track the current URI on CanonicalBrowsingContext.

Due to events in ContentChild being filtered through nsBrowserStatusFilter, some
of the callbacks will never be passed nsIRequest or nsIWebProgress pointers, and
this patch also simplifies them by removing information which is not necessary
from the IPC message.

Finally, this patch adds a number of checks to the relevant Recv callbacks in
the parent process which help ensure that it does not accept web progress events
from a content process which is no longer hosting the target BrowsingContext.
This may allow for us to stop manually suspending web progress events on process
switches, as these checks will handle this automatically based on the existing
BrowsingContext and WindowContext objects.

Differential Revision: https://phabricator.services.mozilla.com/D105556
This commit is contained in:
Nika Layzell 2021-03-09 15:29:40 +00:00
Родитель 3ff4296a89
Коммит ddd075dff2
5 изменённых файлов: 256 добавлений и 219 удалений

Просмотреть файл

@ -3550,11 +3550,6 @@ NS_IMETHODIMP BrowserChild::OnStateChange(nsIWebProgress* aWebProgress,
return NS_OK;
}
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
if (!docShell) {
return NS_OK;
}
// We shouldn't need to notify the parent of redirect state changes, since
// with DocumentChannel that only happens when we switch to the real channel,
// and that's an implementation detail that we can hide.
@ -3562,21 +3557,24 @@ NS_IMETHODIMP BrowserChild::OnStateChange(nsIWebProgress* aWebProgress,
return NS_OK;
}
RefPtr<Document> document;
if (nsCOMPtr<nsPIDOMWindowOuter> outerWindow = do_GetInterface(docShell)) {
document = outerWindow->GetExtantDoc();
} else {
return NS_OK;
// Our OnStateChange call must have provided the nsIDocShell which the source
// comes from. We'll use this to locate the corresponding BrowsingContext in
// the parent process.
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aWebProgress);
if (!docShell) {
MOZ_ASSERT_UNREACHABLE("aWebProgress is null or not a nsIDocShell?");
return NS_ERROR_UNEXPECTED;
}
Maybe<WebProgressData> webProgressData;
WebProgressData webProgressData;
Maybe<WebProgressStateChangeData> stateChangeData;
RequestData requestData;
MOZ_TRY(PrepareProgressListenerData(aWebProgress, aRequest, webProgressData,
requestData));
if (webProgressData->isTopLevel()) {
RefPtr<BrowsingContext> browsingContext = docShell->GetBrowsingContext();
if (browsingContext->IsTopContent()) {
stateChangeData.emplace();
stateChangeData->isNavigating() = docShell->GetIsNavigating();
@ -3584,6 +3582,7 @@ NS_IMETHODIMP BrowserChild::OnStateChange(nsIWebProgress* aWebProgress,
docShell->GetMayEnableCharacterEncodingMenu();
stateChangeData->charsetAutodetected() = docShell->GetCharsetAutodetected();
RefPtr<Document> document = browsingContext->GetExtantDocument();
if (document && aStateFlags & nsIWebProgressListener::STATE_STOP) {
document->GetContentType(stateChangeData->contentType());
document->GetCharacterSet(stateChangeData->charset());
@ -3610,16 +3609,22 @@ NS_IMETHODIMP BrowserChild::OnProgressChange(nsIWebProgress* aWebProgress,
return NS_OK;
}
Maybe<WebProgressData> webProgressData;
RequestData requestData;
// FIXME: We currently ignore ProgressChange events from out-of-process
// subframes both here and in BrowserParent. We may want to change this
// behaviour in the future.
if (!GetBrowsingContext()->IsTopContent()) {
return NS_OK;
}
nsresult rv = PrepareProgressListenerData(aWebProgress, aRequest,
webProgressData, requestData);
NS_ENSURE_SUCCESS(rv, rv);
// As we're being filtered by nsBrowserStatusFilter, we will be passed either
// nullptr or 0 for all arguments other than aCurTotalProgress and
// aMaxTotalProgress. Don't bother sending them.
MOZ_ASSERT(!aWebProgress);
MOZ_ASSERT(!aRequest);
MOZ_ASSERT(aCurSelfProgress == 0);
MOZ_ASSERT(aMaxSelfProgress == 0);
Unused << SendOnProgressChange(webProgressData, requestData, aCurSelfProgress,
aMaxSelfProgress, aCurTotalProgress,
aMaxTotalProgress);
Unused << SendOnProgressChange(aCurTotalProgress, aMaxTotalProgress);
return NS_OK;
}
@ -3632,24 +3637,19 @@ NS_IMETHODIMP BrowserChild::OnLocationChange(nsIWebProgress* aWebProgress,
return NS_OK;
}
nsCOMPtr<nsIWebNavigation> webNav = WebNavigation();
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(webNav);
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aWebProgress);
if (!docShell) {
return NS_OK;
}
RefPtr<Document> document;
if (nsCOMPtr<nsPIDOMWindowOuter> outerWindow = do_GetInterface(docShell)) {
document = outerWindow->GetExtantDoc();
} else {
return NS_OK;
MOZ_ASSERT_UNREACHABLE("aWebProgress is null or not a nsIDocShell?");
return NS_ERROR_UNEXPECTED;
}
RefPtr<BrowsingContext> browsingContext = docShell->GetBrowsingContext();
RefPtr<Document> document = browsingContext->GetExtantDocument();
if (!document) {
return NS_OK;
}
Maybe<WebProgressData> webProgressData;
WebProgressData webProgressData;
RequestData requestData;
MOZ_TRY(PrepareProgressListenerData(aWebProgress, aRequest, webProgressData,
@ -3659,11 +3659,16 @@ NS_IMETHODIMP BrowserChild::OnLocationChange(nsIWebProgress* aWebProgress,
bool canGoBack = false;
bool canGoForward = false;
if (!mozilla::SessionHistoryInParent()) {
MOZ_TRY(WebNavigation()->GetCanGoBack(&canGoBack));
MOZ_TRY(WebNavigation()->GetCanGoForward(&canGoForward));
}
MOZ_TRY(webNav->GetCanGoBack(&canGoBack));
MOZ_TRY(webNav->GetCanGoForward(&canGoForward));
if (browsingContext->IsTopContent()) {
MOZ_ASSERT(
browsingContext == GetBrowsingContext(),
"Toplevel content BrowsingContext which isn't GetBrowsingContext()?");
if (aWebProgress && webProgressData->isTopLevel()) {
locationChangeData.emplace();
document->GetContentType(locationChangeData->contentType());
@ -3723,17 +3728,21 @@ NS_IMETHODIMP BrowserChild::OnStatusChange(nsIWebProgress* aWebProgress,
return NS_OK;
}
Maybe<WebProgressData> webProgressData;
RequestData requestData;
// FIXME: We currently ignore StatusChange from out-of-process subframes both
// here and in BrowserParent. We may want to change this behaviour in the
// future.
if (!GetBrowsingContext()->IsTopContent()) {
return NS_OK;
}
nsresult rv = PrepareProgressListenerData(aWebProgress, aRequest,
webProgressData, requestData);
// As we're being filtered by nsBrowserStatusFilter, we will be passed either
// nullptr or NS_OK for all arguments other than aMessage. Don't bother
// sending them.
MOZ_ASSERT(!aWebProgress);
MOZ_ASSERT(!aRequest);
MOZ_ASSERT(aStatus == NS_OK);
NS_ENSURE_SUCCESS(rv, rv);
const nsString message(aMessage);
Unused << SendOnStatusChange(webProgressData, requestData, aStatus, message);
Unused << SendOnStatusChange(nsDependentString(aMessage));
return NS_OK;
}
@ -3784,51 +3793,48 @@ NS_IMETHODIMP BrowserChild::NotifyNavigationFinished() {
return NS_OK;
}
nsresult BrowserChild::PrepareProgressListenerData(
nsIWebProgress* aWebProgress, nsIRequest* aRequest,
Maybe<WebProgressData>& aWebProgressData, RequestData& aRequestData) {
if (aWebProgress) {
aWebProgressData.emplace();
bool isTopLevel = false;
nsresult rv = aWebProgress->GetIsTopLevel(&isTopLevel);
NS_ENSURE_SUCCESS(rv, rv);
aWebProgressData->isTopLevel() = isTopLevel;
bool isLoadingDocument = false;
rv = aWebProgress->GetIsLoadingDocument(&isLoadingDocument);
NS_ENSURE_SUCCESS(rv, rv);
aWebProgressData->isLoadingDocument() = isLoadingDocument;
uint32_t loadType = 0;
rv = aWebProgress->GetLoadType(&loadType);
NS_ENSURE_SUCCESS(rv, rv);
aWebProgressData->loadType() = loadType;
nsresult BrowserChild::PrepareRequestData(nsIRequest* aRequest,
RequestData& aRequestData) {
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (!channel) {
aRequestData.requestURI() = nullptr;
return NS_OK;
}
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (channel) {
nsCOMPtr<nsIURI> uri;
nsresult rv = channel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
aRequestData.requestURI() = uri;
nsresult rv = channel->GetURI(getter_AddRefs(aRequestData.requestURI()));
NS_ENSURE_SUCCESS(rv, rv);
rv = channel->GetOriginalURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
aRequestData.originalRequestURI() = uri;
rv = channel->GetOriginalURI(
getter_AddRefs(aRequestData.originalRequestURI()));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(channel);
if (classifiedChannel) {
nsAutoCString matchedList;
rv = classifiedChannel->GetMatchedList(matchedList);
NS_ENSURE_SUCCESS(rv, rv);
aRequestData.matchedList() = std::move(matchedList);
}
nsCOMPtr<nsIClassifiedChannel> classifiedChannel = do_QueryInterface(channel);
if (classifiedChannel) {
rv = classifiedChannel->GetMatchedList(aRequestData.matchedList());
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult BrowserChild::PrepareProgressListenerData(
nsIWebProgress* aWebProgress, nsIRequest* aRequest,
WebProgressData& aWebProgressData, RequestData& aRequestData) {
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aWebProgress);
if (!docShell) {
MOZ_ASSERT_UNREACHABLE("aWebProgress is null or not a nsIDocShell?");
return NS_ERROR_UNEXPECTED;
}
aWebProgressData.browsingContext() = docShell->GetBrowsingContext();
nsresult rv =
aWebProgress->GetIsLoadingDocument(&aWebProgressData.isLoadingDocument());
NS_ENSURE_SUCCESS(rv, rv);
rv = aWebProgress->GetLoadType(&aWebProgressData.loadType());
NS_ENSURE_SUCCESS(rv, rv);
return PrepareRequestData(aRequest, aRequestData);
}
bool BrowserChild::UpdateSessionStore(uint32_t aFlushId, bool aIsFinal) {
if (!mSessionStoreListener) {
return false;
@ -3919,15 +3925,12 @@ void BrowserChild::NotifyContentBlockingEvent(
return;
}
Maybe<WebProgressData> webProgressData;
RequestData requestData;
nsresult rv = PrepareProgressListenerData(nullptr, aChannel, webProgressData,
requestData);
NS_ENSURE_SUCCESS_VOID(rv);
Unused << SendNotifyContentBlockingEvent(aEvent, requestData, aBlocked,
PromiseFlatCString(aTrackingOrigin),
aTrackingFullHashes, aReason);
if (NS_SUCCEEDED(PrepareRequestData(aChannel, requestData))) {
Unused << SendNotifyContentBlockingEvent(
aEvent, requestData, aBlocked, PromiseFlatCString(aTrackingOrigin),
aTrackingFullHashes, aReason);
}
}
BrowserChildMessageManager::BrowserChildMessageManager(

Просмотреть файл

@ -796,9 +796,10 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
bool CreateRemoteLayerManager(
mozilla::layers::PCompositorBridgeChild* aCompositorChild);
nsresult PrepareRequestData(nsIRequest* aRequest, RequestData& aRequestData);
nsresult PrepareProgressListenerData(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
Maybe<WebProgressData>& aWebProgressData,
WebProgressData& aWebProgressData,
RequestData& aRequestData);
already_AddRefed<nsIWebBrowserChrome3> GetWebBrowserChromeActor();

Просмотреть файл

@ -2615,145 +2615,153 @@ mozilla::ipc::IPCResult BrowserParent::RecvRegisterProtocolHandler(
}
mozilla::ipc::IPCResult BrowserParent::RecvOnStateChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const uint32_t aStateFlags,
const nsresult aStatus,
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
const uint32_t aStateFlags, const nsresult aStatus,
const Maybe<WebProgressStateChangeData>& aStateChangeData) {
if (mSuspendedProgressEvents) {
return IPC_OK();
}
nsCOMPtr<nsIBrowser> browser = GetBrowser();
if (!GetBrowsingContext()->GetWebProgress() || !browser) {
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
RefPtr<CanonicalBrowsingContext> browsingContext;
if (!ReconstructWebProgressAndRequest(
aWebProgressData, aRequestData, getter_AddRefs(webProgress),
getter_AddRefs(request), getter_AddRefs(browsingContext))) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
if (aStateChangeData.isSome()) {
if (!browsingContext->IsTopContent()) {
return IPC_FAIL(
this,
"Unexpected WebProgressStateChangeData for non toplevel webProgress");
}
if (aWebProgressData && aWebProgressData->isTopLevel() &&
aStateChangeData.isSome()) {
Unused << browser->SetIsNavigating(aStateChangeData->isNavigating());
Unused << browser->SetMayEnableCharacterEncodingMenu(
aStateChangeData->mayEnableCharacterEncodingMenu());
Unused << browser->SetCharsetAutodetected(
aStateChangeData->charsetAutodetected());
Unused << browser->UpdateForStateChange(aStateChangeData->charset(),
aStateChangeData->documentURI(),
aStateChangeData->contentType());
} else if (aStateChangeData.isSome()) {
return IPC_FAIL(
this,
"Unexpected WebProgressStateChangeData for non-top-level WebProgress");
if (nsCOMPtr<nsIBrowser> browser = GetBrowser()) {
Unused << browser->SetIsNavigating(aStateChangeData->isNavigating());
Unused << browser->SetMayEnableCharacterEncodingMenu(
aStateChangeData->mayEnableCharacterEncodingMenu());
Unused << browser->SetCharsetAutodetected(
aStateChangeData->charsetAutodetected());
Unused << browser->UpdateForStateChange(aStateChangeData->charset(),
aStateChangeData->documentURI(),
aStateChangeData->contentType());
}
}
if (nsCOMPtr<nsIWebProgressListener> listener =
GetBrowsingContext()->Top()->GetWebProgress()) {
listener->OnStateChange(webProgress, request, aStateFlags, aStatus);
}
GetBrowsingContext()->Top()->GetWebProgress()->OnStateChange(
webProgress, request, aStateFlags, aStatus);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnProgressChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const int32_t aCurSelfProgress,
const int32_t aMaxSelfProgress, const int32_t aCurTotalProgress,
const int32_t aMaxTotalProgress) {
const int32_t aCurTotalProgress, const int32_t aMaxTotalProgress) {
if (mSuspendedProgressEvents) {
return IPC_OK();
}
if (!GetBrowsingContext()->GetWebProgress()) {
// We only collect progress change notifications for the toplevel
// BrowserParent.
// FIXME: In the future, consider merging in progress change information from
// oop subframes.
if (!GetBrowsingContext()->IsTopContent() ||
!GetBrowsingContext()->GetWebProgress()) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
GetBrowsingContext()->Top()->GetWebProgress()->OnProgressChange(
webProgress, request, aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress);
GetBrowsingContext()->GetWebProgress()->OnProgressChange(
nullptr, nullptr, 0, 0, aCurTotalProgress, aMaxTotalProgress);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnLocationChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, nsIURI* aLocation, const uint32_t aFlags,
const bool aCanGoBack, const bool aCanGoForward,
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
nsIURI* aLocation, const uint32_t aFlags, const bool aCanGoBack,
const bool aCanGoForward,
const Maybe<WebProgressLocationChangeData>& aLocationChangeData) {
if (mSuspendedProgressEvents) {
return IPC_OK();
}
nsCOMPtr<nsIBrowser> browser = GetBrowser();
if (!GetBrowsingContext()->GetWebProgress() || !browser) {
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
RefPtr<CanonicalBrowsingContext> browsingContext;
if (!ReconstructWebProgressAndRequest(
aWebProgressData, aRequestData, getter_AddRefs(webProgress),
getter_AddRefs(request), getter_AddRefs(browsingContext))) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
Unused << browser->UpdateWebNavigationForLocationChange(aCanGoBack,
aCanGoForward);
if (aWebProgressData && aWebProgressData->isTopLevel() &&
aLocationChangeData.isSome()) {
Unused << browser->SetIsNavigating(aLocationChangeData->isNavigating());
Unused << browser->UpdateForLocationChange(
aLocation, aLocationChangeData->charset(),
aLocationChangeData->mayEnableCharacterEncodingMenu(),
aLocationChangeData->charsetAutodetected(),
aLocationChangeData->documentURI(), aLocationChangeData->title(),
aLocationChangeData->contentPrincipal(),
aLocationChangeData->contentPartitionedPrincipal(),
aLocationChangeData->csp(), aLocationChangeData->referrerInfo(),
aLocationChangeData->isSyntheticDocument(),
aLocationChangeData->requestContextID().isSome(),
aLocationChangeData->requestContextID().valueOr(0),
aLocationChangeData->contentType());
nsCOMPtr<nsIBrowser> browser = GetBrowser();
if (!mozilla::SessionHistoryInParent() && browser) {
Unused << browser->UpdateWebNavigationForLocationChange(aCanGoBack,
aCanGoForward);
}
GetBrowsingContext()->Top()->GetWebProgress()->OnLocationChange(
webProgress, request, aLocation, aFlags);
if (aLocationChangeData.isSome()) {
if (!browsingContext->IsTopContent()) {
return IPC_FAIL(this,
"Unexpected WebProgressLocationChangeData for non "
"toplevel webProgress");
}
if (browser) {
Unused << browser->SetIsNavigating(aLocationChangeData->isNavigating());
Unused << browser->UpdateForLocationChange(
aLocation, aLocationChangeData->charset(),
aLocationChangeData->mayEnableCharacterEncodingMenu(),
aLocationChangeData->charsetAutodetected(),
aLocationChangeData->documentURI(), aLocationChangeData->title(),
aLocationChangeData->contentPrincipal(),
aLocationChangeData->contentPartitionedPrincipal(),
aLocationChangeData->csp(), aLocationChangeData->referrerInfo(),
aLocationChangeData->isSyntheticDocument(),
aLocationChangeData->requestContextID().isSome(),
aLocationChangeData->requestContextID().valueOr(0),
aLocationChangeData->contentType());
}
}
if (nsCOMPtr<nsIWebProgressListener> listener =
browsingContext->Top()->GetWebProgress()) {
listener->OnLocationChange(webProgress, request, aLocation, aFlags);
}
// Since we've now changed Documents, notify the BrowsingContext that we've
// changed. Ideally we'd just let the BrowsingContext do this when it changes
// the current window global, but that happens before this and we have a lot
// of tests that depend on the specific ordering of messages.
if (!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) {
GetBrowsingContext()->UpdateSecurityState();
if (browsingContext->IsTopContent() &&
!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) {
browsingContext->UpdateSecurityState();
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnStatusChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const nsresult aStatus,
const nsString& aMessage) {
if (mSuspendedProgressEvents) {
return IPC_OK();
}
if (!GetBrowsingContext()->GetWebProgress()) {
// We only collect status change notifications for the toplevel
// BrowserParent.
// FIXME: In the future, consider merging in status change information from
// oop subframes.
if (!GetBrowsingContext()->IsTopContent() ||
!GetBrowsingContext()->GetWebProgress()) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
GetBrowsingContext()->Top()->GetWebProgress()->OnStatusChange(
webProgress, request, aStatus, aMessage.get());
GetBrowsingContext()->GetWebProgress()->OnStatusChange(nullptr, nullptr,
NS_OK, aMessage.get());
return IPC_OK();
}
@ -2830,32 +2838,63 @@ already_AddRefed<nsIBrowser> BrowserParent::GetBrowser() {
return browser.forget();
}
void BrowserParent::ReconstructWebProgressAndRequest(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, nsIWebProgress** aOutWebProgress,
nsIRequest** aOutRequest) {
bool BrowserParent::ReconstructWebProgressAndRequest(
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
nsIWebProgress** aOutWebProgress, nsIRequest** aOutRequest,
CanonicalBrowsingContext** aOutBrowsingContext) {
MOZ_DIAGNOSTIC_ASSERT(aOutWebProgress,
"aOutWebProgress should never be null");
MOZ_DIAGNOSTIC_ASSERT(aOutRequest, "aOutRequest should never be null");
MOZ_DIAGNOSTIC_ASSERT(aOutBrowsingContext,
"aOutBrowsingContext should never be null");
nsCOMPtr<nsIWebProgress> webProgress;
if (aWebProgressData) {
webProgress = new RemoteWebProgress(aWebProgressData->loadType(),
aWebProgressData->isLoadingDocument(),
aWebProgressData->isTopLevel());
} else {
webProgress = new RemoteWebProgress(0, false, false);
// Look up the BrowsingContext which this notification was fired for.
if (aWebProgressData.browsingContext().IsNullOrDiscarded()) {
NS_WARNING("WebProgress Ignored: BrowsingContext is null or discarded");
return false;
}
webProgress.forget(aOutWebProgress);
RefPtr<CanonicalBrowsingContext> browsingContext =
aWebProgressData.browsingContext().get_canonical();
// Double-check that we actually manage this BrowsingContext, and are not
// receiving a malformed or out-of-date request. browsingContext should either
// be the toplevel one managed by this BrowserParent, or embedded within a
// WindowGlobalParent managed by this BrowserParent.
if (browsingContext != mBrowsingContext) {
WindowGlobalParent* embedder = browsingContext->GetParentWindowContext();
if (!embedder || embedder->GetBrowserParent() != this) {
NS_WARNING("WebProgress Ignored: wrong embedder process");
return false;
}
}
// The current process for this BrowsingContext may have changed since the
// notification was fired. Don't fire events for it anymore, as ownership of
// the BrowsingContext has been moved elsewhere.
if (RefPtr<WindowGlobalParent> current =
browsingContext->GetCurrentWindowGlobal();
current && current->GetBrowserParent() != this) {
NS_WARNING("WebProgress Ignored: no longer current window global");
return false;
}
// Construct a temporary RemoteWebProgress and RemoteWebProgressRequest which
// contains relevant state used by our in-parent callbacks.
nsCOMPtr<nsIWebProgress> webProgress = MakeAndAddRef<RemoteWebProgress>(
aWebProgressData.loadType(), aWebProgressData.isLoadingDocument(),
browsingContext->IsTopContent());
nsCOMPtr<nsIRequest> request;
if (aRequestData.requestURI()) {
nsCOMPtr<nsIRequest> request = MakeAndAddRef<RemoteWebProgressRequest>(
request = MakeAndAddRef<RemoteWebProgressRequest>(
aRequestData.requestURI(), aRequestData.originalRequestURI(),
aRequestData.matchedList());
request.forget(aOutRequest);
} else {
*aOutRequest = nullptr;
}
webProgress.forget(aOutWebProgress);
request.forget(aOutRequest);
browsingContext.forget(aOutBrowsingContext);
return true;
}
mozilla::ipc::IPCResult BrowserParent::RecvSessionStoreUpdate(

Просмотреть файл

@ -279,27 +279,20 @@ class BrowserParent final : public PBrowserParent,
nsIURI* aDocURI);
mozilla::ipc::IPCResult RecvOnStateChange(
const Maybe<WebProgressData>& awebProgressData,
const RequestData& aRequestData, const uint32_t aStateFlags,
const nsresult aStatus,
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
const uint32_t aStateFlags, const nsresult aStatus,
const Maybe<WebProgressStateChangeData>& aStateChangeData);
mozilla::ipc::IPCResult RecvOnProgressChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const int32_t aCurSelfProgress,
const int32_t aMaxSelfProgress, const int32_t aCurTotalProgres,
const int32_t aMaxTotalProgress);
mozilla::ipc::IPCResult RecvOnProgressChange(const int32_t aCurTotalProgres,
const int32_t aMaxTotalProgress);
mozilla::ipc::IPCResult RecvOnLocationChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, nsIURI* aLocation, const uint32_t aFlags,
const bool aCanGoBack, const bool aCanGoForward,
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
nsIURI* aLocation, const uint32_t aFlags, const bool aCanGoBack,
const bool aCanGoForward,
const Maybe<WebProgressLocationChangeData>& aLocationChangeData);
mozilla::ipc::IPCResult RecvOnStatusChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const nsresult aStatus,
const nsString& aMessage);
mozilla::ipc::IPCResult RecvOnStatusChange(const nsString& aMessage);
mozilla::ipc::IPCResult RecvNotifyContentBlockingEvent(
const uint32_t& aEvent, const RequestData& aRequestData,
@ -314,10 +307,10 @@ class BrowserParent final : public PBrowserParent,
already_AddRefed<nsIBrowser> GetBrowser();
void ReconstructWebProgressAndRequest(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, nsIWebProgress** aOutWebProgress,
nsIRequest** aOutRequest);
bool ReconstructWebProgressAndRequest(
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
nsIWebProgress** aOutWebProgress, nsIRequest** aOutRequest,
CanonicalBrowsingContext** aOutBrowsingContext);
mozilla::ipc::IPCResult RecvSessionStoreUpdate(
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,

Просмотреть файл

@ -116,7 +116,7 @@ namespace dom {
struct WebProgressData
{
bool isTopLevel;
MaybeDiscardedBrowsingContext browsingContext;
bool isLoadingDocument;
uint32_t loadType;
};
@ -548,25 +548,26 @@ parent:
async RegisterProtocolHandler(nsString scheme, nsIURI handlerURI, nsString title,
nsIURI documentURI);
async OnStateChange(WebProgressData? aWebProgressData,
async OnStateChange(WebProgressData aWebProgressData,
RequestData aRequestData, uint32_t aStateFlags,
nsresult aStatus,
WebProgressStateChangeData? aStateChangeData);
async OnProgressChange(WebProgressData? aWebProgressData,
RequestData aRequestData, int32_t aCurSelfProgress,
int32_t aMaxSelfProgress, int32_t aCurTotalProgress,
int32_t aMaxTotalProgress);
async OnLocationChange(WebProgressData? aWebProgressData,
async OnLocationChange(WebProgressData aWebProgressData,
RequestData aRequestData, nsIURI aLocation,
uint32_t aFlags, bool aCanGoBack,
bool aCanGoForward,
WebProgressLocationChangeData? aLocationChangeData);
async OnStatusChange(WebProgressData? aWebProgressData,
RequestData aRequestData, nsresult aStatus,
nsString aMessage);
// We only track information about total progress in the parent process.
// This value is throttled using nsBrowserStatusFilter, and records the full
// total progress for nsDocShells managed by this actor.
async OnProgressChange(int32_t aCurTotalProgress, int32_t aMaxTotalProgress);
// Calls to OnStatusChange are throttled by nsBrowserStatusFilter, meaning
// they are only called with a status of `NS_OK`, and with no webProgress or
// request.
async OnStatusChange(nsString aMessage);
async NotifyContentBlockingEvent(uint32_t aEvent, RequestData aRequestData,
bool aBlocked, nsCString aTrackingOrigin,