зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1559657: Pass load time in RemoteWebProgress. r=Ehsan,barret
Differential Revision: https://phabricator.services.mozilla.com/D35147 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
60a8cce828
Коммит
88b4396a69
|
@ -3494,6 +3494,29 @@ NS_IMETHODIMP BrowserChild::OnStateChange(nsIWebProgress* aWebProgress,
|
||||||
MOZ_TRY(PrepareProgressListenerData(aWebProgress, aRequest, webProgressData,
|
MOZ_TRY(PrepareProgressListenerData(aWebProgress, aRequest, webProgressData,
|
||||||
requestData));
|
requestData));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If
|
||||||
|
* 1) this is a document,
|
||||||
|
* 2) the document is top-level,
|
||||||
|
* 3) the document is completely loaded (STATE_STOP), and
|
||||||
|
* 4) this is the end of activity for the document
|
||||||
|
* (STATE_IS_WINDOW, STATE_IS_NETWORK),
|
||||||
|
* then record the elapsed time that it took to load.
|
||||||
|
*/
|
||||||
|
if (document && webProgressData->isTopLevel() &&
|
||||||
|
(aStateFlags & nsIWebProgressListener::STATE_STOP) &&
|
||||||
|
(aStateFlags & nsIWebProgressListener::STATE_IS_WINDOW) &&
|
||||||
|
(aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK)) {
|
||||||
|
RefPtr<nsDOMNavigationTiming> navigationTiming =
|
||||||
|
document->GetNavigationTiming();
|
||||||
|
if (navigationTiming) {
|
||||||
|
TimeDuration elapsedLoadTimeMS =
|
||||||
|
TimeStamp::Now() - navigationTiming->GetNavigationStartTimeStamp();
|
||||||
|
requestData.elapsedLoadTimeMS() =
|
||||||
|
Some(elapsedLoadTimeMS.ToMilliseconds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (webProgressData->isTopLevel()) {
|
if (webProgressData->isTopLevel()) {
|
||||||
stateChangeData.emplace();
|
stateChangeData.emplace();
|
||||||
|
|
||||||
|
|
|
@ -2623,7 +2623,7 @@ void BrowserParent::ReconstructWebProgressAndRequest(
|
||||||
if (aRequestData.requestURI()) {
|
if (aRequestData.requestURI()) {
|
||||||
nsCOMPtr<nsIRequest> request = MakeAndAddRef<RemoteWebProgressRequest>(
|
nsCOMPtr<nsIRequest> request = MakeAndAddRef<RemoteWebProgressRequest>(
|
||||||
aRequestData.requestURI(), aRequestData.originalRequestURI(),
|
aRequestData.requestURI(), aRequestData.originalRequestURI(),
|
||||||
aRequestData.matchedList());
|
aRequestData.matchedList(), aRequestData.elapsedLoadTimeMS());
|
||||||
request.forget(aOutRequest);
|
request.forget(aOutRequest);
|
||||||
} else {
|
} else {
|
||||||
*aOutRequest = nullptr;
|
*aOutRequest = nullptr;
|
||||||
|
|
|
@ -118,6 +118,12 @@ struct RequestData
|
||||||
nsIURI requestURI;
|
nsIURI requestURI;
|
||||||
nsIURI originalRequestURI;
|
nsIURI originalRequestURI;
|
||||||
nsCString matchedList;
|
nsCString matchedList;
|
||||||
|
// The elapsedLoadTimeMS is only set when the request has finished loading.
|
||||||
|
// In other words, this field is set only during and |OnStateChange| event
|
||||||
|
// where |aStateFlags| contains |nsIWebProgressListener::STATE_STOP| and
|
||||||
|
// |nsIWebProgressListener::STATE_IS_NETWORK| and
|
||||||
|
// |nsIWebProgressListener::STATE_IS_WINDOW|, and the document is top level.
|
||||||
|
uint64_t? elapsedLoadTimeMS;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WebProgressStateChangeData
|
struct WebProgressStateChangeData
|
||||||
|
|
|
@ -18,6 +18,17 @@ NS_IMETHODIMP RemoteWebProgressRequest::Init(nsIURI* aURI,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP RemoteWebProgressRequest::GetElapsedLoadTimeMS(
|
||||||
|
uint64_t* aElapsedLoadTimeMS) {
|
||||||
|
NS_ENSURE_ARG_POINTER(aElapsedLoadTimeMS);
|
||||||
|
if (mMaybeElapsedLoadTimeMS) {
|
||||||
|
*aElapsedLoadTimeMS = *mMaybeElapsedLoadTimeMS;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
*aElapsedLoadTimeMS = 0;
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
// nsIChannel methods
|
// nsIChannel methods
|
||||||
|
|
||||||
NS_IMETHODIMP RemoteWebProgressRequest::GetOriginalURI(nsIURI** aOriginalURI) {
|
NS_IMETHODIMP RemoteWebProgressRequest::GetOriginalURI(nsIURI** aOriginalURI) {
|
||||||
|
|
|
@ -26,8 +26,12 @@ class RemoteWebProgressRequest final : public nsIRemoteWebProgressRequest,
|
||||||
: mURI(nullptr), mOriginalURI(nullptr), mMatchedList(VoidCString()) {}
|
: mURI(nullptr), mOriginalURI(nullptr), mMatchedList(VoidCString()) {}
|
||||||
|
|
||||||
RemoteWebProgressRequest(nsIURI* aURI, nsIURI* aOriginalURI,
|
RemoteWebProgressRequest(nsIURI* aURI, nsIURI* aOriginalURI,
|
||||||
const nsACString& aMatchedList)
|
const nsACString& aMatchedList,
|
||||||
: mURI(aURI), mOriginalURI(aOriginalURI), mMatchedList(aMatchedList) {}
|
const Maybe<uint64_t>& aMaybeElapsedLoadTimeMS)
|
||||||
|
: mURI(aURI),
|
||||||
|
mOriginalURI(aOriginalURI),
|
||||||
|
mMatchedList(aMatchedList),
|
||||||
|
mMaybeElapsedLoadTimeMS(aMaybeElapsedLoadTimeMS) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~RemoteWebProgressRequest() = default;
|
~RemoteWebProgressRequest() = default;
|
||||||
|
@ -36,6 +40,13 @@ class RemoteWebProgressRequest final : public nsIRemoteWebProgressRequest,
|
||||||
nsCOMPtr<nsIURI> mURI;
|
nsCOMPtr<nsIURI> mURI;
|
||||||
nsCOMPtr<nsIURI> mOriginalURI;
|
nsCOMPtr<nsIURI> mOriginalURI;
|
||||||
nsCString mMatchedList;
|
nsCString mMatchedList;
|
||||||
|
|
||||||
|
// This field is only Some(...) when the RemoteWebProgressRequest
|
||||||
|
// is created at a time that the document whose progress is being
|
||||||
|
// described by this request is top level and its status changes
|
||||||
|
// from loading to completely loaded.
|
||||||
|
// See BrowserChild::OnStateChange.
|
||||||
|
Maybe<uint64_t> mMaybeElapsedLoadTimeMS;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -10,4 +10,11 @@ interface nsIURI;
|
||||||
interface nsIRemoteWebProgressRequest : nsISupports
|
interface nsIRemoteWebProgressRequest : nsISupports
|
||||||
{
|
{
|
||||||
void init(in nsIURI aURI, in nsIURI aOriginalURI);
|
void init(in nsIURI aURI, in nsIURI aOriginalURI);
|
||||||
|
|
||||||
|
// This field is available to users in |OnStateChange| methods only
|
||||||
|
// when the document whose progress is being described by this progress
|
||||||
|
// request is top level and its status has just changed from loading to
|
||||||
|
// completely loaded; for invocations of |OnStateChange| before or after
|
||||||
|
// that transition, this field will throw |NS_ERROR_UNAVAILABLE|.
|
||||||
|
readonly attribute uint64_t elapsedLoadTimeMS;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,3 +9,5 @@ support-files =
|
||||||
skip-if = !e10 # This is an e10s only probe.
|
skip-if = !e10 # This is an e10s only probe.
|
||||||
[browser_cancel_content_js.js]
|
[browser_cancel_content_js.js]
|
||||||
skip-if = !e10s # This is an e10s only probe.
|
skip-if = !e10s # This is an e10s only probe.
|
||||||
|
[browser_ElapsedTime.js]
|
||||||
|
support-files = elapsed_time.sjs
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synchronize DELAY_MS with DELAY_MS from elapsed_time.sjs
|
||||||
|
*/
|
||||||
|
const DELAY_MS = 200;
|
||||||
|
const SLOW_PAGE =
|
||||||
|
getRootDirectory(gTestPath).replace(
|
||||||
|
"chrome://mochitests/content",
|
||||||
|
"https://example.com"
|
||||||
|
) + "elapsed_time.sjs";
|
||||||
|
|
||||||
|
add_task(async function testLongElapsedTime() {
|
||||||
|
await BrowserTestUtils.withNewTab(
|
||||||
|
{ gBrowser, url: "about:blank" },
|
||||||
|
async function(tabBrowser) {
|
||||||
|
const flags = Ci.nsIWebProgress.NOTIFY_STATE_NETWORK;
|
||||||
|
let listener;
|
||||||
|
|
||||||
|
let stateChangeWaiter = new Promise(resolve => {
|
||||||
|
listener = {
|
||||||
|
onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
|
if (!aWebProgress.isTopLevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const isTopLevel = aWebProgress.isTopLevel;
|
||||||
|
const isStop = aStateFlags & Ci.nsIWebProgressListener.STATE_STOP;
|
||||||
|
const isNetwork =
|
||||||
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
|
||||||
|
const isWindow =
|
||||||
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW;
|
||||||
|
const isLoadingDocument = aWebProgress.isLoadingDocument;
|
||||||
|
|
||||||
|
if (
|
||||||
|
isTopLevel &&
|
||||||
|
isStop &&
|
||||||
|
isWindow &&
|
||||||
|
isNetwork &&
|
||||||
|
!isLoadingDocument
|
||||||
|
) {
|
||||||
|
aRequest.QueryInterface(Ci.nsIRemoteWebProgressRequest);
|
||||||
|
if (aRequest.elapsedLoadTimeMS >= DELAY_MS) {
|
||||||
|
resolve(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
tabBrowser.addProgressListener(listener, flags);
|
||||||
|
|
||||||
|
BrowserTestUtils.loadURI(tabBrowser, SLOW_PAGE);
|
||||||
|
await BrowserTestUtils.browserLoaded(tabBrowser);
|
||||||
|
let pass = await stateChangeWaiter;
|
||||||
|
|
||||||
|
tabBrowser.removeProgressListener(listener);
|
||||||
|
|
||||||
|
ok(
|
||||||
|
pass,
|
||||||
|
"Bug 1559657: Check that the elapsedLoadTimeMS in RemoteWebProgress meets expectations."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
const DELAY_MS = 200;
|
||||||
|
|
||||||
|
const HTML = `<!DOCTYPE HTML>
|
||||||
|
<html dir="ltr" xml:lang="en-US" lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keep timer as a global so that it is not GC'd
|
||||||
|
* between the time that handleRequest() completes
|
||||||
|
* and it expires.
|
||||||
|
*/
|
||||||
|
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||||
|
function handleRequest(req, resp) {
|
||||||
|
resp.processAsync();
|
||||||
|
resp.setHeader("Cache-Control", "no-cache", false);
|
||||||
|
resp.setHeader("Content-Type", "text/html;charset=utf-8", false);
|
||||||
|
|
||||||
|
resp.write(HTML);
|
||||||
|
timer.init(() => {
|
||||||
|
resp.write("");
|
||||||
|
resp.finish();
|
||||||
|
}, DELAY_MS, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче