Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(731)

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor.cc

Issue 2184323003: predictors: Support fonts in resource_prefetch_predictors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove exit-time destructors. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h"
6 6
7 #include <algorithm>
7 #include <map> 8 #include <map>
8 #include <set> 9 #include <set>
9 #include <utility> 10 #include <utility>
10 11
11 #include "base/command_line.h" 12 #include "base/command_line.h"
12 #include "base/macros.h" 13 #include "base/macros.h"
13 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
14 #include "base/metrics/sparse_histogram.h" 15 #include "base/metrics/sparse_histogram.h"
15 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
(...skipping 16 matching lines...) Expand all
33 #include "net/base/mime_util.h" 34 #include "net/base/mime_util.h"
34 #include "net/base/network_change_notifier.h" 35 #include "net/base/network_change_notifier.h"
35 #include "net/http/http_response_headers.h" 36 #include "net/http/http_response_headers.h"
36 #include "net/url_request/url_request.h" 37 #include "net/url_request/url_request.h"
37 #include "net/url_request/url_request_context_getter.h" 38 #include "net/url_request/url_request_context_getter.h"
38 39
39 using content::BrowserThread; 40 using content::BrowserThread;
40 41
41 namespace { 42 namespace {
42 43
44 // Sorted by decreasing likelihood according to HTTP archive.
45 const char* kFontMimeTypes[] = {"font/woff2",
46 "application/x-font-woff",
47 "application/font-woff",
48 "application/font-woff2",
49 "font/x-woff",
50 "application/x-font-ttf",
51 "font/woff",
52 "font/ttf",
53 "application/x-font-otf",
54 "x-font/woff",
55 "application/font-sfnt",
56 "application/font-ttf"};
57
43 // For reporting whether a subresource is handled or not, and for what reasons. 58 // For reporting whether a subresource is handled or not, and for what reasons.
44 enum ResourceStatus { 59 enum ResourceStatus {
45 RESOURCE_STATUS_HANDLED = 0, 60 RESOURCE_STATUS_HANDLED = 0,
46 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE = 1, 61 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE = 1,
47 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE = 2, 62 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE = 2,
48 RESOURCE_STATUS_UNSUPPORTED_MIME_TYPE = 4, 63 RESOURCE_STATUS_UNSUPPORTED_RESOURCE_TYPE = 4,
49 RESOURCE_STATUS_NOT_GET = 8, 64 RESOURCE_STATUS_NOT_GET = 8,
50 RESOURCE_STATUS_URL_TOO_LONG = 16, 65 RESOURCE_STATUS_URL_TOO_LONG = 16,
51 RESOURCE_STATUS_NOT_CACHEABLE = 32, 66 RESOURCE_STATUS_NOT_CACHEABLE = 32,
52 RESOURCE_STATUS_HEADERS_MISSING = 64, 67 RESOURCE_STATUS_HEADERS_MISSING = 64,
53 RESOURCE_STATUS_MAX = 128, 68 RESOURCE_STATUS_MAX = 128,
54 }; 69 };
55 70
56 // For reporting various interesting events that occur during the loading of a 71 // For reporting various interesting events that occur during the loading of a
57 // single main frame. 72 // single main frame.
58 enum NavigationEvent { 73 enum NavigationEvent {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 bool ResourcePrefetchPredictor::ShouldRecordResponse( 219 bool ResourcePrefetchPredictor::ShouldRecordResponse(
205 net::URLRequest* response) { 220 net::URLRequest* response) {
206 const content::ResourceRequestInfo* request_info = 221 const content::ResourceRequestInfo* request_info =
207 content::ResourceRequestInfo::ForRequest(response); 222 content::ResourceRequestInfo::ForRequest(response);
208 if (!request_info) 223 if (!request_info)
209 return false; 224 return false;
210 225
211 if (!request_info->IsMainFrame()) 226 if (!request_info->IsMainFrame())
212 return false; 227 return false;
213 228
214 return request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME ? 229 content::ResourceType resource_type = request_info->GetResourceType();
215 IsHandledMainPage(response) : IsHandledSubresource(response); 230 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME
231 ? IsHandledMainPage(response)
232 : IsHandledSubresource(response, resource_type);
216 } 233 }
217 234
218 // static 235 // static
219 bool ResourcePrefetchPredictor::ShouldRecordRedirect( 236 bool ResourcePrefetchPredictor::ShouldRecordRedirect(
220 net::URLRequest* response) { 237 net::URLRequest* response) {
221 const content::ResourceRequestInfo* request_info = 238 const content::ResourceRequestInfo* request_info =
222 content::ResourceRequestInfo::ForRequest(response); 239 content::ResourceRequestInfo::ForRequest(response);
223 if (!request_info) 240 if (!request_info)
224 return false; 241 return false;
225 242
226 if (!request_info->IsMainFrame()) 243 if (!request_info->IsMainFrame())
227 return false; 244 return false;
228 245
229 return request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME && 246 return request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME &&
230 IsHandledMainPage(response); 247 IsHandledMainPage(response);
231 } 248 }
232 249
233 // static 250 // static
234 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { 251 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) {
235 return request->url().SchemeIsHTTPOrHTTPS(); 252 return request->url().SchemeIsHTTPOrHTTPS();
236 } 253 }
237 254
238 // static 255 // static
239 bool ResourcePrefetchPredictor::IsHandledSubresource( 256 bool ResourcePrefetchPredictor::IsHandledSubresource(
240 net::URLRequest* response) { 257 net::URLRequest* response,
258 content::ResourceType resource_type) {
241 int resource_status = 0; 259 int resource_status = 0;
242 260
243 if (!response->first_party_for_cookies().SchemeIsHTTPOrHTTPS()) 261 if (!response->first_party_for_cookies().SchemeIsHTTPOrHTTPS())
244 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE; 262 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE;
245 263
246 if (!response->url().SchemeIsHTTPOrHTTPS()) 264 if (!response->url().SchemeIsHTTPOrHTTPS())
247 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE; 265 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE;
248 266
249 std::string mime_type; 267 std::string mime_type;
250 response->GetMimeType(&mime_type); 268 response->GetMimeType(&mime_type);
251 if (!mime_type.empty() && !mime_util::IsSupportedImageMimeType(mime_type) && 269 if (!IsHandledResourceType(resource_type, mime_type))
252 !mime_util::IsSupportedJavascriptMimeType(mime_type) && 270 resource_status |= RESOURCE_STATUS_UNSUPPORTED_RESOURCE_TYPE;
253 !net::MatchesMimeType("text/css", mime_type)) {
254 resource_status |= RESOURCE_STATUS_UNSUPPORTED_MIME_TYPE;
255 }
256 271
257 if (response->method() != "GET") 272 if (response->method() != "GET")
258 resource_status |= RESOURCE_STATUS_NOT_GET; 273 resource_status |= RESOURCE_STATUS_NOT_GET;
259 274
260 if (response->original_url().spec().length() > 275 if (response->original_url().spec().length() >
261 ResourcePrefetchPredictorTables::kMaxStringLength) { 276 ResourcePrefetchPredictorTables::kMaxStringLength) {
262 resource_status |= RESOURCE_STATUS_URL_TOO_LONG; 277 resource_status |= RESOURCE_STATUS_URL_TOO_LONG;
263 } 278 }
264 279
265 if (!response->response_info().headers.get()) 280 if (!response->response_info().headers.get())
266 resource_status |= RESOURCE_STATUS_HEADERS_MISSING; 281 resource_status |= RESOURCE_STATUS_HEADERS_MISSING;
267 282
268 if (!IsCacheable(response)) 283 if (!IsCacheable(response))
269 resource_status |= RESOURCE_STATUS_NOT_CACHEABLE; 284 resource_status |= RESOURCE_STATUS_NOT_CACHEABLE;
270 285
271 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.ResourceStatus", 286 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.ResourceStatus",
272 resource_status, 287 resource_status,
273 RESOURCE_STATUS_MAX); 288 RESOURCE_STATUS_MAX);
274 289
275 return resource_status == 0; 290 return resource_status == 0;
276 } 291 }
277 292
278 // static 293 // static
294 bool ResourcePrefetchPredictor::IsHandledResourceType(
295 content::ResourceType resource_type,
296 const std::string& mime_type) {
297 bool handled = resource_type == content::RESOURCE_TYPE_STYLESHEET ||
298 resource_type == content::RESOURCE_TYPE_SCRIPT ||
299 resource_type == content::RESOURCE_TYPE_IMAGE ||
300 resource_type == content::RESOURCE_TYPE_FONT_RESOURCE;
301 // Restricts content::RESOURCE_TYPE_{PREFETCH,SUB_RESOURCE} to a small set of
302 // mime types, because these resource types don't communicate how the
303 // resources
304 // will be used.
305 if ((resource_type == content::RESOURCE_TYPE_PREFETCH ||
306 resource_type == content::RESOURCE_TYPE_SUB_RESOURCE)) {
307 content::ResourceType resource_type_from_mime = GetResourceTypeFromMimeType(
308 mime_type, content::RESOURCE_TYPE_LAST_TYPE);
309 handled = resource_type_from_mime != content::RESOURCE_TYPE_LAST_TYPE;
310 }
311 return handled;
312 }
313
314 // static
279 bool ResourcePrefetchPredictor::IsCacheable(const net::URLRequest* response) { 315 bool ResourcePrefetchPredictor::IsCacheable(const net::URLRequest* response) {
280 if (response->was_cached()) 316 if (response->was_cached())
281 return true; 317 return true;
282 318
283 // For non cached responses, we will ensure that the freshness lifetime is 319 // For non cached responses, we will ensure that the freshness lifetime is
284 // some sane value. 320 // some sane value.
285 const net::HttpResponseInfo& response_info = response->response_info(); 321 const net::HttpResponseInfo& response_info = response->response_info();
286 if (!response_info.headers.get()) 322 if (!response_info.headers.get())
287 return false; 323 return false;
288 base::Time response_time(response_info.response_time); 324 base::Time response_time(response_info.response_time);
289 response_time += base::TimeDelta::FromSeconds(1); 325 response_time += base::TimeDelta::FromSeconds(1);
290 base::TimeDelta freshness = 326 base::TimeDelta freshness =
291 response_info.headers->GetFreshnessLifetimes(response_time).freshness; 327 response_info.headers->GetFreshnessLifetimes(response_time).freshness;
292 return freshness > base::TimeDelta(); 328 return freshness > base::TimeDelta();
293 } 329 }
294 330
295 // static 331 // static
296 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType( 332 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType(
297 const std::string& mime_type, 333 const std::string& mime_type,
298 content::ResourceType fallback) { 334 content::ResourceType fallback) {
299 if (mime_util::IsSupportedImageMimeType(mime_type)) 335 if (mime_type.empty()) {
336 return fallback;
337 } else if (mime_util::IsSupportedImageMimeType(mime_type)) {
300 return content::RESOURCE_TYPE_IMAGE; 338 return content::RESOURCE_TYPE_IMAGE;
301 else if (mime_util::IsSupportedJavascriptMimeType(mime_type)) 339 } else if (mime_util::IsSupportedJavascriptMimeType(mime_type)) {
302 return content::RESOURCE_TYPE_SCRIPT; 340 return content::RESOURCE_TYPE_SCRIPT;
303 else if (net::MatchesMimeType("text/css", mime_type)) 341 } else if (net::MatchesMimeType("text/css", mime_type)) {
304 return content::RESOURCE_TYPE_STYLESHEET; 342 return content::RESOURCE_TYPE_STYLESHEET;
305 else 343 } else {
306 return fallback; 344 bool found =
345 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes),
346 [&mime_type](const std::string& mime) {
347 return net::MatchesMimeType(mime, mime_type);
348 });
349 if (found)
350 return content::RESOURCE_TYPE_FONT_RESOURCE;
351 }
352 return fallback;
307 } 353 }
308 354
309 //////////////////////////////////////////////////////////////////////////////// 355 ////////////////////////////////////////////////////////////////////////////////
310 // ResourcePrefetchPredictor structs. 356 // ResourcePrefetchPredictor structs.
311 357
312 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 358 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
313 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), 359 : resource_type(content::RESOURCE_TYPE_LAST_TYPE),
314 was_cached(false) { 360 was_cached(false) {
315 } 361 }
316 362
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 // HistoryService is already loaded. Continue with Initialization. 1381 // HistoryService is already loaded. Continue with Initialization.
1336 OnHistoryAndCacheLoaded(); 1382 OnHistoryAndCacheLoaded();
1337 return; 1383 return;
1338 } 1384 }
1339 DCHECK(!history_service_observer_.IsObserving(history_service)); 1385 DCHECK(!history_service_observer_.IsObserving(history_service));
1340 history_service_observer_.Add(history_service); 1386 history_service_observer_.Add(history_service);
1341 return; 1387 return;
1342 } 1388 }
1343 1389
1344 } // namespace predictors 1390 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698