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( ...@@ -397,8 +397,10 @@ void MetricsWebContentsObserver::DidFinishNavigation(
if (!navigation_handle->HasCommitted() && if (!navigation_handle->HasCommitted() &&
navigation_handle->GetNetErrorCode() == net::ERR_ABORTED && navigation_handle->GetNetErrorCode() == net::ERR_ABORTED &&
navigation_handle->GetResponseHeaders()) { navigation_handle->GetResponseHeaders()) {
if (finished_nav) if (finished_nav) {
finished_nav->DidInternalNavigationAbort(navigation_handle);
finished_nav->StopTracking(); finished_nav->StopTracking();
}
return; return;
} }
......
...@@ -60,13 +60,15 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver { ...@@ -60,13 +60,15 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver {
std::vector<mojom::PageLoadTimingPtr>* complete_timings, std::vector<mojom::PageLoadTimingPtr>* complete_timings,
std::vector<ExtraRequestCompleteInfo>* loaded_resources, std::vector<ExtraRequestCompleteInfo>* loaded_resources,
std::vector<GURL>* observed_committed_urls, std::vector<GURL>* observed_committed_urls,
std::vector<GURL>* observed_aborted_urls,
std::vector<mojom::PageLoadFeatures>* observed_features) std::vector<mojom::PageLoadFeatures>* observed_features)
: updated_timings_(updated_timings), : updated_timings_(updated_timings),
updated_subframe_timings_(updated_subframe_timings), updated_subframe_timings_(updated_subframe_timings),
complete_timings_(complete_timings), complete_timings_(complete_timings),
loaded_resources_(loaded_resources), loaded_resources_(loaded_resources),
observed_features_(observed_features), 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, ObservePolicy OnStart(content::NavigationHandle* navigation_handle,
const GURL& currently_committed_url, const GURL& currently_committed_url,
...@@ -107,6 +109,11 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver { ...@@ -107,6 +109,11 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver {
observed_features_->push_back(features); observed_features_->push_back(features);
} }
void OnDidInternalNavigationAbort(
content::NavigationHandle* navigation_handle) override {
observed_aborted_urls_->push_back(navigation_handle->GetURL());
}
private: private:
std::vector<mojom::PageLoadTimingPtr>* const updated_timings_; std::vector<mojom::PageLoadTimingPtr>* const updated_timings_;
std::vector<mojom::PageLoadTimingPtr>* const updated_subframe_timings_; std::vector<mojom::PageLoadTimingPtr>* const updated_subframe_timings_;
...@@ -114,6 +121,7 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver { ...@@ -114,6 +121,7 @@ class TestPageLoadMetricsObserver : public PageLoadMetricsObserver {
std::vector<ExtraRequestCompleteInfo>* const loaded_resources_; std::vector<ExtraRequestCompleteInfo>* const loaded_resources_;
std::vector<mojom::PageLoadFeatures>* const observed_features_; std::vector<mojom::PageLoadFeatures>* const observed_features_;
std::vector<GURL>* const observed_committed_urls_; std::vector<GURL>* const observed_committed_urls_;
std::vector<GURL>* const observed_aborted_urls_;
}; };
// Test PageLoadMetricsObserver that stops observing page loads with certain // Test PageLoadMetricsObserver that stops observing page loads with certain
...@@ -159,7 +167,8 @@ class TestPageLoadMetricsEmbedderInterface ...@@ -159,7 +167,8 @@ class TestPageLoadMetricsEmbedderInterface
void RegisterObservers(PageLoadTracker* tracker) override { void RegisterObservers(PageLoadTracker* tracker) override {
tracker->AddObserver(std::make_unique<TestPageLoadMetricsObserver>( tracker->AddObserver(std::make_unique<TestPageLoadMetricsObserver>(
&updated_timings_, &updated_subframe_timings_, &complete_timings_, &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>( tracker->AddObserver(std::make_unique<FilteringPageLoadMetricsObserver>(
&completed_filtered_urls_)); &completed_filtered_urls_));
} }
...@@ -184,6 +193,10 @@ class TestPageLoadMetricsEmbedderInterface ...@@ -184,6 +193,10 @@ class TestPageLoadMetricsEmbedderInterface
return observed_committed_urls_; return observed_committed_urls_;
} }
const std::vector<GURL>& observed_aborted_urls() const {
return observed_aborted_urls_;
}
const std::vector<mojom::PageLoadFeatures>& observed_features() const { const std::vector<mojom::PageLoadFeatures>& observed_features() const {
return observed_features_; return observed_features_;
} }
...@@ -202,6 +215,7 @@ class TestPageLoadMetricsEmbedderInterface ...@@ -202,6 +215,7 @@ class TestPageLoadMetricsEmbedderInterface
std::vector<mojom::PageLoadTimingPtr> updated_subframe_timings_; std::vector<mojom::PageLoadTimingPtr> updated_subframe_timings_;
std::vector<mojom::PageLoadTimingPtr> complete_timings_; std::vector<mojom::PageLoadTimingPtr> complete_timings_;
std::vector<GURL> observed_committed_urls_; std::vector<GURL> observed_committed_urls_;
std::vector<GURL> observed_aborted_urls_;
std::vector<ExtraRequestCompleteInfo> loaded_resources_; std::vector<ExtraRequestCompleteInfo> loaded_resources_;
std::vector<GURL> completed_filtered_urls_; std::vector<GURL> completed_filtered_urls_;
std::vector<mojom::PageLoadFeatures> observed_features_; std::vector<mojom::PageLoadFeatures> observed_features_;
...@@ -313,6 +327,10 @@ class MetricsWebContentsObserverTest : public ChromeRenderViewHostTestHarness { ...@@ -313,6 +327,10 @@ class MetricsWebContentsObserverTest : public ChromeRenderViewHostTestHarness {
return embedder_interface_->observed_committed_urls_from_on_start(); 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 { const std::vector<mojom::PageLoadFeatures>& observed_features() const {
return embedder_interface_->observed_features(); return embedder_interface_->observed_features();
} }
...@@ -369,6 +387,16 @@ TEST_F(MetricsWebContentsObserverTest, SuccessfulMainFrameNavigation) { ...@@ -369,6 +387,16 @@ TEST_F(MetricsWebContentsObserverTest, SuccessfulMainFrameNavigation) {
CheckNoErrorEvents(); 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) { TEST_F(MetricsWebContentsObserverTest, SubFrame) {
mojom::PageLoadTiming timing; mojom::PageLoadTiming timing;
page_load_metrics::InitPageLoadTimingForTest(&timing); page_load_metrics::InitPageLoadTimingForTest(&timing);
......
...@@ -318,6 +318,13 @@ class PageLoadMetricsObserver { ...@@ -318,6 +318,13 @@ class PageLoadMetricsObserver {
virtual ObservePolicy OnCommit(content::NavigationHandle* navigation_handle, virtual ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
ukm::SourceId source_id); 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 // OnDidFinishSubFrameNavigation is triggered when a sub-frame of the
// committed page has finished navigating. It has either committed, aborted, // committed page has finished navigating. It has either committed, aborted,
// was a same document navigation, or has been replaced. It is up to the // was a same document navigation, or has been replaced. It is up to the
......
...@@ -356,6 +356,13 @@ void PageLoadTracker::DidCommitSameDocumentNavigation( ...@@ -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( void PageLoadTracker::DidFinishSubFrameNavigation(
content::NavigationHandle* navigation_handle) { content::NavigationHandle* navigation_handle) {
for (const auto& observer : observers_) { for (const auto& observer : observers_) {
......
...@@ -189,6 +189,7 @@ class PageLoadTracker : public PageLoadMetricsUpdateDispatcher::Client { ...@@ -189,6 +189,7 @@ class PageLoadTracker : public PageLoadMetricsUpdateDispatcher::Client {
void Commit(content::NavigationHandle* navigation_handle); void Commit(content::NavigationHandle* navigation_handle);
void DidCommitSameDocumentNavigation( void DidCommitSameDocumentNavigation(
content::NavigationHandle* navigation_handle); content::NavigationHandle* navigation_handle);
void DidInternalNavigationAbort(content::NavigationHandle* navigation_handle);
void DidFinishSubFrameNavigation( void DidFinishSubFrameNavigation(
content::NavigationHandle* navigation_handle); content::NavigationHandle* navigation_handle);
void FailedProvisionalLoad(content::NavigationHandle* navigation_handle, void FailedProvisionalLoad(content::NavigationHandle* navigation_handle,
......
...@@ -572,7 +572,9 @@ void NavigationSimulator::AbortCommit() { ...@@ -572,7 +572,9 @@ void NavigationSimulator::AbortCommit() {
CHECK_EQ(1, num_did_finish_navigation_called_); 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 " CHECK_LE(state_, STARTED) << "NavigationSimulator::Fail can only be "
"called once, and cannot be called after " "called once, and cannot be called after "
"NavigationSimulator::ReadyToCommit"; "NavigationSimulator::ReadyToCommit";
...@@ -584,6 +586,10 @@ void NavigationSimulator::Fail(int error_code) { ...@@ -584,6 +586,10 @@ void NavigationSimulator::Fail(int error_code) {
if (state_ == INITIALIZATION) if (state_ == INITIALIZATION)
Start(); Start();
DCHECK(!handle_->GetResponseHeaders());
static_cast<NavigationHandleImpl*>(handle_)->set_response_headers_for_testing(
response_headers);
state_ = FAILED; state_ = FAILED;
PrepareCompleteCallbackOnHandle(); PrepareCompleteCallbackOnHandle();
...@@ -604,6 +610,10 @@ void NavigationSimulator::Fail(int error_code) { ...@@ -604,6 +610,10 @@ void NavigationSimulator::Fail(int error_code) {
std::move(complete_closure).Run(); std::move(complete_closure).Run();
} }
void NavigationSimulator::Fail(int error_code) {
FailWithResponseHeaders(error_code, nullptr);
}
void NavigationSimulator::FailComplete(int error_code) { void NavigationSimulator::FailComplete(int error_code) {
bool should_result_in_error_page = error_code != net::ERR_ABORTED; bool should_result_in_error_page = error_code != net::ERR_ABORTED;
if (error_code != net::ERR_ABORTED) { if (error_code != net::ERR_ABORTED) {
......
...@@ -203,6 +203,12 @@ class NavigationSimulator : public WebContentsObserver { ...@@ -203,6 +203,12 @@ class NavigationSimulator : public WebContentsObserver {
// Simulates the commit of a navigation or an error page aborting. // Simulates the commit of a navigation or an error page aborting.
virtual void AbortCommit(); 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|. // Simulates the navigation failing with the error code |error_code|.
virtual void Fail(int error_code); virtual void Fail(int error_code);
......
...@@ -82,6 +82,13 @@ class WebContentsTester { ...@@ -82,6 +82,13 @@ class WebContentsTester {
// emulates what happens on a new navigation. // emulates what happens on a new navigation.
virtual void NavigateAndCommit(const GURL& url) = 0; 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. // Sets the loading state to the given value.
virtual void TestSetIsLoading(bool value) = 0; virtual void TestSetIsLoading(bool value) = 0;
......
...@@ -119,6 +119,9 @@ class CancellingNavigationSimulatorTest ...@@ -119,6 +119,9 @@ class CancellingNavigationSimulatorTest
void DidFinishNavigation(content::NavigationHandle* handle) override { void DidFinishNavigation(content::NavigationHandle* handle) override {
did_finish_navigation_ = true; did_finish_navigation_ = true;
if (handle->GetResponseHeaders()) {
response_headers_ = handle->GetResponseHeaders()->raw_headers();
}
} }
void OnWillFailRequestCalled() { will_fail_request_called_ = true; } void OnWillFailRequestCalled() { will_fail_request_called_ = true; }
...@@ -128,6 +131,7 @@ class CancellingNavigationSimulatorTest ...@@ -128,6 +131,7 @@ class CancellingNavigationSimulatorTest
std::unique_ptr<NavigationSimulator> simulator_; std::unique_ptr<NavigationSimulator> simulator_;
bool did_finish_navigation_ = false; bool did_finish_navigation_ = false;
bool will_fail_request_called_ = false; bool will_fail_request_called_ = false;
std::string response_headers_;
base::WeakPtrFactory<CancellingNavigationSimulatorTest> weak_ptr_factory_; base::WeakPtrFactory<CancellingNavigationSimulatorTest> weak_ptr_factory_;
private: private:
...@@ -286,6 +290,21 @@ TEST_P(NavigationSimulatorTestCancelFail, Fail) { ...@@ -286,6 +290,21 @@ TEST_P(NavigationSimulatorTestCancelFail, Fail) {
simulator_->GetLastThrottleCheckResult()); 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( INSTANTIATE_TEST_CASE_P(
Fail, Fail,
NavigationSimulatorTestCancelFail, NavigationSimulatorTestCancelFail,
......
...@@ -292,6 +292,15 @@ void TestWebContents::NavigateAndCommit(const GURL& url) { ...@@ -292,6 +292,15 @@ void TestWebContents::NavigateAndCommit(const GURL& url) {
navigation->Commit(); 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) { void TestWebContents::TestSetIsLoading(bool value) {
if (value) { if (value) {
DidStartLoading(GetMainFrame()->frame_tree_node(), true); DidStartLoading(GetMainFrame()->frame_tree_node(), true);
......
...@@ -68,6 +68,10 @@ class TestWebContents : public WebContentsImpl, public WebContentsTester { ...@@ -68,6 +68,10 @@ class TestWebContents : public WebContentsImpl, public WebContentsTester {
void CommitPendingNavigation() override; void CommitPendingNavigation() override;
TestRenderFrameHost* GetPendingMainFrame() override; TestRenderFrameHost* GetPendingMainFrame() override;
void NavigateAndCommit(const GURL& url) 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 TestSetIsLoading(bool value) override;
void TestDidNavigate(RenderFrameHost* render_frame_host, void TestDidNavigate(RenderFrameHost* render_frame_host,
int nav_entry_id, 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