| 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> | 7 #include <string> |
| 8 #include <tuple> | 8 #include <tuple> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/metrics/field_trial.h" | |
| 12 #include "base/strings/string_split.h" | |
| 13 #include "chrome/browser/net/prediction_options.h" | 11 #include "chrome/browser/net/prediction_options.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
| 16 #include "components/prefs/pref_service.h" | 14 #include "components/prefs/pref_service.h" |
| 17 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 18 #include "content/public/browser/render_frame_host.h" | 16 #include "content/public/browser/render_frame_host.h" |
| 19 #include "content/public/browser/render_process_host.h" | 17 #include "content/public/browser/render_process_host.h" |
| 20 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
| 21 | 19 |
| 22 using base::FieldTrialList; | |
| 23 using std::string; | |
| 24 using std::vector; | |
| 25 | |
| 26 namespace predictors { | 20 namespace predictors { |
| 27 | 21 |
| 28 const char kSpeculativePrefetchingTrialName[] = | 22 namespace { |
| 29 "SpeculativeResourcePrefetching"; | |
| 30 | 23 |
| 31 /* | 24 constexpr int kLearningMode = ResourcePrefetchPredictorConfig::URL_LEARNING | |
| 32 * SpeculativeResourcePrefetching is a field trial, and its value must have the | 25 ResourcePrefetchPredictorConfig::HOST_LEARNING; |
| 33 * following format: key1=value1:key2=value2:key3=value3 | 26 constexpr int kPrefetchingMode = |
| 34 * e.g. "Prefetching=Enabled:Predictor=Url:Confidence=High" | 27 ResourcePrefetchPredictorConfig::URL_PREFETCHING | |
| 35 * The function below extracts the value corresponding to a key provided from | 28 ResourcePrefetchPredictorConfig::HOST_PREFETCHING; |
| 36 * the SpeculativeResourcePrefetching field trial. | 29 |
| 37 */ | 30 } // namespace |
| 38 std::string GetFieldTrialSpecValue(string key) { | |
| 39 std::string trial_name = | |
| 40 FieldTrialList::FindFullName(kSpeculativePrefetchingTrialName); | |
| 41 for (const base::StringPiece& element : base::SplitStringPiece( | |
| 42 trial_name, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { | |
| 43 std::vector<base::StringPiece> key_value = base::SplitStringPiece( | |
| 44 element, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 45 if (key_value.size() == 2 && key_value[0] == key) | |
| 46 return key_value[1].as_string(); | |
| 47 } | |
| 48 return string(); | |
| 49 } | |
| 50 | 31 |
| 51 bool IsSpeculativeResourcePrefetchingEnabled( | 32 bool IsSpeculativeResourcePrefetchingEnabled( |
| 52 Profile* profile, | 33 Profile* profile, |
| 53 ResourcePrefetchPredictorConfig* config) { | 34 ResourcePrefetchPredictorConfig* config) { |
| 54 DCHECK(config); | 35 DCHECK(config); |
| 55 | 36 |
| 56 // Off the record - disabled. | 37 // Off the record - disabled. |
| 57 if (!profile || profile->IsOffTheRecord()) | 38 if (!profile || profile->IsOffTheRecord()) |
| 58 return false; | 39 return false; |
| 59 | 40 |
| 60 // Enabled by command line switch. The config has the default params already | 41 // Enabled by command line switch. The config has the default params already |
| 61 // set. The command line with just enable them with the default params. | 42 // set. The command line with just enable them with the default params. |
| 62 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 43 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 63 switches::kSpeculativeResourcePrefetching)) { | 44 switches::kSpeculativeResourcePrefetching)) { |
| 64 const std::string value = | 45 const std::string value = |
| 65 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 46 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 66 switches::kSpeculativeResourcePrefetching); | 47 switches::kSpeculativeResourcePrefetching); |
| 67 | 48 |
| 68 if (value == switches::kSpeculativeResourcePrefetchingDisabled) { | 49 if (value == switches::kSpeculativeResourcePrefetchingDisabled) { |
| 69 return false; | 50 return false; |
| 70 } else if (value == switches::kSpeculativeResourcePrefetchingLearning) { | 51 } else if (value == switches::kSpeculativeResourcePrefetchingLearning) { |
| 71 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | 52 config->mode |= kLearningMode; |
| 72 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
| 73 return true; | 53 return true; |
| 74 } else if (value == switches::kSpeculativeResourcePrefetchingEnabled) { | 54 } else if (value == switches::kSpeculativeResourcePrefetchingEnabled) { |
| 75 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | 55 config->mode |= kLearningMode | kPrefetchingMode; |
| 76 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
| 77 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
| 78 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
| 79 return true; | 56 return true; |
| 80 } | 57 } |
| 81 } | 58 } |
| 82 | 59 |
| 83 // Disable if no field trial is specified. | 60 return false; |
| 84 std::string trial = base::FieldTrialList::FindFullName( | |
| 85 kSpeculativePrefetchingTrialName); | |
| 86 if (trial.empty()) | |
| 87 return false; | |
| 88 | |
| 89 // Enabled by field trial. | |
| 90 std::string spec_prefetching = GetFieldTrialSpecValue("Prefetching"); | |
| 91 std::string spec_predictor = GetFieldTrialSpecValue("Predictor"); | |
| 92 std::string spec_confidence = GetFieldTrialSpecValue("Confidence"); | |
| 93 std::string spec_more_resources = GetFieldTrialSpecValue("MoreResources"); | |
| 94 std::string spec_small_db = GetFieldTrialSpecValue("SmallDB"); | |
| 95 | |
| 96 if (spec_prefetching == "Learning") { | |
| 97 if (spec_predictor == "Url") { | |
| 98 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
| 99 } else if (spec_predictor == "Host") { | |
| 100 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
| 101 } else { | |
| 102 // Default: both Url and Host | |
| 103 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
| 104 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
| 105 } | |
| 106 } else if (spec_prefetching == "Enabled") { | |
| 107 if (spec_predictor == "Url") { | |
| 108 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
| 109 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
| 110 } else if (spec_predictor == "Host") { | |
| 111 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
| 112 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
| 113 } else { | |
| 114 // Default: both Url and Host | |
| 115 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; | |
| 116 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; | |
| 117 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; | |
| 118 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; | |
| 119 } | |
| 120 } else { | |
| 121 // Default: spec_prefetching == "Disabled" | |
| 122 return false; | |
| 123 } | |
| 124 | |
| 125 if (spec_confidence == "Low") { | |
| 126 config->min_url_visit_count = 1; | |
| 127 config->min_resource_confidence_to_trigger_prefetch = 0.5f; | |
| 128 config->min_resource_hits_to_trigger_prefetch = 1; | |
| 129 } else if (spec_confidence == "High") { | |
| 130 config->min_url_visit_count = 3; | |
| 131 config->min_resource_confidence_to_trigger_prefetch = 0.9f; | |
| 132 config->min_resource_hits_to_trigger_prefetch = 3; | |
| 133 } else { | |
| 134 // default | |
| 135 config->min_url_visit_count = 2; | |
| 136 config->min_resource_confidence_to_trigger_prefetch = 0.7f; | |
| 137 config->min_resource_hits_to_trigger_prefetch = 2; | |
| 138 } | |
| 139 | |
| 140 if (spec_more_resources == "Enabled") { | |
| 141 config->max_resources_per_entry = 100; | |
| 142 } | |
| 143 | |
| 144 if (spec_small_db == "Enabled") { | |
| 145 config->max_urls_to_track = 200; | |
| 146 config->max_hosts_to_track = 100; | |
| 147 } | |
| 148 | |
| 149 return true; | |
| 150 } | 61 } |
| 151 | 62 |
| 152 NavigationID::NavigationID() | 63 NavigationID::NavigationID() |
| 153 : render_process_id(-1), | 64 : render_process_id(-1), |
| 154 render_frame_id(-1) { | 65 render_frame_id(-1) { |
| 155 } | 66 } |
| 156 | 67 |
| 157 NavigationID::NavigationID(int render_process_id, | 68 NavigationID::NavigationID(int render_process_id, |
| 158 int render_frame_id, | 69 int render_frame_id, |
| 159 const GURL& main_frame_url) | 70 const GURL& main_frame_url) |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 } | 156 } |
| 246 | 157 |
| 247 bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled( | 158 bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled( |
| 248 Profile* profile) const { | 159 Profile* profile) const { |
| 249 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 160 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 250 if (!profile || !profile->GetPrefs() || | 161 if (!profile || !profile->GetPrefs() || |
| 251 chrome_browser_net::CanPrefetchAndPrerenderUI(profile->GetPrefs()) != | 162 chrome_browser_net::CanPrefetchAndPrerenderUI(profile->GetPrefs()) != |
| 252 chrome_browser_net::NetworkPredictionStatus::ENABLED) { | 163 chrome_browser_net::NetworkPredictionStatus::ENABLED) { |
| 253 return false; | 164 return false; |
| 254 } | 165 } |
| 255 return (mode & HOST_PRFETCHING) > 0; | 166 return (mode & HOST_PREFETCHING) > 0; |
| 256 } | 167 } |
| 257 | 168 |
| 258 bool ResourcePrefetchPredictorConfig::IsLowConfidenceForTest() const { | 169 bool ResourcePrefetchPredictorConfig::IsLowConfidenceForTest() const { |
| 259 return min_url_visit_count == 1 && | 170 return min_url_visit_count == 1 && |
| 260 std::abs(min_resource_confidence_to_trigger_prefetch - 0.5f) < 1e-6 && | 171 std::abs(min_resource_confidence_to_trigger_prefetch - 0.5f) < 1e-6 && |
| 261 min_resource_hits_to_trigger_prefetch == 1; | 172 min_resource_hits_to_trigger_prefetch == 1; |
| 262 } | 173 } |
| 263 | 174 |
| 264 bool ResourcePrefetchPredictorConfig::IsHighConfidenceForTest() const { | 175 bool ResourcePrefetchPredictorConfig::IsHighConfidenceForTest() const { |
| 265 return min_url_visit_count == 3 && | 176 return min_url_visit_count == 3 && |
| 266 std::abs(min_resource_confidence_to_trigger_prefetch - 0.9f) < 1e-6 && | 177 std::abs(min_resource_confidence_to_trigger_prefetch - 0.9f) < 1e-6 && |
| 267 min_resource_hits_to_trigger_prefetch == 3; | 178 min_resource_hits_to_trigger_prefetch == 3; |
| 268 } | 179 } |
| 269 | 180 |
| 270 bool ResourcePrefetchPredictorConfig::IsMoreResourcesEnabledForTest() const { | 181 bool ResourcePrefetchPredictorConfig::IsMoreResourcesEnabledForTest() const { |
| 271 return max_resources_per_entry == 100; | 182 return max_resources_per_entry == 100; |
| 272 } | 183 } |
| 273 | 184 |
| 274 bool ResourcePrefetchPredictorConfig::IsSmallDBEnabledForTest() const { | 185 bool ResourcePrefetchPredictorConfig::IsSmallDBEnabledForTest() const { |
| 275 return max_urls_to_track == 200 && max_hosts_to_track == 100; | 186 return max_urls_to_track == 200 && max_hosts_to_track == 100; |
| 276 } | 187 } |
| 277 | 188 |
| 278 } // namespace predictors | 189 } // namespace predictors |
| OLD | NEW |