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/predictors/resource_prefetch_common.h" 6 7 #include "base/command_line.h" 8 #include "base/metrics/field_trial.h" 9 #include "base/prefs/pref_service.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/common/chrome_switches.h" 12 #include "chrome/common/pref_names.h" 13 #include "content/public/browser/render_process_host.h" 14 #include "content/public/browser/render_view_host.h" 15 #include "content/public/browser/web_contents.h" 16 17 namespace predictors { 18 19 const char kSpeculativePrefetchingTrialName[] = 20 "SpeculativeResourcePrefetching"; 21 22 bool IsSpeculativeResourcePrefetchingEnabled( 23 Profile* profile, 24 ResourcePrefetchPredictorConfig* config) { 25 DCHECK(config); 26 27 // Off the record - disabled. 28 if (!profile || profile->IsOffTheRecord()) 29 return false; 30 31 // If the user has explicitly disabled "predictive actions" - disabled. 32 if (!profile->GetPrefs() || 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( 40 switches::kSpeculativeResourcePrefetching)) { 41 const std::string value = 42 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 43 switches::kSpeculativeResourcePrefetching); 44 45 if (value == switches::kSpeculativeResourcePrefetchingDisabled) { 46 return false; 47 } else if (value == switches::kSpeculativeResourcePrefetchingLearning) { 48 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; 49 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; 50 return true; 51 } else if (value == switches::kSpeculativeResourcePrefetchingEnabled) { 52 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; 53 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; 54 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; 55 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; 56 return true; 57 } 58 } 59 60 std::string trial = base::FieldTrialList::FindFullName( 61 kSpeculativePrefetchingTrialName); 62 63 if (trial == "LearningHost") { 64 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; 65 return true; 66 } else if (trial == "LearningURL") { 67 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; 68 return true; 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 93 config->min_url_visit_count = 1; 94 config->min_resource_confidence_to_trigger_prefetch = 0.5f; 95 config->min_resource_hits_to_trigger_prefetch = 1; 96 return true; 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; 104 config->min_resource_confidence_to_trigger_prefetch = 0.9f; 105 config->min_resource_hits_to_trigger_prefetch = 3; 106 return true; 107 } else if (trial == "PrefetchingMoreResources") { 108 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; 109 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; 110 config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; 111 config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; 112 113 config->max_resources_per_entry = 100; 114 return true; 115 } else if (trial == "LearningSmallDB") { 116 config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; 117 config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; 118 119 config->max_urls_to_track = 200; 120 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 } 156 157 return false; 158 } 159 160 NavigationID::NavigationID() : render_process_id(-1), render_view_id(-1) { 161 } 162 163 NavigationID::NavigationID(const NavigationID& other) 164 : render_process_id(other.render_process_id), 165 render_view_id(other.render_view_id), 166 main_frame_url(other.main_frame_url), 167 creation_time(other.creation_time) { 168 } 169 170 NavigationID::NavigationID(content::WebContents* web_contents) 171 : render_process_id(web_contents->GetRenderProcessHost()->GetID()), 172 render_view_id(web_contents->GetRenderViewHost()->GetRoutingID()), 173 main_frame_url(web_contents->GetURL()) { 174 } 175 176 bool NavigationID::is_valid() const { 177 return render_process_id != -1 && render_view_id != -1 && 178 !main_frame_url.is_empty(); 179 } 180 181 bool NavigationID::operator<(const NavigationID& rhs) const { 182 DCHECK(is_valid() && rhs.is_valid()); 183 if (render_process_id != rhs.render_process_id) 184 return render_process_id < rhs.render_process_id; 185 else if (render_view_id != rhs.render_view_id) 186 return render_view_id < rhs.render_view_id; 187 else 188 return main_frame_url < rhs.main_frame_url; 189 } 190 191 bool NavigationID::operator==(const NavigationID& rhs) const { 192 DCHECK(is_valid() && rhs.is_valid()); 193 return IsSameRenderer(rhs) && main_frame_url == rhs.main_frame_url; 194 } 195 196 bool NavigationID::IsSameRenderer(const NavigationID& other) const { 197 DCHECK(is_valid() && other.is_valid()); 198 return render_process_id == other.render_process_id && 199 render_view_id == other.render_view_id; 200 } 201 202 ResourcePrefetchPredictorConfig::ResourcePrefetchPredictorConfig() 203 : mode(0), 204 max_navigation_lifetime_seconds(60), 205 max_urls_to_track(500), 206 max_hosts_to_track(200), 207 min_url_visit_count(2), 208 max_resources_per_entry(50), 209 max_consecutive_misses(3), 210 min_resource_confidence_to_trigger_prefetch(0.8f), 211 min_resource_hits_to_trigger_prefetch(3), 212 max_prefetches_inflight_per_navigation(24), 213 max_prefetches_inflight_per_host_per_navigation(3) { 214 } 215 216 ResourcePrefetchPredictorConfig::~ResourcePrefetchPredictorConfig() { 217 } 218 219 bool ResourcePrefetchPredictorConfig::IsLearningEnabled() const { 220 return IsURLLearningEnabled() || IsHostLearningEnabled(); 221 } 222 223 bool ResourcePrefetchPredictorConfig::IsPrefetchingEnabled() const { 224 return IsURLPrefetchingEnabled() || IsHostPrefetchingEnabled(); 225 } 226 227 bool ResourcePrefetchPredictorConfig::IsURLLearningEnabled() const { 228 return (mode & URL_LEARNING) > 0; 229 } 230 231 bool ResourcePrefetchPredictorConfig::IsHostLearningEnabled() const { 232 return (mode & HOST_LEARNING) > 0; 233 } 234 235 bool ResourcePrefetchPredictorConfig::IsURLPrefetchingEnabled() const { 236 return (mode & URL_PREFETCHING) > 0; 237 } 238 239 bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled() const { 240 return (mode & HOST_PRFETCHING) > 0; 241 } 242 243 } // namespace predictors 244