Popular sites on the NTP: re-download popular suggestions once per Chrome run
[chromium-blink-merge.git] / chrome / browser / net / resource_prefetch_predictor_observer.cc
blob81d9b07ff98f3ddeee536cdbf1f3eecb45b314b5
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/net/resource_prefetch_predictor_observer.h"
7 #include <string>
9 #include "base/metrics/histogram.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/resource_request_info.h"
13 #include "net/url_request/url_request.h"
14 #include "url/gurl.h"
16 using content::BrowserThread;
17 using predictors::ResourcePrefetchPredictor;
19 namespace {
21 // Enum for measuring statistics pertaining to observed request, responses and
22 // redirects.
23 enum RequestStats {
24 REQUEST_STATS_TOTAL_RESPONSES = 0,
25 REQUEST_STATS_TOTAL_PROCESSED_RESPONSES = 1,
26 REQUEST_STATS_NO_RESOURCE_REQUEST_INFO = 2,
27 REQUEST_STATS_NO_RENDER_FRAME_ID_FROM_REQUEST_INFO = 3,
28 REQUEST_STATS_MAX = 4,
31 // Specific to main frame requests.
32 enum MainFrameRequestStats {
33 MAIN_FRAME_REQUEST_STATS_TOTAL_REQUESTS = 0,
34 MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS = 1,
35 MAIN_FRAME_REQUEST_STATS_TOTAL_REDIRECTS = 2,
36 MAIN_FRAME_REQUEST_STATS_PROCESSED_REDIRECTS = 3,
37 MAIN_FRAME_REQUEST_STATS_TOTAL_RESPONSES = 4,
38 MAIN_FRAME_REQUEST_STATS_PROCESSED_RESPONSES = 5,
39 MAIN_FRAME_REQUEST_STATS_MAX = 6,
42 void ReportRequestStats(RequestStats stat) {
43 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.RequestStats",
44 stat,
45 REQUEST_STATS_MAX);
48 void ReportMainFrameRequestStats(MainFrameRequestStats stat) {
49 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.MainFrameRequestStats",
50 stat,
51 MAIN_FRAME_REQUEST_STATS_MAX);
54 bool SummarizeResponse(net::URLRequest* request,
55 ResourcePrefetchPredictor::URLRequestSummary* summary) {
56 const content::ResourceRequestInfo* info =
57 content::ResourceRequestInfo::ForRequest(request);
58 if (!info) {
59 ReportRequestStats(REQUEST_STATS_NO_RESOURCE_REQUEST_INFO);
60 return false;
63 int render_process_id, render_frame_id;
64 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) {
65 ReportRequestStats(REQUEST_STATS_NO_RENDER_FRAME_ID_FROM_REQUEST_INFO);
66 return false;
69 summary->navigation_id.render_process_id = render_process_id;
70 summary->navigation_id.render_frame_id = render_frame_id;
71 summary->navigation_id.main_frame_url = request->first_party_for_cookies();
72 summary->navigation_id.creation_time = request->creation_time();
73 summary->resource_url = request->original_url();
74 summary->resource_type = info->GetResourceType();
75 request->GetMimeType(&summary->mime_type);
76 summary->was_cached = request->was_cached();
78 // Use the mime_type to determine the resource type for subresources since
79 // types such as PREFETCH, SUB_RESOURCE, etc are not useful.
80 if (summary->resource_type != content::RESOURCE_TYPE_MAIN_FRAME) {
81 summary->resource_type =
82 ResourcePrefetchPredictor::GetResourceTypeFromMimeType(
83 summary->mime_type,
84 summary->resource_type);
86 return true;
89 } // namespace
91 namespace chrome_browser_net {
93 ResourcePrefetchPredictorObserver::ResourcePrefetchPredictorObserver(
94 ResourcePrefetchPredictor* predictor)
95 : predictor_(predictor->AsWeakPtr()) {
96 DCHECK_CURRENTLY_ON(BrowserThread::UI);
99 ResourcePrefetchPredictorObserver::~ResourcePrefetchPredictorObserver() {
100 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
101 BrowserThread::CurrentlyOn(BrowserThread::IO));
104 void ResourcePrefetchPredictorObserver::OnRequestStarted(
105 net::URLRequest* request,
106 content::ResourceType resource_type,
107 int child_id,
108 int frame_id) {
109 DCHECK_CURRENTLY_ON(BrowserThread::IO);
111 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
112 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_REQUESTS);
114 if (!ResourcePrefetchPredictor::ShouldRecordRequest(request, resource_type))
115 return;
117 ResourcePrefetchPredictor::URLRequestSummary summary;
118 summary.navigation_id.render_process_id = child_id;
119 summary.navigation_id.render_frame_id = frame_id;
120 summary.navigation_id.main_frame_url = request->first_party_for_cookies();
121 summary.navigation_id.creation_time = request->creation_time();
122 summary.resource_url = request->original_url();
123 summary.resource_type = resource_type;
125 BrowserThread::PostTask(
126 BrowserThread::UI,
127 FROM_HERE,
128 base::Bind(&ResourcePrefetchPredictor::RecordURLRequest,
129 predictor_,
130 summary));
132 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
133 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS);
136 void ResourcePrefetchPredictorObserver::OnRequestRedirected(
137 const GURL& redirect_url,
138 net::URLRequest* request) {
139 DCHECK_CURRENTLY_ON(BrowserThread::IO);
141 const content::ResourceRequestInfo* request_info =
142 content::ResourceRequestInfo::ForRequest(request);
143 if (request_info &&
144 request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME) {
145 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_REDIRECTS);
148 if (!ResourcePrefetchPredictor::ShouldRecordRedirect(request))
149 return;
151 ResourcePrefetchPredictor::URLRequestSummary summary;
152 if (!SummarizeResponse(request, &summary))
153 return;
155 summary.redirect_url = redirect_url;
157 BrowserThread::PostTask(
158 BrowserThread::UI,
159 FROM_HERE,
160 base::Bind(&ResourcePrefetchPredictor::RecordURLRedirect,
161 predictor_,
162 summary));
164 if (request_info &&
165 request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME) {
166 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_REDIRECTS);
170 void ResourcePrefetchPredictorObserver::OnResponseStarted(
171 net::URLRequest* request) {
172 DCHECK_CURRENTLY_ON(BrowserThread::IO);
174 ReportRequestStats(REQUEST_STATS_TOTAL_RESPONSES);
176 const content::ResourceRequestInfo* request_info =
177 content::ResourceRequestInfo::ForRequest(request);
178 if (request_info &&
179 request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME) {
180 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_RESPONSES);
183 if (!ResourcePrefetchPredictor::ShouldRecordResponse(request))
184 return;
185 ResourcePrefetchPredictor::URLRequestSummary summary;
186 if (!SummarizeResponse(request, &summary))
187 return;
189 BrowserThread::PostTask(
190 BrowserThread::UI,
191 FROM_HERE,
192 base::Bind(&ResourcePrefetchPredictor::RecordURLResponse,
193 predictor_,
194 summary));
196 ReportRequestStats(REQUEST_STATS_TOTAL_PROCESSED_RESPONSES);
197 if (request_info &&
198 request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME) {
199 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_RESPONSES);
203 } // namespace chrome_browser_net