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
.resource_url
= request
->original_url();
122 summary
.resource_type
= resource_type
;
124 BrowserThread::PostTask(
127 base::Bind(&ResourcePrefetchPredictor::RecordURLRequest
,
131 if (resource_type
== content::RESOURCE_TYPE_MAIN_FRAME
)
132 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS
);
135 void ResourcePrefetchPredictorObserver::OnRequestRedirected(
136 const GURL
& redirect_url
,
137 net::URLRequest
* request
) {
138 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
140 const content::ResourceRequestInfo
* request_info
=
141 content::ResourceRequestInfo::ForRequest(request
);
143 request_info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
) {
144 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_REDIRECTS
);
147 if (!ResourcePrefetchPredictor::ShouldRecordRedirect(request
))
150 ResourcePrefetchPredictor::URLRequestSummary summary
;
151 if (!SummarizeResponse(request
, &summary
))
154 summary
.redirect_url
= redirect_url
;
156 BrowserThread::PostTask(
159 base::Bind(&ResourcePrefetchPredictor::RecordURLRedirect
,
164 request_info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
) {
165 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_REDIRECTS
);
169 void ResourcePrefetchPredictorObserver::OnResponseStarted(
170 net::URLRequest
* request
) {
171 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
173 ReportRequestStats(REQUEST_STATS_TOTAL_RESPONSES
);
175 const content::ResourceRequestInfo
* request_info
=
176 content::ResourceRequestInfo::ForRequest(request
);
178 request_info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
) {
179 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_RESPONSES
);
182 if (!ResourcePrefetchPredictor::ShouldRecordResponse(request
))
184 ResourcePrefetchPredictor::URLRequestSummary summary
;
185 if (!SummarizeResponse(request
, &summary
))
188 BrowserThread::PostTask(
191 base::Bind(&ResourcePrefetchPredictor::RecordURLResponse
,
195 ReportRequestStats(REQUEST_STATS_TOTAL_PROCESSED_RESPONSES
);
197 request_info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
) {
198 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_RESPONSES
);
202 } // namespace chrome_browser_net