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_common.h" | 5 #include "chrome/browser/predictors/resource_prefetch_common.h" |
6 | 6 |
| 7 #include <stdlib.h> |
| 8 |
7 #include "base/command_line.h" | 9 #include "base/command_line.h" |
8 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
9 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
| 12 #include "base/strings/string_split.h" |
| 13 #include "chrome/browser/net/prediction_options.h" |
10 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
11 #include "chrome/common/chrome_switches.h" | 15 #include "chrome/common/chrome_switches.h" |
12 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
| 17 #include "content/public/browser/browser_thread.h" |
13 #include "content/public/browser/render_process_host.h" | 18 #include "content/public/browser/render_process_host.h" |
14 #include "content/public/browser/render_view_host.h" | 19 #include "content/public/browser/render_view_host.h" |
15 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
16 | 21 |
| 22 using base::FieldTrialList; |
| 23 using std::string; |
| 24 using std::vector; |
| 25 |
17 namespace predictors { | 26 namespace predictors { |
18 | 27 |
19 const char kSpeculativePrefetchingTrialName[] = | 28 const char kSpeculativePrefetchingTrialName[] = |
20 "SpeculativeResourcePrefetching"; | 29 "SpeculativeResourcePrefetching"; |
21 | 30 |
| 31 /* |
| 32 * SpeculativeResourcePrefetching is a field trial, and its value must have the |
| 33 * following format: key1=value1:key2=value2:key3=value3 |
| 34 * e.g. "Prefetching=Enabled:Predictor=Url:Confidence=High" |
| 35 * The function below extracts the value corresponding to a key provided from |
| 36 * the SpeculativeResourcePrefetching field trial. |
| 37 */ |
| 38 string GetFiledTrialSpecValue(string key) { |
| 39 vector<string> elements; |
| 40 base::SplitString( |
| 41 FieldTrialList::FindFullName(kSpeculativePrefetchingTrialName), |
| 42 ':', |
| 43 &elements); |
| 44 for (int i = 0; i < static_cast<int>(elements.size()); i++) { |
| 45 vector<string> key_value; |
| 46 base::SplitString(elements[i], '=', &key_value); |
| 47 if (key_value.size() == 2 && key_value[0] == key) |
| 48 return key_value[1]; |
| 49 } |
| 50 return string(); |
| 51 } |
| 52 |
22 bool IsSpeculativeResourcePrefetchingEnabled( | 53 bool IsSpeculativeResourcePrefetchingEnabled( |
23 Profile* profile, | 54 Profile* profile, |
24 ResourcePrefetchPredictorConfig* config) { | 55 ResourcePrefetchPredictorConfig* config) { |
25 DCHECK(config); | 56 DCHECK(config); |
26 | 57 |
27 // Off the record - disabled. | 58 // Off the record - disabled. |
28 if (!profile || profile->IsOffTheRecord()) | 59 if (!profile || profile->IsOffTheRecord()) |
29 return false; | 60 return false; |
30 | 61 |
31 // If the user has explicitly disabled "predictive actions" - disabled. | 62 // Enabled by command line switch. The config has the default params already |
32 if (!profile->GetPrefs() || | 63 // set. The command line with just enable them with the default params. |
33 !profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)) { | |
34 return false; | |
35 } | |
36 | |
37 // The config has the default params already set. The command line with just | |
38 // enable them with the default params. | |
39 if (CommandLine::ForCurrentProcess()->HasSwitch( | 64 if (CommandLine::ForCurrentProcess()->HasSwitch( |
40 switches::kSpeculativeResourcePrefetching)) { | 65 switches::kSpeculativeResourcePrefetching)) { |
41 const std::string value = | 66 const std::string value = |
42 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 67 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
43 switches::kSpeculativeResourcePrefetching); | 68 switches::kSpeculativeResourcePrefetching); |
44 | 69 |
45 if (value == switches::kSpeculativeResourcePrefetchingDisabled) { | 70 if (value == switches::kSpeculativeResourcePrefetchingDisabled) { |
46 return false; | 71 return false; |
47 } else if (value == switches::kSpeculativeResourcePrefetchingLearning) { | 72 } else if (value == switches::kSpeculativeResourcePrefetchingLearning) { |
48 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | 73 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
49 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | 74 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
50 return true; | 75 return true; |
51 } else if (value == switches::kSpeculativeResourcePrefetchingEnabled) { | 76 } else if (value == switches::kSpeculativeResourcePrefetchingEnabled) { |
52 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | 77 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
53 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | 78 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
54 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | 79 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
55 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | 80 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
56 return true; | 81 return true; |
57 } | 82 } |
58 } | 83 } |
59 | 84 |
| 85 // Disable if no field trial is specified. |
60 std::string trial = base::FieldTrialList::FindFullName( | 86 std::string trial = base::FieldTrialList::FindFullName( |
61 kSpeculativePrefetchingTrialName); | 87 kSpeculativePrefetchingTrialName); |
| 88 if (trial.empty()) |
| 89 return false; |
62 | 90 |
63 if (trial == "LearningHost") { | 91 // Enabled by field trial. |
64 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | 92 std::string spec_prefetching = GetFiledTrialSpecValue("Prefetching"); |
65 return true; | 93 std::string spec_predictor = GetFiledTrialSpecValue("Predictor"); |
66 } else if (trial == "LearningURL") { | 94 std::string spec_confidence = GetFiledTrialSpecValue("Confidence"); |
67 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | 95 std::string spec_more_resources = GetFiledTrialSpecValue("MoreResources"); |
68 return true; | 96 std::string spec_small_db = GetFiledTrialSpecValue("SmallDB"); |
69 } else if (trial == "Learning") { | |
70 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
71 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
72 return true; | |
73 } else if (trial == "PrefetchingHost") { | |
74 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
75 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
76 return true; | |
77 } else if (trial == "PrefetchingURL") { | |
78 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
79 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
80 return true; | |
81 } else if (trial == "Prefetching") { | |
82 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
83 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
84 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
85 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
86 return true; | |
87 } else if (trial == "PrefetchingLowConfidence") { | |
88 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
89 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
90 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
91 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
92 | 97 |
| 98 if (spec_prefetching == "Learning") { |
| 99 if (spec_predictor == "Url") { |
| 100 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
| 101 } else if (spec_predictor == "Host") { |
| 102 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
| 103 } else { |
| 104 // Default: both Url and Host |
| 105 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
| 106 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
| 107 } |
| 108 } else if (spec_prefetching == "Enabled") { |
| 109 if (spec_predictor == "Url") { |
| 110 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
| 111 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
| 112 } else if (spec_predictor == "Host") { |
| 113 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
| 114 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
| 115 } else { |
| 116 // Default: both Url and Host |
| 117 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
| 118 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
| 119 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
| 120 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
| 121 } |
| 122 } else { |
| 123 // Default: spec_prefetching == "Disabled" |
| 124 return false; |
| 125 } |
| 126 |
| 127 if (spec_confidence == "Low") { |
93 config->min_url_visit_count = 1; | 128 config->min_url_visit_count = 1; |
94 config->min_resource_confidence_to_trigger_prefetch = 0.5f; | 129 config->min_resource_confidence_to_trigger_prefetch = 0.5f; |
95 config->min_resource_hits_to_trigger_prefetch = 1; | 130 config->min_resource_hits_to_trigger_prefetch = 1; |
96 return true; | 131 } else if (spec_confidence == "High") { |
97 } else if (trial == "PrefetchingHighConfidence") { | |
98 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
99 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
100 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
101 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
102 | |
103 config->min_url_visit_count = 3; | 132 config->min_url_visit_count = 3; |
104 config->min_resource_confidence_to_trigger_prefetch = 0.9f; | 133 config->min_resource_confidence_to_trigger_prefetch = 0.9f; |
105 config->min_resource_hits_to_trigger_prefetch = 3; | 134 config->min_resource_hits_to_trigger_prefetch = 3; |
106 return true; | 135 } else { |
107 } else if (trial == "PrefetchingMoreResources") { | 136 // default |
108 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | 137 config->min_url_visit_count = 2; |
109 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | 138 config->min_resource_confidence_to_trigger_prefetch = 0.7f; |
110 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | 139 config->min_resource_hits_to_trigger_prefetch = 2; |
111 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | 140 } |
112 | 141 |
| 142 if (spec_more_resources == "Enabled") { |
113 config->max_resources_per_entry = 100; | 143 config->max_resources_per_entry = 100; |
114 return true; | 144 } |
115 } else if (trial == "LearningSmallDB") { | |
116 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
117 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
118 | 145 |
| 146 if (spec_small_db == "Enabled") { |
119 config->max_urls_to_track = 200; | 147 config->max_urls_to_track = 200; |
120 config->max_hosts_to_track = 100; | 148 config->max_hosts_to_track = 100; |
121 return true; | |
122 } else if (trial == "PrefetchingSmallDB") { | |
123 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
124 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
125 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
126 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
127 | |
128 config->max_urls_to_track = 200; | |
129 config->max_hosts_to_track = 100; | |
130 return true; | |
131 } else if (trial == "PrefetchingSmallDBLowConfidence") { | |
132 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
133 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
134 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
135 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
136 | |
137 config->max_urls_to_track = 200; | |
138 config->max_hosts_to_track = 100; | |
139 config->min_url_visit_count = 1; | |
140 config->min_resource_confidence_to_trigger_prefetch = 0.5f; | |
141 config->min_resource_hits_to_trigger_prefetch = 1; | |
142 return true; | |
143 } else if (trial == "PrefetchingSmallDBHighConfidence") { | |
144 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
145 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
146 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
147 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
148 | |
149 config->max_urls_to_track = 200; | |
150 config->max_hosts_to_track = 100; | |
151 config->min_url_visit_count = 3; | |
152 config->min_resource_confidence_to_trigger_prefetch = 0.9f; | |
153 config->min_resource_hits_to_trigger_prefetch = 3; | |
154 return true; | |
155 } | 149 } |
156 | 150 |
157 return false; | 151 return true; |
158 } | 152 } |
159 | 153 |
160 NavigationID::NavigationID() | 154 NavigationID::NavigationID() |
161 : render_process_id(-1), | 155 : render_process_id(-1), |
162 render_frame_id(-1) { | 156 render_frame_id(-1) { |
163 } | 157 } |
164 | 158 |
165 NavigationID::NavigationID(const NavigationID& other) | 159 NavigationID::NavigationID(const NavigationID& other) |
166 : render_process_id(other.render_process_id), | 160 : render_process_id(other.render_process_id), |
167 render_frame_id(other.render_frame_id), | 161 render_frame_id(other.render_frame_id), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 } | 196 } |
203 | 197 |
204 ResourcePrefetchPredictorConfig::ResourcePrefetchPredictorConfig() | 198 ResourcePrefetchPredictorConfig::ResourcePrefetchPredictorConfig() |
205 : mode(0), | 199 : mode(0), |
206 max_navigation_lifetime_seconds(60), | 200 max_navigation_lifetime_seconds(60), |
207 max_urls_to_track(500), | 201 max_urls_to_track(500), |
208 max_hosts_to_track(200), | 202 max_hosts_to_track(200), |
209 min_url_visit_count(2), | 203 min_url_visit_count(2), |
210 max_resources_per_entry(50), | 204 max_resources_per_entry(50), |
211 max_consecutive_misses(3), | 205 max_consecutive_misses(3), |
212 min_resource_confidence_to_trigger_prefetch(0.8f), | 206 min_resource_confidence_to_trigger_prefetch(0.7f), |
213 min_resource_hits_to_trigger_prefetch(3), | 207 min_resource_hits_to_trigger_prefetch(2), |
214 max_prefetches_inflight_per_navigation(24), | 208 max_prefetches_inflight_per_navigation(24), |
215 max_prefetches_inflight_per_host_per_navigation(3) { | 209 max_prefetches_inflight_per_host_per_navigation(3) { |
216 } | 210 } |
217 | 211 |
218 ResourcePrefetchPredictorConfig::~ResourcePrefetchPredictorConfig() { | 212 ResourcePrefetchPredictorConfig::~ResourcePrefetchPredictorConfig() { |
219 } | 213 } |
220 | 214 |
221 bool ResourcePrefetchPredictorConfig::IsLearningEnabled() const { | 215 bool ResourcePrefetchPredictorConfig::IsLearningEnabled() const { |
222 return IsURLLearningEnabled() || IsHostLearningEnabled(); | 216 return IsURLLearningEnabled() || IsHostLearningEnabled(); |
223 } | 217 } |
224 | 218 |
225 bool ResourcePrefetchPredictorConfig::IsPrefetchingEnabled() const { | 219 bool ResourcePrefetchPredictorConfig::IsPrefetchingEnabled( |
226 return IsURLPrefetchingEnabled() || IsHostPrefetchingEnabled(); | 220 Profile* profile) const { |
| 221 return IsURLPrefetchingEnabled(profile) || IsHostPrefetchingEnabled(profile); |
227 } | 222 } |
228 | 223 |
229 bool ResourcePrefetchPredictorConfig::IsURLLearningEnabled() const { | 224 bool ResourcePrefetchPredictorConfig::IsURLLearningEnabled() const { |
230 return (mode & URL_LEARNING) > 0; | 225 return (mode & URL_LEARNING) > 0; |
231 } | 226 } |
232 | 227 |
233 bool ResourcePrefetchPredictorConfig::IsHostLearningEnabled() const { | 228 bool ResourcePrefetchPredictorConfig::IsHostLearningEnabled() const { |
234 return (mode & HOST_LEARNING) > 0; | 229 return (mode & HOST_LEARNING) > 0; |
235 } | 230 } |
236 | 231 |
237 bool ResourcePrefetchPredictorConfig::IsURLPrefetchingEnabled() const { | 232 bool ResourcePrefetchPredictorConfig::IsURLPrefetchingEnabled( |
| 233 Profile* profile) const { |
| 234 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 235 if (!profile || !profile->GetPrefs() || |
| 236 !chrome_browser_net::CanPrefetchAndPrerenderUI(profile->GetPrefs())) { |
| 237 return false; |
| 238 } |
238 return (mode & URL_PREFETCHING) > 0; | 239 return (mode & URL_PREFETCHING) > 0; |
239 } | 240 } |
240 | 241 |
241 bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled() const { | 242 bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled( |
| 243 Profile* profile) const { |
| 244 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 245 if (!profile || !profile->GetPrefs() || |
| 246 !chrome_browser_net::CanPrefetchAndPrerenderUI(profile->GetPrefs())) { |
| 247 return false; |
| 248 } |
242 return (mode & HOST_PRFETCHING) > 0; | 249 return (mode & HOST_PRFETCHING) > 0; |
243 } | 250 } |
244 | 251 |
| 252 bool ResourcePrefetchPredictorConfig::IsLowConfidenceForTest() const { |
| 253 return min_url_visit_count == 1 && |
| 254 std::abs(min_resource_confidence_to_trigger_prefetch - 0.5f) < 1e-6 && |
| 255 min_resource_hits_to_trigger_prefetch == 1; |
| 256 } |
| 257 |
| 258 bool ResourcePrefetchPredictorConfig::IsHighConfidenceForTest() const { |
| 259 return min_url_visit_count == 3 && |
| 260 std::abs(min_resource_confidence_to_trigger_prefetch - 0.9f) < 1e-6 && |
| 261 min_resource_hits_to_trigger_prefetch == 3; |
| 262 } |
| 263 |
| 264 bool ResourcePrefetchPredictorConfig::IsMoreResourcesEnabledForTest() const { |
| 265 return max_resources_per_entry == 100; |
| 266 } |
| 267 |
| 268 bool ResourcePrefetchPredictorConfig::IsSmallDBEnabledForTest() const { |
| 269 return max_urls_to_track == 200 && max_hosts_to_track == 100; |
| 270 } |
| 271 |
245 } // namespace predictors | 272 } // namespace predictors |
OLD | NEW |