зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1696158 - Move CanSavePresentation to the parent process. Notify parent process of requests in the loadgroup. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D110233
This commit is contained in:
Родитель
d2466bf821
Коммит
14377359b0
|
@ -36,6 +36,7 @@
|
|||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/ScrollTypes.h"
|
||||
#include "mozilla/SimpleEnumerator.h"
|
||||
#include "mozilla/StaticPrefs_browser.h"
|
||||
#include "mozilla/StaticPrefs_docshell.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
|
@ -290,6 +291,7 @@ static mozilla::LazyLogModule gDocShellAndDOMWindowLeakLogging(
|
|||
static mozilla::LazyLogModule gDocShellLeakLog("nsDocShellLeak");
|
||||
extern mozilla::LazyLogModule gPageCacheLog;
|
||||
mozilla::LazyLogModule gSHLog("SessionHistory");
|
||||
extern mozilla::LazyLogModule gSHIPBFCacheLog;
|
||||
|
||||
const char kBrandBundleURL[] = "chrome://branding/locale/brand.properties";
|
||||
const char kAppstringsBundleURL[] =
|
||||
|
@ -13589,3 +13591,102 @@ void nsDocShell::MoveLoadingToActiveEntry(bool aPersist) {
|
|||
hadActiveEntry, aPersist, false);
|
||||
}
|
||||
}
|
||||
|
||||
void nsDocShell::RecordSingleChannelId() {
|
||||
if (mLoadGroup && mBrowsingContext->GetCurrentWindowContext()) {
|
||||
Maybe<uint64_t> singleChannelId;
|
||||
nsCOMPtr<nsISimpleEnumerator> requests;
|
||||
mLoadGroup->GetRequests(getter_AddRefs(requests));
|
||||
for (const auto& request : SimpleEnumerator<nsIRequest>(requests)) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
|
||||
// Ignore favicon loads, they don't need to block caching.
|
||||
nsCOMPtr<nsILoadInfo> li;
|
||||
if (channel && (li = channel->LoadInfo()) &&
|
||||
li->InternalContentPolicyType() ==
|
||||
nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we already found a channel ID or this is not an nsIIdentChannel then
|
||||
// we have more than one request in the loadgroup.
|
||||
nsCOMPtr<nsIIdentChannel> identChannel;
|
||||
if (singleChannelId.isSome() ||
|
||||
!(identChannel = do_QueryInterface(channel))) {
|
||||
// We really have three states: no request, one request with an id and
|
||||
// eiher one request without an id or multiple requests. Nothing() is no
|
||||
// request, Some(non-zero) is one request and Some(0) is one request
|
||||
// without an id or multiple requests.
|
||||
singleChannelId = Some(0);
|
||||
break;
|
||||
}
|
||||
|
||||
singleChannelId = Some(identChannel->ChannelId());
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Verbose))) {
|
||||
nsAutoCString uri("[no uri]");
|
||||
if (mCurrentURI) {
|
||||
uri = mCurrentURI->GetSpecOrDefault();
|
||||
}
|
||||
if (singleChannelId.isNothing()) {
|
||||
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
|
||||
("Loadgroup for %s doesn't have any requests relevant for "
|
||||
"blocking BFCache",
|
||||
uri.get()));
|
||||
} else if (singleChannelId.value() == 0) {
|
||||
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
|
||||
("Loadgroup for %s has multiple requests relevant for blocking "
|
||||
"BFCache",
|
||||
uri.get()));
|
||||
} else {
|
||||
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
|
||||
("Loadgroup for %s has one request with id %" PRIu64
|
||||
" relevant for blocking BFCache",
|
||||
uri.get(), singleChannelId.value()));
|
||||
}
|
||||
}
|
||||
|
||||
if (mSingleChannelId != singleChannelId) {
|
||||
mSingleChannelId = singleChannelId;
|
||||
WindowGlobalChild* wgc =
|
||||
mBrowsingContext->GetCurrentWindowContext()->GetWindowGlobalChild();
|
||||
if (wgc) {
|
||||
wgc->SendSetSingleChannelId(singleChannelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::OnStartRequest(nsIRequest* aRequest) {
|
||||
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Verbose))) {
|
||||
nsAutoCString uri("[no uri]");
|
||||
if (mCurrentURI) {
|
||||
uri = mCurrentURI->GetSpecOrDefault();
|
||||
}
|
||||
nsAutoCString name;
|
||||
aRequest->GetName(name);
|
||||
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
|
||||
("Adding request %s to loadgroup for %s", name.get(), uri.get()));
|
||||
}
|
||||
RecordSingleChannelId();
|
||||
return nsDocLoader::OnStartRequest(aRequest);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
|
||||
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Verbose))) {
|
||||
nsAutoCString uri("[no uri]");
|
||||
if (mCurrentURI) {
|
||||
uri = mCurrentURI->GetSpecOrDefault();
|
||||
}
|
||||
nsAutoCString name;
|
||||
aRequest->GetName(name);
|
||||
MOZ_LOG(
|
||||
gSHIPBFCacheLog, LogLevel::Verbose,
|
||||
("Removing request %s from loadgroup for %s", name.get(), uri.get()));
|
||||
}
|
||||
RecordSingleChannelId();
|
||||
return nsDocLoader::OnStopRequest(aRequest, aStatusCode);
|
||||
}
|
||||
|
|
|
@ -511,6 +511,10 @@ class nsDocShell final : public nsDocLoader,
|
|||
// This returns true only when using session history in parent.
|
||||
bool IsLoadingFromSessionHistory();
|
||||
|
||||
NS_IMETHODIMP OnStartRequest(nsIRequest* aRequest) override;
|
||||
NS_IMETHODIMP OnStopRequest(nsIRequest* aRequest,
|
||||
nsresult aStatusCode) override;
|
||||
|
||||
private: // member functions
|
||||
friend class nsDSURIContentListener;
|
||||
friend class FramingChecker;
|
||||
|
@ -713,6 +717,8 @@ class nsDocShell final : public nsDocLoader,
|
|||
nsIContentSecurityPolicy* aCsp, bool aFireOnLocationChange,
|
||||
bool aAddToGlobalHistory, bool aCloneSHChildren);
|
||||
|
||||
void RecordSingleChannelId();
|
||||
|
||||
public:
|
||||
// Helper method that is called when a new document (including any
|
||||
// sub-documents - ie. frames) has been completely loaded.
|
||||
|
@ -1215,6 +1221,9 @@ class nsDocShell final : public nsDocLoader,
|
|||
// Possible values are defined as constants in nsIDocShell.idl.
|
||||
MetaViewportOverride mMetaViewportOverride;
|
||||
|
||||
// See WindowGlobalParent::mSingleChannelId.
|
||||
mozilla::Maybe<uint64_t> mSingleChannelId;
|
||||
|
||||
// The following two fields cannot be declared as bit fields
|
||||
// because of uses with AutoRestore.
|
||||
bool mCreatingDocument; // (should be) debugging only
|
||||
|
|
|
@ -186,6 +186,16 @@ parent:
|
|||
// enum for the valid flags.
|
||||
async UpdateBFCacheStatus(uint16_t aOnFlags, uint16_t aOffFlags);
|
||||
|
||||
/**
|
||||
* Used to notify the parent when there's a change in the number of requests
|
||||
* in the loadgroup. If there are no requests this will be set to Nothing().
|
||||
* If there is one request this will be set to the ID of that request, if it
|
||||
* implements nsIIdentChannel. If there are more than one requests this will
|
||||
* be set to 0.
|
||||
* Note that some requests are ignored (eg. favicon loads).
|
||||
*/
|
||||
async SetSingleChannelId(uint64_t? singleChannelId);
|
||||
|
||||
async Destroy();
|
||||
};
|
||||
|
||||
|
|
|
@ -1369,6 +1369,12 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateBFCacheStatus(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult WindowGlobalParent::RecvSetSingleChannelId(
|
||||
const Maybe<uint64_t>& aSingleChannelId) {
|
||||
mSingleChannelId = aSingleChannelId;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
if (mPageUseCountersWindow) {
|
||||
mPageUseCountersWindow->FinishAccumulatingPageUseCounters();
|
||||
|
|
|
@ -213,6 +213,8 @@ class WindowGlobalParent final : public WindowContext,
|
|||
const Maybe<nsPoint>& aScrollPosition,
|
||||
uint32_t aEpoch);
|
||||
|
||||
Maybe<uint64_t> GetSingleChannelId() { return mSingleChannelId; }
|
||||
|
||||
protected:
|
||||
already_AddRefed<JSActor> InitJSActor(JS::HandleObject aMaybeActor,
|
||||
const nsACString& aName,
|
||||
|
@ -283,6 +285,10 @@ class WindowGlobalParent final : public WindowContext,
|
|||
mozilla::ipc::IPCResult RecvUpdateBFCacheStatus(const uint16_t& aOnFlags,
|
||||
const uint16_t& aOffFlags);
|
||||
|
||||
public:
|
||||
mozilla::ipc::IPCResult RecvSetSingleChannelId(
|
||||
const Maybe<uint64_t>& aSingleChannelId);
|
||||
|
||||
private:
|
||||
WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext,
|
||||
uint64_t aInnerWindowId, uint64_t aOuterWindowId,
|
||||
|
@ -357,6 +363,17 @@ class WindowGlobalParent final : public WindowContext,
|
|||
bool mSentPageUseCounters = false;
|
||||
|
||||
uint16_t mBFCacheStatus = 0;
|
||||
|
||||
// mSingleChannelId records whether the loadgroup contains a single request
|
||||
// with an id. If there is one channel in the loadgroup and it has an id then
|
||||
// mSingleChannelId is set to Some(id) (ids are non-zero). If there is one
|
||||
// request in the loadgroup and it's not a channel or it doesn't have an id,
|
||||
// or there are multiple requests in the loadgroup, then mSingleChannelId is
|
||||
// set to Some(0). If there are no requests in the loadgroup then
|
||||
// mSingleChannelId is set to Nothing().
|
||||
// Note: We ignore favicon loads when considering the requests in the
|
||||
// loadgroup.
|
||||
Maybe<uint64_t> mSingleChannelId;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
Загрузка…
Ссылка в новой задаче