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"
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"
16 using content::BrowserThread
;
17 using predictors::ResourcePrefetchPredictor
;
21 // Enum for measuring statistics pertaining to observed request, responses and
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",
48 void ReportMainFrameRequestStats(MainFrameRequestStats stat
) {
49 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.MainFrameRequestStats",
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
);
59 ReportRequestStats(REQUEST_STATS_NO_RESOURCE_REQUEST_INFO
);
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
);
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(
84 summary
->resource_type
);
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
,
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
))
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(
128 base::Bind(&ResourcePrefetchPredictor::RecordURLRequest
,
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
);
144 request_info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
) {
145 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_REDIRECTS
);
148 if (!ResourcePrefetchPredictor::ShouldRecordRedirect(request
))
151 ResourcePrefetchPredictor::URLRequestSummary summary
;
152 if (!SummarizeResponse(request
, &summary
))
155 summary
.redirect_url
= redirect_url
;
157 BrowserThread::PostTask(
160 base::Bind(&ResourcePrefetchPredictor::RecordURLRedirect
,
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
);
179 request_info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
) {
180 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_RESPONSES
);
183 if (!ResourcePrefetchPredictor::ShouldRecordResponse(request
))
185 ResourcePrefetchPredictor::URLRequestSummary summary
;
186 if (!SummarizeResponse(request
, &summary
))
189 BrowserThread::PostTask(
192 base::Bind(&ResourcePrefetchPredictor::RecordURLResponse
,
196 ReportRequestStats(REQUEST_STATS_TOTAL_PROCESSED_RESPONSES
);
198 request_info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
) {
199 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_RESPONSES
);
203 } // namespace chrome_browser_net