OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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. | |
4 | |
5 #include "chrome/browser/net/resource_prefetch_predictor_observer.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/metrics/histogram.h" | |
10 #include "content/public/browser/browser_thread.h" | |
11 #include "content/public/browser/resource_request_info.h" | |
12 #include "net/url_request/url_request.h" | |
13 #include "url/gurl.h" | |
14 | |
15 using content::BrowserThread; | |
16 using predictors::ResourcePrefetchPredictor; | |
17 | |
18 namespace { | |
19 | |
20 // Enum for measuring statistics pertaining to observed request, responses and | |
21 // redirects. | |
22 enum RequestStats { | |
23 REQUEST_STATS_TOTAL_RESPONSES = 0, | |
24 REQUEST_STATS_TOTAL_PROCESSED_RESPONSES = 1, | |
25 REQUEST_STATS_NO_RESOURCE_REQUEST_INFO = 2, | |
26 REQUEST_STATS_NO_RENDER_VIEW_ID_FROM_REQUEST_INFO = 3, | |
27 REQUEST_STATS_MAX = 4, | |
28 }; | |
29 | |
30 // Specific to main frame requests. | |
31 enum MainFrameRequestStats { | |
32 MAIN_FRAME_REQUEST_STATS_TOTAL_REQUESTS = 0, | |
33 MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS = 1, | |
34 MAIN_FRAME_REQUEST_STATS_TOTAL_REDIRECTS = 2, | |
35 MAIN_FRAME_REQUEST_STATS_PROCESSED_REDIRECTS = 3, | |
36 MAIN_FRAME_REQUEST_STATS_TOTAL_RESPONSES = 4, | |
37 MAIN_FRAME_REQUEST_STATS_PROCESSED_RESPONSES = 5, | |
38 MAIN_FRAME_REQUEST_STATS_MAX = 6, | |
39 }; | |
40 | |
41 void ReportRequestStats(RequestStats stat) { | |
42 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.RequestStats", | |
43 stat, | |
44 REQUEST_STATS_MAX); | |
45 } | |
46 | |
47 void ReportMainFrameRequestStats(MainFrameRequestStats stat) { | |
48 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.MainFrameRequestStats", | |
49 stat, | |
50 MAIN_FRAME_REQUEST_STATS_MAX); | |
51 } | |
52 | |
53 bool SummarizeResponse(net::URLRequest* request, | |
54 ResourcePrefetchPredictor::URLRequestSummary* summary) { | |
55 const content::ResourceRequestInfo* info = | |
56 content::ResourceRequestInfo::ForRequest(request); | |
57 if (!info) { | |
58 ReportRequestStats(REQUEST_STATS_NO_RESOURCE_REQUEST_INFO); | |
59 return false; | |
60 } | |
61 | |
62 int render_process_id, render_view_id; | |
63 if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id)) { | |
64 ReportRequestStats(REQUEST_STATS_NO_RENDER_VIEW_ID_FROM_REQUEST_INFO); | |
65 return false; | |
66 } | |
67 | |
68 summary->navigation_id.render_process_id = render_process_id; | |
69 summary->navigation_id.render_view_id = render_view_id; | |
70 summary->navigation_id.main_frame_url = request->first_party_for_cookies(); | |
71 summary->navigation_id.creation_time = request->creation_time(); | |
72 summary->resource_url = request->original_url(); | |
73 summary->resource_type = info->GetResourceType(); | |
74 request->GetMimeType(&summary->mime_type); | |
75 summary->was_cached = request->was_cached(); | |
76 | |
77 // Use the mime_type to determine the resource type for subresources since | |
78 // types such as PREFETCH, SUB_RESOURCE, etc are not useful. | |
79 if (summary->resource_type != ResourceType::MAIN_FRAME) { | |
80 summary->resource_type = | |
81 ResourcePrefetchPredictor::GetResourceTypeFromMimeType( | |
82 summary->mime_type, | |
83 summary->resource_type); | |
84 } | |
85 return true; | |
86 } | |
87 | |
88 } // namespace | |
89 | |
90 namespace chrome_browser_net { | |
91 | |
92 ResourcePrefetchPredictorObserver::ResourcePrefetchPredictorObserver( | |
93 ResourcePrefetchPredictor* predictor) | |
94 : predictor_(predictor->AsWeakPtr()) { | |
95 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
96 } | |
97 | |
98 ResourcePrefetchPredictorObserver::~ResourcePrefetchPredictorObserver() { | |
99 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | |
100 BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
101 } | |
102 | |
103 void ResourcePrefetchPredictorObserver::OnRequestStarted( | |
104 net::URLRequest* request, | |
105 ResourceType::Type resource_type, | |
106 int child_id, | |
107 int route_id) { | |
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
109 | |
110 if (resource_type == ResourceType::MAIN_FRAME) | |
111 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_REQUESTS); | |
112 | |
113 if (!ResourcePrefetchPredictor::ShouldRecordRequest(request, resource_type)) | |
114 return; | |
115 | |
116 ResourcePrefetchPredictor::URLRequestSummary summary; | |
117 summary.navigation_id.render_process_id = child_id; | |
118 summary.navigation_id.render_view_id = route_id; | |
119 summary.navigation_id.main_frame_url = request->first_party_for_cookies(); | |
120 summary.resource_url = request->original_url(); | |
121 summary.resource_type = resource_type; | |
122 | |
123 BrowserThread::PostTask( | |
124 BrowserThread::UI, | |
125 FROM_HERE, | |
126 base::Bind(&ResourcePrefetchPredictor::RecordURLRequest, | |
127 predictor_, | |
128 summary)); | |
129 | |
130 if (resource_type == ResourceType::MAIN_FRAME) | |
131 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS); | |
132 } | |
133 | |
134 void ResourcePrefetchPredictorObserver::OnRequestRedirected( | |
135 const GURL& redirect_url, | |
136 net::URLRequest* request) { | |
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
138 | |
139 const content::ResourceRequestInfo* request_info = | |
140 content::ResourceRequestInfo::ForRequest(request); | |
141 if (request_info && | |
142 request_info->GetResourceType() == ResourceType::MAIN_FRAME) { | |
143 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_REDIRECTS); | |
144 } | |
145 | |
146 if (!ResourcePrefetchPredictor::ShouldRecordRedirect(request)) | |
147 return; | |
148 | |
149 ResourcePrefetchPredictor::URLRequestSummary summary; | |
150 if (!SummarizeResponse(request, &summary)) | |
151 return; | |
152 | |
153 summary.redirect_url = redirect_url; | |
154 | |
155 BrowserThread::PostTask( | |
156 BrowserThread::UI, | |
157 FROM_HERE, | |
158 base::Bind(&ResourcePrefetchPredictor::RecordURLRedirect, | |
159 predictor_, | |
160 summary)); | |
161 | |
162 if (request_info && | |
163 request_info->GetResourceType() == ResourceType::MAIN_FRAME) { | |
164 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_REDIRECTS); | |
165 } | |
166 } | |
167 | |
168 void ResourcePrefetchPredictorObserver::OnResponseStarted( | |
169 net::URLRequest* request) { | |
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
171 | |
172 ReportRequestStats(REQUEST_STATS_TOTAL_RESPONSES); | |
173 | |
174 const content::ResourceRequestInfo* request_info = | |
175 content::ResourceRequestInfo::ForRequest(request); | |
176 if (request_info && | |
177 request_info->GetResourceType() == ResourceType::MAIN_FRAME) { | |
178 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_TOTAL_RESPONSES); | |
179 } | |
180 | |
181 if (!ResourcePrefetchPredictor::ShouldRecordResponse(request)) | |
182 return; | |
183 ResourcePrefetchPredictor::URLRequestSummary summary; | |
184 if (!SummarizeResponse(request, &summary)) | |
185 return; | |
186 | |
187 BrowserThread::PostTask( | |
188 BrowserThread::UI, | |
189 FROM_HERE, | |
190 base::Bind(&ResourcePrefetchPredictor::RecordURLResponse, | |
191 predictor_, | |
192 summary)); | |
193 | |
194 ReportRequestStats(REQUEST_STATS_TOTAL_PROCESSED_RESPONSES); | |
195 if (request_info && | |
196 request_info->GetResourceType() == ResourceType::MAIN_FRAME) { | |
197 ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_RESPONSES); | |
198 } | |
199 } | |
200 | |
201 } // namespace chrome_browser_net | |
OLD | NEW |