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