зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1602318 - Associate a current DocumentLoadListener with CanonicalBrowsingContext. r=nika,necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D67094
This commit is contained in:
Родитель
0230c3bba2
Коммит
8981f913c2
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/dom/PlaybackController.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/net/DocumentLoadListener.h"
|
||||
|
||||
#include "nsGlobalWindowOuter.h"
|
||||
|
||||
|
@ -543,6 +544,20 @@ MediaController* CanonicalBrowsingContext::GetMediaController() {
|
|||
return mTabMediaController;
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::StartDocumentLoad(
|
||||
net::DocumentLoadListener* aLoad) {
|
||||
if (mCurrentLoad) {
|
||||
mCurrentLoad->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
mCurrentLoad = aLoad;
|
||||
}
|
||||
void CanonicalBrowsingContext::EndDocumentLoad(
|
||||
net::DocumentLoadListener* aLoad) {
|
||||
if (mCurrentLoad == aLoad) {
|
||||
mCurrentLoad = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(CanonicalBrowsingContext, BrowsingContext,
|
||||
mSessionHistory)
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
#include "nsISHEntry.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class DocumentLoadListener;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
||||
class WindowGlobalParent;
|
||||
|
@ -176,6 +180,15 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
uint64_t mPendingSwitchId;
|
||||
};
|
||||
|
||||
friend class net::DocumentLoadListener;
|
||||
// Called when a DocumentLoadListener is created to start a load for
|
||||
// this browsing context.
|
||||
void StartDocumentLoad(net::DocumentLoadListener* aLoad);
|
||||
// Called once DocumentLoadListener completes handling a load, and it
|
||||
// is either complete, or handed off to the final channel to deliver
|
||||
// data to the destination docshell.
|
||||
void EndDocumentLoad(net::DocumentLoadListener* aLoad);
|
||||
|
||||
// XXX(farre): Store a ContentParent pointer here rather than mProcessId?
|
||||
// Indicates which process owns the docshell.
|
||||
uint64_t mProcessId;
|
||||
|
@ -197,6 +210,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
// context.
|
||||
RefPtr<MediaController> mTabMediaController;
|
||||
|
||||
RefPtr<net::DocumentLoadListener> mCurrentLoad;
|
||||
|
||||
// These are being mirrored from docshell
|
||||
nsCOMPtr<nsISHEntry> mOSHE;
|
||||
nsCOMPtr<nsISHEntry> mLSHE;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "nsMimeTypes.h"
|
||||
#include "nsIViewSourceChannel.h"
|
||||
#include "nsIOService.h"
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/StaticPrefs_security.h"
|
||||
#include "nsICookieService.h"
|
||||
|
@ -339,6 +340,13 @@ GetTopWindowExcludingExtensionAccessibleContentFrames(
|
|||
return prev.forget();
|
||||
}
|
||||
|
||||
CanonicalBrowsingContext* DocumentLoadListener::GetBrowsingContext() {
|
||||
if (!mParentChannelListener) {
|
||||
return nullptr;
|
||||
}
|
||||
return mParentChannelListener->GetBrowsingContext();
|
||||
}
|
||||
|
||||
bool DocumentLoadListener::Open(
|
||||
nsDocShellLoadState* aLoadState, nsLoadFlags aLoadFlags, uint32_t aCacheKey,
|
||||
const uint64_t& aChannelId, const TimeStamp& aAsyncOpenTime,
|
||||
|
@ -505,6 +513,10 @@ bool DocumentLoadListener::Open(
|
|||
mTiming = aTiming;
|
||||
mSrcdocData = aLoadState->SrcdocData();
|
||||
mBaseURI = aLoadState->BaseURI();
|
||||
|
||||
if (auto* ctx = GetBrowsingContext()) {
|
||||
ctx->StartDocumentLoad(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -518,6 +530,10 @@ void DocumentLoadListener::DocumentChannelBridgeDisconnected() {
|
|||
httpChannelImpl->SetWarningReporter(nullptr);
|
||||
}
|
||||
mDocumentChannelBridge = nullptr;
|
||||
|
||||
if (auto* ctx = GetBrowsingContext()) {
|
||||
ctx->EndDocumentLoad(this);
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentLoadListener::Cancel(const nsresult& aStatusCode) {
|
||||
|
@ -525,9 +541,18 @@ void DocumentLoadListener::Cancel(const nsresult& aStatusCode) {
|
|||
("DocumentLoadListener Cancel [this=%p, "
|
||||
"aStatusCode=%" PRIx32 " ]",
|
||||
this, static_cast<uint32_t>(aStatusCode)));
|
||||
if (mChannel && !mDoingProcessSwitch) {
|
||||
if (mDoingProcessSwitch) {
|
||||
// If we've already initiated process-switching
|
||||
// then we can no longer be cancelled and we'll
|
||||
// disconnect the old listeners when done.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(aStatusCode);
|
||||
}
|
||||
|
||||
DisconnectChildListeners(aStatusCode, aStatusCode);
|
||||
}
|
||||
|
||||
void DocumentLoadListener::DisconnectChildListeners(nsresult aStatus,
|
||||
|
@ -537,7 +562,10 @@ void DocumentLoadListener::DisconnectChildListeners(nsresult aStatus,
|
|||
"aStatus=%" PRIx32 " aLoadGroupStatus=%" PRIx32 " ]",
|
||||
this, static_cast<uint32_t>(aStatus),
|
||||
static_cast<uint32_t>(aLoadGroupStatus)));
|
||||
RefPtr<DocumentLoadListener> keepAlive(this);
|
||||
if (mDocumentChannelBridge) {
|
||||
// This will drop the bridge's reference to us, so we use keepAlive to
|
||||
// make sure we don't get deleted until we exit the function.
|
||||
mDocumentChannelBridge->DisconnectChildListeners(aStatus, aLoadGroupStatus);
|
||||
}
|
||||
DocumentChannelBridgeDisconnected();
|
||||
|
@ -639,6 +667,9 @@ void DocumentLoadListener::FinishReplacementChannelSetup(bool aSucceeded) {
|
|||
redirectChannel->Delete();
|
||||
}
|
||||
mChannel->Resume();
|
||||
if (auto* ctx = GetBrowsingContext()) {
|
||||
ctx->EndDocumentLoad(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -765,6 +796,10 @@ void DocumentLoadListener::ResumeSuspendedChannel(
|
|||
"Should not have added new stream listener function!");
|
||||
|
||||
mChannel->Resume();
|
||||
|
||||
if (auto* ctx = GetBrowsingContext()) {
|
||||
ctx->EndDocumentLoad(this);
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentLoadListener::SerializeRedirectData(
|
||||
|
@ -1024,9 +1059,6 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
|
|||
MOZ_DIAGNOSTIC_ASSERT(mChannel);
|
||||
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(mChannel);
|
||||
|
||||
// If this is a download, then redirect entirely within the parent.
|
||||
// TODO, see bug 1574372.
|
||||
|
||||
if (!mDocumentChannelBridge) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
@ -1035,15 +1067,6 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
|
|||
// might cancel the channel.
|
||||
nsContentSecurityUtils::PerformCSPFrameAncestorAndXFOCheck(mChannel);
|
||||
|
||||
// Once we initiate a process switch, we ask the child to notify the
|
||||
// listeners that we have completed. If the switch promise then gets
|
||||
// rejected we also cancel the parent, which results in this being called.
|
||||
// We don't need to forward it on though, since the child side is already
|
||||
// completed.
|
||||
if (mDoingProcessSwitch) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Generally we want to switch to a real channel even if the request failed,
|
||||
// since the listener might want to access protocol-specific data (like http
|
||||
// response headers) in its error handling.
|
||||
|
@ -1053,7 +1076,7 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
|
|||
nsresult status = NS_OK;
|
||||
aRequest->GetStatus(&status);
|
||||
if (status == NS_ERROR_NO_CONTENT) {
|
||||
mDocumentChannelBridge->DisconnectChildListeners(status, status);
|
||||
DisconnectChildListeners(status, status);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "mozilla/net/PDocumentChannelParent.h"
|
||||
#include "mozilla/net/ParentChannelListener.h"
|
||||
#include "mozilla/net/ADocumentChannelBridge.h"
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIObserver.h"
|
||||
|
@ -32,6 +31,9 @@
|
|||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class CanonicalBrowsingContext;
|
||||
}
|
||||
namespace net {
|
||||
using ChildEndpointPromise =
|
||||
MozPromise<ipc::Endpoint<extensions::PStreamFilterChild>, bool, true>;
|
||||
|
@ -218,6 +220,8 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
|
|||
dom::CanonicalBrowsingContext* aBrowsingContext,
|
||||
nsDocShellLoadState* aLoadState, uint64_t aOuterWindowId);
|
||||
|
||||
dom::CanonicalBrowsingContext* GetBrowsingContext();
|
||||
|
||||
// This defines a variant that describes all the attribute setters (and their
|
||||
// parameters) from nsIParentChannel
|
||||
//
|
||||
|
|
Загрузка…
Ссылка в новой задаче