Commit f8e5a4f4 authored by Yao Xiao's avatar Yao Xiao Committed by Commit Bot

Add OnDidInternalNavigationAbort observer method

It allows us to observe mainframe download in PageLoadMetricsObserver.

Bug: 881345
Change-Id: Icc5a3fb9dd645b9bdc291b64030789312614b74d
Reviewed-on: https://chromium-review.googlesource.com/c/1260566Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarJosh Karlin <jkarlin@chromium.org>
Commit-Queue: Yao Xiao <yaoxia@chromium.org>
Cr-Commit-Position: refs/heads/master@{#597576}
parent f6379e5a
......@@ -397,8 +397,10 @@ void MetricsWebContentsObserver::DidFinishNavigation(
if (!navigation_handle->HasCommitted() &&
navigation_handle->GetNetErrorCode() == net::ERR_ABORTED &&
navigation_handle->GetResponseHeaders()) {
if (finished_nav)
if (finished_nav) {
finished_nav->DidInternalNavigationAbort(navigation_handle);
finished_nav->StopTracking();
}
return;
}
......
......@@ -60,13 +60,15 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver {
std::vector<mojom::PageLoadTimingPtr>* complete_timings,
std::vector<ExtraRequestCompleteInfo>* loaded_resources,
std::vector<GURL>* observed_committed_urls,
std::vector<GURL>* observed_aborted_urls,
std::vector<mojom::PageLoadFeatures>* observed_features)
: updated_timings_(updated_timings),
updated_subframe_timings_(updated_subframe_timings),
complete_timings_(complete_timings),
loaded_resources_(loaded_resources),
observed_features_(observed_features),
observed_committed_urls_(observed_committed_urls) {}
observed_committed_urls_(observed_committed_urls),
observed_aborted_urls_(observed_aborted_urls) {}
ObservePolicy OnStart(content::NavigationHandle* navigation_handle,
const GURL& currently_committed_url,
......@@ -107,6 +109,11 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver {
observed_features_->push_back(features);
}
void OnDidInternalNavigationAbort(
content::NavigationHandle* navigation_handle) override {
observed_aborted_urls_->push_back(navigation_handle->GetURL());
}
private:
std::vector<mojom::PageLoadTimingPtr>* const updated_timings_;
std::vector<mojom::PageLoadTimingPtr>* const updated_subframe_timings_;
......@@ -114,6 +121,7 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver {
std::vector<ExtraRequestCompleteInfo>* const loaded_resources_;
std::vector<mojom::PageLoadFeatures>* const observed_features_;
std::vector<GURL>* const observed_committed_urls_;
std::vector<GURL>* const observed_aborted_urls_;
};
// Test PageLoadMetricsObserver that stops observing page loads with certain
......@@ -159,7 +167,8 @@ class TestPageLoadMetricsEmbedderInterface
void RegisterObservers(PageLoadTracker* tracker) override {
tracker->AddObserver(std::make_unique<TestPageLoadMetricsObserver>(
&updated_timings_, &updated_subframe_timings_, &complete_timings_,
&loaded_resources_, &observed_committed_urls_, &observed_features_));
&loaded_resources_, &observed_committed_urls_, &observed_aborted_urls_,
&observed_features_));
tracker->AddObserver(std::make_unique<FilteringPageLoadMetricsObserver>(
&completed_filtered_urls_));
}
......@@ -184,6 +193,10 @@ class TestPageLoadMetricsEmbedderInterface
return observed_committed_urls_;
}
const std::vector<GURL>& observed_aborted_urls() const {
return observed_aborted_urls_;
}
const std::vector<mojom::PageLoadFeatures>& observed_features() const {
return observed_features_;
}
......@@ -202,6 +215,7 @@ class TestPageLoadMetricsEmbedderInterface
std::vector<mojom::PageLoadTimingPtr> updated_subframe_timings_;
std::vector<mojom::PageLoadTimingPtr> complete_timings_;
std::vector<GURL> observed_committed_urls_;
std::vector<GURL> observed_aborted_urls_;
std::vector<ExtraRequestCompleteInfo> loaded_resources_;
std::vector<GURL> completed_filtered_urls_;
std::vector<mojom::PageLoadFeatures> observed_features_;
......@@ -313,6 +327,10 @@ class MetricsWebContentsObserverTest : public ChromeRenderViewHostTestHarness {
return embedder_interface_->observed_committed_urls_from_on_start();
}
const std::vector<GURL>& observed_aborted_urls() const {
return embedder_interface_->observed_aborted_urls();
}
const std::vector<mojom::PageLoadFeatures>& observed_features() const {
return embedder_interface_->observed_features();
}
......@@ -369,6 +387,16 @@ TEST_F(MetricsWebContentsObserverTest, SuccessfulMainFrameNavigation) {
CheckNoErrorEvents();
}
TEST_F(MetricsWebContentsObserverTest, MainFrameNavigationInternalAbort) {
content::WebContentsTester* web_contents_tester =
content::WebContentsTester::For(web_contents());
web_contents_tester->NavigateAndFail(
GURL(kDefaultTestUrl), net::ERR_ABORTED,
base::MakeRefCounted<net::HttpResponseHeaders>("some_headers"));
ASSERT_EQ(1u, observed_aborted_urls().size());
ASSERT_EQ(kDefaultTestUrl, observed_aborted_urls().front().spec());
}
TEST_F(MetricsWebContentsObserverTest, SubFrame) {
mojom::PageLoadTiming timing;
page_load_metrics::InitPageLoadTimingForTest(&timing);
......
......@@ -318,6 +318,13 @@ class PageLoadMetricsObserver {
virtual ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
ukm::SourceId source_id);
// OnDidInternalNavigationAbort is triggered when the main frame navigation
// aborts with HTTP responses that don't commit, such as HTTP 204 responses
// and downloads. Note that |navigation_handle| will be destroyed
// soon after this call. Don't hold a reference to it.
virtual void OnDidInternalNavigationAbort(
content::NavigationHandle* navigation_handle) {}
// OnDidFinishSubFrameNavigation is triggered when a sub-frame of the
// committed page has finished navigating. It has either committed, aborted,
// was a same document navigation, or has been replaced. It is up to the
......
......@@ -356,6 +356,13 @@ void PageLoadTracker::DidCommitSameDocumentNavigation(
}
}
void PageLoadTracker::DidInternalNavigationAbort(
content::NavigationHandle* navigation_handle) {
for (const auto& observer : observers_) {
observer->OnDidInternalNavigationAbort(navigation_handle);
}
}
void PageLoadTracker::DidFinishSubFrameNavigation(
content::NavigationHandle* navigation_handle) {
for (const auto& observer : observers_) {
......
......@@ -189,6 +189,7 @@ class PageLoadTracker : public PageLoadMetricsUpdateDispatcher::Client {
void Commit(content::NavigationHandle* navigation_handle);
void DidCommitSameDocumentNavigation(
content::NavigationHandle* navigation_handle);
void DidInternalNavigationAbort(content::NavigationHandle* navigation_handle);
void DidFinishSubFrameNavigation(
content::NavigationHandle* navigation_handle);
void FailedProvisionalLoad(content::NavigationHandle* navigation_handle,
......
......@@ -572,7 +572,9 @@ void NavigationSimulator::AbortCommit() {
CHECK_EQ(1, num_did_finish_navigation_called_);
}
void NavigationSimulator::Fail(int error_code) {
void NavigationSimulator::FailWithResponseHeaders(
int error_code,
scoped_refptr<net::HttpResponseHeaders> response_headers) {
CHECK_LE(state_, STARTED) << "NavigationSimulator::Fail can only be "
"called once, and cannot be called after "
"NavigationSimulator::ReadyToCommit";
......@@ -584,6 +586,10 @@ void NavigationSimulator::Fail(int error_code) {
if (state_ == INITIALIZATION)
Start();
DCHECK(!handle_->GetResponseHeaders());
static_cast<NavigationHandleImpl*>(handle_)->set_response_headers_for_testing(
response_headers);
state_ = FAILED;
PrepareCompleteCallbackOnHandle();
......@@ -604,6 +610,10 @@ void NavigationSimulator::Fail(int error_code) {
std::move(complete_closure).Run();
}
void NavigationSimulator::Fail(int error_code) {
FailWithResponseHeaders(error_code, nullptr);
}
void NavigationSimulator::FailComplete(int error_code) {
bool should_result_in_error_page = error_code != net::ERR_ABORTED;
if (error_code != net::ERR_ABORTED) {
......
......@@ -203,6 +203,12 @@ class NavigationSimulator : public WebContentsObserver {
// Simulates the commit of a navigation or an error page aborting.
virtual void AbortCommit();
// Simulates the navigation failing with the error code |error_code| and
// response headers |response_headers|.
virtual void FailWithResponseHeaders(
int error_code,
scoped_refptr<net::HttpResponseHeaders> response_headers);
// Simulates the navigation failing with the error code |error_code|.
virtual void Fail(int error_code);
......
......@@ -82,6 +82,13 @@ class WebContentsTester {
// emulates what happens on a new navigation.
virtual void NavigateAndCommit(const GURL& url) = 0;
// Creates a pending navigation to the given URL with the default parameters
// and then aborts it with the given |error_code| and |response_headers|.
virtual void NavigateAndFail(
const GURL& url,
int error_code,
scoped_refptr<net::HttpResponseHeaders> response_headers) = 0;
// Sets the loading state to the given value.
virtual void TestSetIsLoading(bool value) = 0;
......
......@@ -119,6 +119,9 @@ class CancellingNavigationSimulatorTest
void DidFinishNavigation(content::NavigationHandle* handle) override {
did_finish_navigation_ = true;
if (handle->GetResponseHeaders()) {
response_headers_ = handle->GetResponseHeaders()->raw_headers();
}
}
void OnWillFailRequestCalled() { will_fail_request_called_ = true; }
......@@ -128,6 +131,7 @@ class CancellingNavigationSimulatorTest
std::unique_ptr<NavigationSimulator> simulator_;
bool did_finish_navigation_ = false;
bool will_fail_request_called_ = false;
std::string response_headers_;
base::WeakPtrFactory<CancellingNavigationSimulatorTest> weak_ptr_factory_;
private:
......@@ -286,6 +290,21 @@ TEST_P(NavigationSimulatorTestCancelFail, Fail) {
simulator_->GetLastThrottleCheckResult());
}
// Test canceling the simulated navigation with response headers.
TEST_P(NavigationSimulatorTestCancelFail, FailWithResponseHeaders) {
simulator_->Start();
using namespace std::string_literals;
std::string header =
"HTTP/1.1 404 Not Found\0"
"content-encoding: gzip\0\0"s;
simulator_->FailWithResponseHeaders(
net::ERR_CERT_DATE_INVALID,
base::MakeRefCounted<net::HttpResponseHeaders>(header));
EXPECT_EQ(response_headers_, header);
}
INSTANTIATE_TEST_CASE_P(
Fail,
NavigationSimulatorTestCancelFail,
......
......@@ -292,6 +292,15 @@ void TestWebContents::NavigateAndCommit(const GURL& url) {
navigation->Commit();
}
void TestWebContents::NavigateAndFail(
const GURL& url,
int error_code,
scoped_refptr<net::HttpResponseHeaders> response_headers) {
std::unique_ptr<NavigationSimulator> navigation =
NavigationSimulator::CreateBrowserInitiated(url, this);
navigation->FailWithResponseHeaders(error_code, std::move(response_headers));
}
void TestWebContents::TestSetIsLoading(bool value) {
if (value) {
DidStartLoading(GetMainFrame()->frame_tree_node(), true);
......
......@@ -68,6 +68,10 @@ class TestWebContents : public WebContentsImpl, public WebContentsTester {
void CommitPendingNavigation() override;
TestRenderFrameHost* GetPendingMainFrame() override;
void NavigateAndCommit(const GURL& url) override;
void NavigateAndFail(
const GURL& url,
int error_code,
scoped_refptr<net::HttpResponseHeaders> response_headers) override;
void TestSetIsLoading(bool value) override;
void TestDidNavigate(RenderFrameHost* render_frame_host,
int nav_entry_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment