Commit 80cf9541 authored by bmcquade's avatar bmcquade Committed by Commit bot

Add common page filtering logic for page load metrics.

BUG=
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_site_isolation

Review-Url: https://codereview.chromium.org/2331053003
Cr-Commit-Position: refs/heads/master@{#419467}
parent 7c4bbe1f
......@@ -670,6 +670,8 @@ split_static_library("browser") {
"ntp_snippets/bookmark_last_visit_updater.h",
"ntp_snippets/content_suggestions_service_factory.cc",
"ntp_snippets/content_suggestions_service_factory.h",
"page_load_metrics/browser_page_track_decider.cc",
"page_load_metrics/browser_page_track_decider.h",
"page_load_metrics/metrics_navigation_throttle.cc",
"page_load_metrics/metrics_navigation_throttle.h",
"page_load_metrics/metrics_web_contents_observer.cc",
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/page_load_metrics/browser_page_track_decider.h"
#include <string>
#include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "net/http/http_response_headers.h"
namespace page_load_metrics {
BrowserPageTrackDecider::BrowserPageTrackDecider(
PageLoadMetricsEmbedderInterface* embedder_interface,
content::WebContents* web_contents,
content::NavigationHandle* navigation_handle)
: embedder_interface_(embedder_interface),
web_contents_(web_contents),
navigation_handle_(navigation_handle) {}
BrowserPageTrackDecider::~BrowserPageTrackDecider() {}
bool BrowserPageTrackDecider::HasCommitted() {
return navigation_handle_->HasCommitted();
}
bool BrowserPageTrackDecider::IsHttpOrHttpsUrl() {
return navigation_handle_->GetURL().SchemeIsHTTPOrHTTPS();
}
bool BrowserPageTrackDecider::IsNewTabPageUrl() {
return embedder_interface_->IsNewTabPageUrl(navigation_handle_->GetURL());
}
bool BrowserPageTrackDecider::IsChromeErrorPage() {
DCHECK(HasCommitted());
return navigation_handle_->IsErrorPage();
}
int BrowserPageTrackDecider::GetHttpStatusCode() {
DCHECK(HasCommitted());
const net::HttpResponseHeaders* response_headers =
navigation_handle_->GetResponseHeaders();
if (!response_headers)
return -1;
return response_headers->response_code();
}
bool BrowserPageTrackDecider::IsHtmlOrXhtmlPage() {
DCHECK(HasCommitted());
const std::string& mime_type = web_contents_->GetContentsMimeType();
return mime_type == "text/html" || mime_type == "application/xhtml+xml";
}
} // namespace page_load_metrics
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_BROWSER_PAGE_TRACK_DECIDER_H_
#define CHROME_BROWSER_PAGE_LOAD_METRICS_BROWSER_PAGE_TRACK_DECIDER_H_
#include "base/macros.h"
#include "chrome/common/page_load_metrics/page_track_decider.h"
namespace content {
class NavigationHandle;
class WebContents;
} // namespace content
namespace page_load_metrics {
class PageLoadMetricsEmbedderInterface;
class BrowserPageTrackDecider : public PageTrackDecider {
public:
// embedder_interface, web_contents, and navigation_handle are not owned by
// BrowserPageTrackDecider, and must outlive the
// BrowserPageTrackDecider.
BrowserPageTrackDecider(PageLoadMetricsEmbedderInterface* embedder_interface,
content::WebContents* web_contents,
content::NavigationHandle* navigation_handle);
~BrowserPageTrackDecider() override;
bool HasCommitted() override;
bool IsHttpOrHttpsUrl() override;
bool IsNewTabPageUrl() override;
bool IsChromeErrorPage() override;
bool IsHtmlOrXhtmlPage() override;
int GetHttpStatusCode() override;
private:
PageLoadMetricsEmbedderInterface* const embedder_interface_;
content::WebContents* const web_contents_;
content::NavigationHandle* const navigation_handle_;
DISALLOW_COPY_AND_ASSIGN(BrowserPageTrackDecider);
};
} // namespace page_load_metrics
#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_BROWSER_PAGE_TRACK_DECIDER_H_
......@@ -14,6 +14,7 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "chrome/browser/page_load_metrics/browser_page_track_decider.h"
#include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
#include "chrome/common/page_load_metrics/page_load_metrics_messages.h"
#include "chrome/common/page_load_metrics/page_load_timing.h"
......@@ -819,6 +820,13 @@ void MetricsWebContentsObserver::DidFinishNavigation(
std::move(provisional_loads_[navigation_handle]));
provisional_loads_.erase(navigation_handle);
// Ignore same-page navigations.
if (navigation_handle->HasCommitted() && navigation_handle->IsSamePage()) {
if (finished_nav)
finished_nav->StopTracking();
return;
}
const bool should_track =
finished_nav && ShouldTrackNavigation(navigation_handle);
......@@ -826,10 +834,6 @@ void MetricsWebContentsObserver::DidFinishNavigation(
finished_nav->StopTracking();
if (navigation_handle->HasCommitted()) {
// Ignore same-page navigations.
if (navigation_handle->IsSamePage())
return;
// Notify other loads that they may have been aborted by this committed
// load. is_certainly_browser_timestamp is set to false because
// NavigationStart() could be set in either the renderer or browser process.
......@@ -1061,18 +1065,11 @@ void MetricsWebContentsObserver::OnTimingUpdated(
bool MetricsWebContentsObserver::ShouldTrackNavigation(
content::NavigationHandle* navigation_handle) const {
DCHECK(navigation_handle->IsInMainFrame());
if (!navigation_handle->GetURL().SchemeIsHTTPOrHTTPS())
return false;
if (embedder_interface_->IsNewTabPageUrl(navigation_handle->GetURL()))
return false;
if (navigation_handle->HasCommitted()) {
if (navigation_handle->IsSamePage() || navigation_handle->IsErrorPage())
return false;
const std::string& mime_type = web_contents()->GetContentsMimeType();
if (mime_type != "text/html" && mime_type != "application/xhtml+xml")
return false;
}
return true;
DCHECK(!navigation_handle->HasCommitted() ||
!navigation_handle->IsSamePage());
return BrowserPageTrackDecider(embedder_interface_.get(), web_contents(),
navigation_handle).ShouldTrack();
}
} // namespace page_load_metrics
......@@ -99,6 +99,8 @@ static_library("common") {
"page_load_metrics/page_load_metrics_messages.h",
"page_load_metrics/page_load_timing.cc",
"page_load_metrics/page_load_timing.h",
"page_load_metrics/page_track_decider.cc",
"page_load_metrics/page_track_decider.h",
"partial_circular_buffer.cc",
"partial_circular_buffer.h",
"pref_names_util.cc",
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/page_load_metrics/page_track_decider.h"
namespace page_load_metrics {
PageTrackDecider::PageTrackDecider() {}
PageTrackDecider::~PageTrackDecider() {}
bool PageTrackDecider::ShouldTrack() {
// Ignore non-HTTP schemes (e.g. chrome://).
if (!IsHttpOrHttpsUrl())
return false;
// Ignore NTP loads.
if (IsNewTabPageUrl())
return false;
if (HasCommitted()) {
// Ignore Chrome error pages (e.g. No Internet connection).
if (IsChromeErrorPage())
return false;
// Ignore non-HTML documents (e.g. SVG, images).
if (!IsHtmlOrXhtmlPage())
return false;
// Ignore network error pages (e.g. 4xx, 5xx).
int http_status_code = GetHttpStatusCode();
if (http_status_code > 0 &&
(http_status_code < 200 || http_status_code >= 400))
return false;
}
return true;
}
} // namespace page_load_metrics
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_COMMON_PAGE_LOAD_METRICS_PAGE_TRACK_DECIDER_H_
#define CHROME_COMMON_PAGE_LOAD_METRICS_PAGE_TRACK_DECIDER_H_
#include "base/macros.h"
namespace page_load_metrics {
// PageTrackDecider is an interface used to determine whether metrics should be
// tracked for a given page. This class is used by the core page load metrics
// tracking infrastructure in both the browser and render processes so policy
// decisions about which page loads to track are consistent across processes.
class PageTrackDecider {
public:
PageTrackDecider();
virtual ~PageTrackDecider();
// Whether metrics should be tracked for the current page. This method invokes
// the pure virtual methods below to decide whether metrics should be tracked.
bool ShouldTrack();
// Whether the navigation for the current page has committed.
virtual bool HasCommitted() = 0;
// Whether the current page's URL is HTTP or HTTPS. Note that the page does
// not need to have committed, nor does the URL or hostname of the URL need to
// point at a valid web page or host, for this method to return true.
virtual bool IsHttpOrHttpsUrl() = 0;
// Whether the current page's URL is for a Chrome new tab page. Note that in
// some cases the new tab page is served over the network via https.
virtual bool IsNewTabPageUrl() = 0;
// The methods below can only be called if HasCommitted() returns true.
// Whether the current page is a Chrome-generated error page. Example error
// pages include pages displayed after a network error that did not result in
// receiving an HTTP/HTTPS response, such as the 'There is no Internet
// connection' page, which is displayed when the user attempts to navigate
// without an Internet connection. This method returns false for non-Chrome
// generated error pages, such as pages with 4xx/5xx response codes. To
// check whether the current page resulted in a 4xx/5xx error, use
// IsHTTPErrorPage() instead.
virtual bool IsChromeErrorPage() = 0;
// Returns the HTTP status code for the current page, or -1 if no status code
// is available.
virtual int GetHttpStatusCode() = 0;
// Whether the current page is an HTML or XHTML page.
virtual bool IsHtmlOrXhtmlPage() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(PageTrackDecider);
};
} // namespace page_load_metrics
#endif // CHROME_COMMON_PAGE_LOAD_METRICS_PAGE_TRACK_DECIDER_H_
......@@ -56,6 +56,8 @@ static_library("renderer") {
"page_load_metrics/metrics_render_frame_observer.h",
"page_load_metrics/page_timing_metrics_sender.cc",
"page_load_metrics/page_timing_metrics_sender.h",
"page_load_metrics/renderer_page_track_decider.cc",
"page_load_metrics/renderer_page_track_decider.h",
"plugins/non_loadable_plugin_placeholder.cc",
"plugins/non_loadable_plugin_placeholder.h",
"plugins/plugin_uma.cc",
......
......@@ -10,9 +10,9 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/renderer/page_load_metrics/page_timing_metrics_sender.h"
#include "chrome/renderer/page_load_metrics/renderer_page_track_decider.h"
#include "chrome/renderer/searchbox/search_bouncer.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebDataSource.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
......@@ -86,33 +86,12 @@ bool MetricsRenderFrameObserver::ShouldSendMetrics() const {
if (HasNoRenderFrame())
return false;
const blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
// We only generate historgrams for main frames.
// We only track metrics for main frames.
if (frame->parent())
return false;
const blink::WebDocument& document = frame->document();
// Ignore non-HTTP schemes (e.g. chrome://).
const GURL& url = document.url();
if (!url.SchemeIsHTTPOrHTTPS())
return false;
// Ignore NTP loads.
if (SearchBouncer::GetInstance()->IsNewTabPage(url))
return false;
// Ignore non-HTML documents (e.g. SVG). Note that images are treated by
// Blink as HTML documents, so to exclude images, we must perform
// additional mime type checking below.
if (!document.isHTMLDocument() && !document.isXHTMLDocument())
return false;
// Ignore non-HTML mime types (e.g. images).
const blink::WebURLResponse& url_response = frame->dataSource()->response();
std::string mime_type = url_response.mimeType().utf8();
if (mime_type != "text/html" && mime_type != "application/xhtml+xml")
return false;
return true;
return RendererPageTrackDecider(&document, frame->dataSource()).ShouldTrack();
}
PageLoadTiming MetricsRenderFrameObserver::GetTiming() const {
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/page_load_metrics/renderer_page_track_decider.h"
#include <string>
#include "chrome/renderer/searchbox/search_bouncer.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebDataSource.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "url/gurl.h"
namespace page_load_metrics {
RendererPageTrackDecider::RendererPageTrackDecider(
const blink::WebDocument* document,
const blink::WebDataSource* data_source)
: document_(document), data_source_(data_source) {}
RendererPageTrackDecider::~RendererPageTrackDecider() {}
bool RendererPageTrackDecider::HasCommitted() {
// RendererPageTrackDecider is only instantiated for committed pages.
return true;
}
bool RendererPageTrackDecider::IsHttpOrHttpsUrl() {
return static_cast<GURL>(document_->url()).SchemeIsHTTPOrHTTPS();
}
bool RendererPageTrackDecider::IsNewTabPageUrl() {
return SearchBouncer::GetInstance()->IsNewTabPage(document_->url());
}
bool RendererPageTrackDecider::IsChromeErrorPage() {
return data_source_->hasUnreachableURL();
}
int RendererPageTrackDecider::GetHttpStatusCode() {
return data_source_->response().httpStatusCode();
}
bool RendererPageTrackDecider::IsHtmlOrXhtmlPage() {
// Ignore non-HTML documents (e.g. SVG). Note that images are treated by
// Blink as HTML documents, so to exclude images, we must perform
// additional mime type checking below.
if (!document_->isHTMLDocument() && !document_->isXHTMLDocument())
return false;
// Ignore non-HTML mime types (e.g. images).
blink::WebString mime_type = data_source_->response().mimeType();
return mime_type == "text/html" || mime_type == "application/xhtml+xml";
}
} // namespace page_load_metrics
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_RENDERER_PAGE_LOAD_METRICS_RENDERER_PAGE_TRACK_DECIDER_H_
#define CHROME_RENDERER_PAGE_LOAD_METRICS_RENDERER_PAGE_TRACK_DECIDER_H_
#include "base/macros.h"
#include "chrome/common/page_load_metrics/page_track_decider.h"
namespace blink {
class WebDocument;
class WebDataSource;
} // namespace blink
namespace page_load_metrics {
class RendererPageTrackDecider : public PageTrackDecider {
public:
// document and data_source are not owned by RendererPageTrackDecider,
// and must outlive the RendererPageTrackDecider.
RendererPageTrackDecider(const blink::WebDocument* document,
const blink::WebDataSource* data_source);
~RendererPageTrackDecider() override;
bool HasCommitted() override;
bool IsHttpOrHttpsUrl() override;
bool IsNewTabPageUrl() override;
bool IsChromeErrorPage() override;
bool IsHtmlOrXhtmlPage() override;
int GetHttpStatusCode() override;
private:
const blink::WebDocument* const document_;
const blink::WebDataSource* const data_source_;
DISALLOW_COPY_AND_ASSIGN(RendererPageTrackDecider);
};
} // namespace page_load_metrics
#endif // CHROME_RENDERER_PAGE_LOAD_METRICS_RENDERER_PAGE_TRACK_DECIDER_H_
<html>
<body>
I am a 404 page!
</body>
</html>
HTTP/1.0 404 Not Found
Content-type: text/html
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