| OLD | NEW |
| 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 <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/metrics/sparse_histogram.h" |
| 13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 16 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 17 #include "chrome/browser/chrome_notification_types.h" | 18 #include "chrome/browser/chrome_notification_types.h" |
| 18 #include "chrome/browser/history/history_database.h" | 19 #include "chrome/browser/history/history_database.h" |
| 19 #include "chrome/browser/history/history_db_task.h" | 20 #include "chrome/browser/history/history_db_task.h" |
| 20 #include "chrome/browser/history/history_notifications.h" | 21 #include "chrome/browser/history/history_notifications.h" |
| 21 #include "chrome/browser/history/history_service.h" | 22 #include "chrome/browser/history/history_service.h" |
| 22 #include "chrome/browser/history/history_service_factory.h" | 23 #include "chrome/browser/history/history_service_factory.h" |
| 23 #include "chrome/browser/predictors/predictor_database.h" | 24 #include "chrome/browser/predictors/predictor_database.h" |
| 24 #include "chrome/browser/predictors/predictor_database_factory.h" | 25 #include "chrome/browser/predictors/predictor_database_factory.h" |
| 25 #include "chrome/browser/predictors/resource_prefetcher_manager.h" | 26 #include "chrome/browser/predictors/resource_prefetcher_manager.h" |
| 26 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/profiles/profile.h" |
| 27 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
| 28 #include "chrome/common/url_constants.h" | 29 #include "chrome/common/url_constants.h" |
| 29 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 30 #include "content/public/browser/navigation_controller.h" | 31 #include "content/public/browser/navigation_controller.h" |
| 31 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 32 #include "content/public/browser/notification_source.h" | 33 #include "content/public/browser/notification_source.h" |
| 33 #include "content/public/browser/notification_types.h" | 34 #include "content/public/browser/notification_types.h" |
| 34 #include "content/public/browser/resource_request_info.h" | 35 #include "content/public/browser/resource_request_info.h" |
| 35 #include "content/public/browser/web_contents.h" | 36 #include "content/public/browser/web_contents.h" |
| 36 #include "net/base/mime_util.h" | 37 #include "net/base/mime_util.h" |
| 38 #include "net/base/network_change_notifier.h" |
| 37 #include "net/http/http_response_headers.h" | 39 #include "net/http/http_response_headers.h" |
| 38 #include "net/url_request/url_request.h" | 40 #include "net/url_request/url_request.h" |
| 39 #include "net/url_request/url_request_context_getter.h" | 41 #include "net/url_request/url_request_context_getter.h" |
| 40 | 42 |
| 41 using content::BrowserThread; | 43 using content::BrowserThread; |
| 42 | 44 |
| 43 namespace { | 45 namespace { |
| 44 | 46 |
| 45 // For reporting whether a subresource is handled or not, and for what reasons. | 47 // For reporting whether a subresource is handled or not, and for what reasons. |
| 46 enum ResourceStatus { | 48 enum ResourceStatus { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, | 85 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, |
| 84 REPORTING_EVENT_COUNT = 2 | 86 REPORTING_EVENT_COUNT = 2 |
| 85 }; | 87 }; |
| 86 | 88 |
| 87 void RecordNavigationEvent(NavigationEvent event) { | 89 void RecordNavigationEvent(NavigationEvent event) { |
| 88 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationEvent", | 90 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationEvent", |
| 89 event, | 91 event, |
| 90 NAVIGATION_EVENT_COUNT); | 92 NAVIGATION_EVENT_COUNT); |
| 91 } | 93 } |
| 92 | 94 |
| 95 // These are additional connection types for |
| 96 // net::NetworkChangeNotifier::ConnectionType. They have negative values in case |
| 97 // the original network connection types expand. |
| 98 enum AdditionalConnectionType { |
| 99 CONNECTION_ALL = -2, |
| 100 CONNECTION_CELLULAR = -1 |
| 101 }; |
| 102 |
| 103 std::string GetNetTypeStr() { |
| 104 switch (net::NetworkChangeNotifier::GetConnectionType()) { |
| 105 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: |
| 106 return "Ethernet"; |
| 107 case net::NetworkChangeNotifier::CONNECTION_WIFI: |
| 108 return "WiFi"; |
| 109 case net::NetworkChangeNotifier::CONNECTION_2G: |
| 110 return "2G"; |
| 111 case net::NetworkChangeNotifier::CONNECTION_3G: |
| 112 return "3G"; |
| 113 case net::NetworkChangeNotifier::CONNECTION_4G: |
| 114 return "4G"; |
| 115 case net::NetworkChangeNotifier::CONNECTION_NONE: |
| 116 return "None"; |
| 117 case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: |
| 118 return "Bluetooth"; |
| 119 case net::NetworkChangeNotifier::CONNECTION_UNKNOWN: |
| 120 default: |
| 121 break; |
| 122 } |
| 123 return "Unknown"; |
| 124 } |
| 125 |
| 126 void ReportPrefetchedNetworkType(int type) { |
| 127 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 128 "ResourcePrefetchPredictor.NetworkType.Prefetched", |
| 129 type); |
| 130 } |
| 131 |
| 132 void ReportNotPrefetchedNetworkType(int type) { |
| 133 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 134 "ResourcePrefetchPredictor.NetworkType.NotPrefetched", |
| 135 type); |
| 136 } |
| 137 |
| 93 } // namespace | 138 } // namespace |
| 94 | 139 |
| 95 namespace predictors { | 140 namespace predictors { |
| 96 | 141 |
| 97 //////////////////////////////////////////////////////////////////////////////// | 142 //////////////////////////////////////////////////////////////////////////////// |
| 98 // History lookup task. | 143 // History lookup task. |
| 99 | 144 |
| 100 // Used to fetch the visit count for a URL from the History database. | 145 // Used to fetch the visit count for a URL from the History database. |
| 101 class GetUrlVisitCountTask : public history::HistoryDBTask { | 146 class GetUrlVisitCountTask : public history::HistoryDBTask { |
| 102 public: | 147 public: |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 | 563 |
| 519 NavigationMap::iterator nav_it = | 564 NavigationMap::iterator nav_it = |
| 520 inflight_navigations_.find(navigation_id); | 565 inflight_navigations_.find(navigation_id); |
| 521 if (nav_it == inflight_navigations_.end()) { | 566 if (nav_it == inflight_navigations_.end()) { |
| 522 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL); | 567 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL); |
| 523 return; | 568 return; |
| 524 } | 569 } |
| 525 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL); | 570 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL); |
| 526 | 571 |
| 527 // Report any stats. | 572 // Report any stats. |
| 573 base::TimeDelta plt = base::TimeTicks::Now() - navigation_id.creation_time; |
| 574 ReportPageLoadTimeStats(plt); |
| 528 if (prefetch_manager_.get()) { | 575 if (prefetch_manager_.get()) { |
| 529 ResultsMap::iterator results_it = results_map_.find(navigation_id); | 576 ResultsMap::iterator results_it = results_map_.find(navigation_id); |
| 530 bool have_prefetch_results = results_it != results_map_.end(); | 577 bool have_prefetch_results = results_it != results_map_.end(); |
| 531 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults", | 578 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults", |
| 532 have_prefetch_results); | 579 have_prefetch_results); |
| 533 if (have_prefetch_results) { | 580 if (have_prefetch_results) { |
| 534 ReportAccuracyStats(results_it->second->key_type, | 581 ReportAccuracyStats(results_it->second->key_type, |
| 535 *(nav_it->second), | 582 *(nav_it->second), |
| 536 results_it->second->requests.get()); | 583 results_it->second->requests.get()); |
| 584 ReportPageLoadTimePrefetchStats( |
| 585 plt, |
| 586 true, |
| 587 base::Bind(&ReportPrefetchedNetworkType), |
| 588 results_it->second->key_type); |
| 589 } else { |
| 590 ReportPageLoadTimePrefetchStats( |
| 591 plt, |
| 592 false, |
| 593 base::Bind(&ReportNotPrefetchedNetworkType), |
| 594 PREFETCH_KEY_TYPE_URL); |
| 537 } | 595 } |
| 538 } else { | 596 } else { |
| 539 scoped_ptr<ResourcePrefetcher::RequestVector> requests( | 597 scoped_ptr<ResourcePrefetcher::RequestVector> requests( |
| 540 new ResourcePrefetcher::RequestVector); | 598 new ResourcePrefetcher::RequestVector); |
| 541 PrefetchKeyType key_type; | 599 PrefetchKeyType key_type; |
| 542 if (GetPrefetchData(navigation_id, requests.get(), &key_type)) { | 600 if (GetPrefetchData(navigation_id, requests.get(), &key_type)) { |
| 543 RecordNavigationEvent(NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL); | 601 RecordNavigationEvent(NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL); |
| 544 ReportPredictedAccuracyStats(key_type, | 602 ReportPredictedAccuracyStats(key_type, |
| 545 *(nav_it->second), | 603 *(nav_it->second), |
| 546 *requests); | 604 *requests); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 BrowserThread::PostTask( | 1054 BrowserThread::PostTask( |
| 997 BrowserThread::DB, FROM_HERE, | 1055 BrowserThread::DB, FROM_HERE, |
| 998 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, | 1056 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, |
| 999 tables_, | 1057 tables_, |
| 1000 url_data, | 1058 url_data, |
| 1001 host_data)); | 1059 host_data)); |
| 1002 } | 1060 } |
| 1003 } | 1061 } |
| 1004 | 1062 |
| 1005 //////////////////////////////////////////////////////////////////////////////// | 1063 //////////////////////////////////////////////////////////////////////////////// |
| 1006 // Accuracy measurement. | 1064 // Page load time and accuracy measurement. |
| 1065 |
| 1066 // This is essentially UMA_HISTOGRAM_MEDIUM_TIMES, but it avoids using the |
| 1067 // STATIC_HISTOGRAM_POINTER_BLOCK in UMA_HISTOGRAM definitions. |
| 1068 #define RPP_HISTOGRAM_MEDIUM_TIMES(name, page_load_time) \ |
| 1069 do { \ |
| 1070 base::HistogramBase* histogram = base::Histogram::FactoryTimeGet( \ |
| 1071 name, \ |
| 1072 base::TimeDelta::FromMilliseconds(10), \ |
| 1073 base::TimeDelta::FromMinutes(3), \ |
| 1074 50, \ |
| 1075 base::HistogramBase::kUmaTargetedHistogramFlag); \ |
| 1076 histogram->AddTime(page_load_time); \ |
| 1077 } while (0) |
| 1078 |
| 1079 void ResourcePrefetchPredictor::ReportPageLoadTimeStats( |
| 1080 base::TimeDelta plt) const { |
| 1081 net::NetworkChangeNotifier::ConnectionType connection_type = |
| 1082 net::NetworkChangeNotifier::GetConnectionType(); |
| 1083 |
| 1084 RPP_HISTOGRAM_MEDIUM_TIMES("ResourcePrefetchPredictor.PLT", plt); |
| 1085 RPP_HISTOGRAM_MEDIUM_TIMES( |
| 1086 "ResourcePrefetchPredictor.PLT_" + GetNetTypeStr(), plt); |
| 1087 if (net::NetworkChangeNotifier::IsConnectionCellular(connection_type)) |
| 1088 RPP_HISTOGRAM_MEDIUM_TIMES("ResourcePrefetchPredictor.PLT_Cellular", plt); |
| 1089 } |
| 1090 |
| 1091 void ResourcePrefetchPredictor::ReportPageLoadTimePrefetchStats( |
| 1092 base::TimeDelta plt, |
| 1093 bool prefetched, |
| 1094 base::Callback<void(int)> report_network_type_callback, |
| 1095 PrefetchKeyType key_type) const { |
| 1096 net::NetworkChangeNotifier::ConnectionType connection_type = |
| 1097 net::NetworkChangeNotifier::GetConnectionType(); |
| 1098 bool on_cellular = |
| 1099 net::NetworkChangeNotifier::IsConnectionCellular(connection_type); |
| 1100 |
| 1101 report_network_type_callback.Run(CONNECTION_ALL); |
| 1102 report_network_type_callback.Run(connection_type); |
| 1103 if (on_cellular) |
| 1104 report_network_type_callback.Run(CONNECTION_CELLULAR); |
| 1105 |
| 1106 std::string prefetched_str; |
| 1107 if (prefetched) |
| 1108 prefetched_str = "Prefetched"; |
| 1109 else |
| 1110 prefetched_str = "NotPrefetched"; |
| 1111 |
| 1112 RPP_HISTOGRAM_MEDIUM_TIMES( |
| 1113 "ResourcePrefetchPredictor.PLT." + prefetched_str, plt); |
| 1114 RPP_HISTOGRAM_MEDIUM_TIMES( |
| 1115 "ResourcePrefetchPredictor.PLT." + prefetched_str + "_" + GetNetTypeStr(), |
| 1116 plt); |
| 1117 if (on_cellular) { |
| 1118 RPP_HISTOGRAM_MEDIUM_TIMES( |
| 1119 "ResourcePrefetchPredictor.PLT." + prefetched_str + "_Cellular", plt); |
| 1120 } |
| 1121 |
| 1122 if (!prefetched) |
| 1123 return; |
| 1124 |
| 1125 std::string type = |
| 1126 key_type == PREFETCH_KEY_TYPE_HOST ? "Host" : "Url"; |
| 1127 RPP_HISTOGRAM_MEDIUM_TIMES( |
| 1128 "ResourcePrefetchPredictor.PLT.Prefetched." + type, plt); |
| 1129 RPP_HISTOGRAM_MEDIUM_TIMES( |
| 1130 "ResourcePrefetchPredictor.PLT.Prefetched." + type + "_" |
| 1131 + GetNetTypeStr(), |
| 1132 plt); |
| 1133 if (on_cellular) { |
| 1134 RPP_HISTOGRAM_MEDIUM_TIMES( |
| 1135 "ResourcePrefetchPredictor.PLT.Prefetched." + type + "_Cellular", |
| 1136 plt); |
| 1137 } |
| 1138 } |
| 1007 | 1139 |
| 1008 void ResourcePrefetchPredictor::ReportAccuracyStats( | 1140 void ResourcePrefetchPredictor::ReportAccuracyStats( |
| 1009 PrefetchKeyType key_type, | 1141 PrefetchKeyType key_type, |
| 1010 const std::vector<URLRequestSummary>& actual, | 1142 const std::vector<URLRequestSummary>& actual, |
| 1011 ResourcePrefetcher::RequestVector* prefetched) const { | 1143 ResourcePrefetcher::RequestVector* prefetched) const { |
| 1012 // Annotate the results. | 1144 // Annotate the results. |
| 1013 std::map<GURL, bool> actual_resources; | 1145 std::map<GURL, bool> actual_resources; |
| 1014 for (std::vector<URLRequestSummary>::const_iterator it = actual.begin(); | 1146 for (std::vector<URLRequestSummary>::const_iterator it = actual.begin(); |
| 1015 it != actual.end(); ++it) { | 1147 it != actual.end(); ++it) { |
| 1016 actual_resources[it->resource_url] = it->was_cached; | 1148 actual_resources[it->resource_url] = it->was_cached; |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 prefetch_network * 100.0 / num_assumed_prefetched); | 1342 prefetch_network * 100.0 / num_assumed_prefetched); |
| 1211 | 1343 |
| 1212 // Measure the ratio of total number of resources prefetched from network vs | 1344 // Measure the ratio of total number of resources prefetched from network vs |
| 1213 // the total number of resources fetched by the page from the network. | 1345 // the total number of resources fetched by the page from the network. |
| 1214 if (total_resources_fetched_from_network > 0) { | 1346 if (total_resources_fetched_from_network > 0) { |
| 1215 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( | 1347 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( |
| 1216 "PrefetchFromNetworkPercentOfTotalFromNetwork", | 1348 "PrefetchFromNetworkPercentOfTotalFromNetwork", |
| 1217 prefetch_network * 100.0 / total_resources_fetched_from_network); | 1349 prefetch_network * 100.0 / total_resources_fetched_from_network); |
| 1218 } | 1350 } |
| 1219 | 1351 |
| 1352 #undef RPP_HISTOGRAM_MEDIUM_TIMES |
| 1220 #undef RPP_PREDICTED_HISTOGRAM_PERCENTAGE | 1353 #undef RPP_PREDICTED_HISTOGRAM_PERCENTAGE |
| 1221 #undef RPP_PREDICTED_HISTOGRAM_COUNTS | 1354 #undef RPP_PREDICTED_HISTOGRAM_COUNTS |
| 1222 } | 1355 } |
| 1223 | 1356 |
| 1224 } // namespace predictors | 1357 } // namespace predictors |
| OLD | NEW |