• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/prerender/prerender_field_trial.h"
6 
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "chrome/browser/net/prediction_options.h"
15 #include "chrome/browser/predictors/autocomplete_action_predictor.h"
16 #include "chrome/browser/prerender/prerender_manager.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/sync/profile_sync_service.h"
19 #include "chrome/browser/sync/profile_sync_service_factory.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/chrome_version_info.h"
22 #include "chrome/common/pref_names.h"
23 #include "components/metrics/metrics_service.h"
24 #include "components/variations/variations_associated_data.h"
25 
26 using base::FieldTrial;
27 using base::FieldTrialList;
28 using base::StringToInt;
29 using std::string;
30 using std::vector;
31 
32 namespace prerender {
33 
34 namespace {
35 
36 const char kOmniboxTrialName[] = "PrerenderFromOmnibox";
37 int g_omnibox_trial_default_group_number = kint32min;
38 
39 const char kDisabledGroup[] = "Disabled";
40 const char kEnabledGroup[] = "Enabled";
41 
42 const char kLocalPredictorSpecTrialName[] = "PrerenderLocalPredictorSpec";
43 const char kLocalPredictorKeyName[] = "LocalPredictor";
44 const char kLocalPredictorUnencryptedSyncOnlyKeyName[] =
45     "LocalPredictorUnencryptedSyncOnly";
46 const char kLocalPredictorNetworkPredictionEnabledOnly[] =
47     "LocalPredictorNetworkPredictionEnabledOnly";
48 const char kLocalPredictorOnCellularOnly[] = "LocalPredictorOnCellularOnly";
49 const char kSideEffectFreeWhitelistKeyName[] = "SideEffectFreeWhitelist";
50 const char kPrerenderLaunchKeyName[] = "PrerenderLaunch";
51 const char kPrerenderAlwaysControlKeyName[] = "PrerenderAlwaysControl";
52 const char kPrerenderPrefetchKeyName[] = "PrerenderPrefetch";
53 const char kPrerenderQueryPrerenderServiceKeyName[] =
54     "PrerenderQueryPrerenderService";
55 const char kPrerenderQueryPrerenderServiceCurrentURLKeyName[] =
56     "PrerenderQueryPrerenderServiceCurrentURL";
57 const char kPrerenderQueryPrerenderServiceCandidateURLsKeyName[] =
58     "PrerenderQueryPrerenderServiceCandidateURLs";
59 const char kPrerenderServiceBehaviorIDKeyName[] = "PrerenderServiceBehaviorID";
60 const char kPrerenderServiceFetchTimeoutKeyName[] =
61     "PrerenderServiceFetchTimeoutMs";
62 const char kPrefetchListTimeoutKeyName[] = "PrefetchListTimeoutSeconds";
63 const char kPrerenderTTLKeyName[] = "PrerenderTTLSeconds";
64 const char kPrerenderPriorityHalfLifeTimeKeyName[] =
65     "PrerenderPriorityHalfLifeTimeSeconds";
66 const char kMaxConcurrentPrerenderKeyName[] = "MaxConcurrentPrerenders";
67 const char kMaxLaunchPrerenderKeyName[] = "MaxLaunchPrerenders";
68 const char kSkipFragment[] = "SkipFragment";
69 const char kSkipHTTPS[] = "SkipHTTPS";
70 const char kSkipWhitelist[] = "SkipWhitelist";
71 const char kSkipServiceWhitelist[] = "SkipServiceWhitelist";
72 const char kSkipLoggedIn[] = "SkipLoggedIn";
73 const char kSkipDefaultNoPrerender[] = "SkipDefaultNoPrerender";
74 const char kPrerenderServiceURLPrefixParameterName[] =
75     "PrerenderServiceURLPrefix";
76 const char kDefaultPrerenderServiceURLPrefix[] =
77     "https://clients4.google.com/prerenderservice/?q=";
78 const int kMinPrerenderServiceTimeoutMs = 1;
79 const int kMaxPrerenderServiceTimeoutMs = 10000;
80 const int kDefaultPrerenderServiceTimeoutMs = 1000;
81 const int kMinPrefetchListTimeoutSeconds = 1;
82 const int kMaxPrefetchListTimeoutSeconds = 1800;
83 const int kDefaultPrefetchListTimeoutSeconds = 300;
84 const char kSkipPrerenderLocalCanadidates[] = "SkipPrerenderLocalCandidates";
85 const char kSkipPrerenderServiceCanadidates[] =
86     "SkipPrerenderServiceCandidates";
87 const char kDisableSessionStorageNamespaceMerging[] =
88     "DisableSessionStorageNamespaceMerging";
89 const char kPrerenderCookieStore[] = "PrerenderCookieStore";
90 
SetupPrerenderFieldTrial()91 void SetupPrerenderFieldTrial() {
92   const FieldTrial::Probability divisor = 1000;
93 
94   FieldTrial::Probability control_probability;
95   FieldTrial::Probability experiment_multi_prerender_probability;
96   FieldTrial::Probability experiment_15min_ttl_probability;
97   FieldTrial::Probability experiment_no_use_probability;
98   FieldTrial::Probability experiment_match_complete_probability;
99 
100   chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
101   if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
102       channel == chrome::VersionInfo::CHANNEL_BETA) {
103     // Use very conservatives and stable settings in beta and stable.
104     const FieldTrial::Probability release_prerender_enabled_probability = 970;
105     const FieldTrial::Probability release_control_probability = 10;
106     const FieldTrial::Probability
107         release_experiment_multi_prerender_probability = 0;
108     const FieldTrial::Probability release_experiment_15min_ttl_probability = 10;
109     const FieldTrial::Probability release_experiment_no_use_probability = 0;
110     const FieldTrial::Probability
111         release_experiment_match_complete_probability = 10;
112     COMPILE_ASSERT(
113         release_prerender_enabled_probability +
114         release_control_probability +
115         release_experiment_multi_prerender_probability +
116         release_experiment_15min_ttl_probability +
117         release_experiment_no_use_probability +
118         release_experiment_match_complete_probability == divisor,
119         release_experiment_probabilities_must_equal_divisor);
120 
121     control_probability = release_control_probability;
122     experiment_multi_prerender_probability =
123         release_experiment_multi_prerender_probability;
124     experiment_15min_ttl_probability = release_experiment_15min_ttl_probability;
125     experiment_no_use_probability = release_experiment_no_use_probability;
126     experiment_match_complete_probability =
127         release_experiment_match_complete_probability;
128   } else {
129     // In testing channels, use more experiments and a larger control group to
130     // improve quality of data.
131     const FieldTrial::Probability dev_prerender_enabled_probability = 200;
132     const FieldTrial::Probability dev_control_probability = 200;
133     const FieldTrial::Probability
134         dev_experiment_multi_prerender_probability = 200;
135     const FieldTrial::Probability dev_experiment_15min_ttl_probability = 100;
136     const FieldTrial::Probability dev_experiment_no_use_probability = 100;
137     const FieldTrial::Probability
138         dev_experiment_match_complete_probability = 200;
139     COMPILE_ASSERT(dev_prerender_enabled_probability +
140                    dev_control_probability +
141                    dev_experiment_multi_prerender_probability +
142                    dev_experiment_15min_ttl_probability +
143                    dev_experiment_no_use_probability +
144                    dev_experiment_match_complete_probability == divisor,
145                    dev_experiment_probabilities_must_equal_divisor);
146 
147     control_probability = dev_control_probability;
148     experiment_multi_prerender_probability =
149         dev_experiment_multi_prerender_probability;
150     experiment_15min_ttl_probability = dev_experiment_15min_ttl_probability;
151     experiment_no_use_probability = dev_experiment_no_use_probability;
152     experiment_match_complete_probability =
153         dev_experiment_match_complete_probability;
154   }
155 
156   int prerender_enabled_group = -1;
157   scoped_refptr<FieldTrial> trial(
158       FieldTrialList::FactoryGetFieldTrial(
159           "Prerender", divisor, "PrerenderEnabled",
160           2014, 12, 31, FieldTrial::SESSION_RANDOMIZED,
161           &prerender_enabled_group));
162   const int control_group =
163       trial->AppendGroup("PrerenderControl",
164                          control_probability);
165   const int experiment_multi_prerender_group =
166       trial->AppendGroup("PrerenderMulti",
167                          experiment_multi_prerender_probability);
168   const int experiment_15_min_TTL_group =
169       trial->AppendGroup("Prerender15minTTL",
170                          experiment_15min_ttl_probability);
171   const int experiment_no_use_group =
172       trial->AppendGroup("PrerenderNoUse",
173                          experiment_no_use_probability);
174   const int experiment_match_complete_group =
175       trial->AppendGroup("MatchComplete",
176                          experiment_match_complete_probability);
177 
178   const int trial_group = trial->group();
179   if (trial_group == prerender_enabled_group) {
180     PrerenderManager::SetMode(
181         PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
182   } else if (trial_group == control_group) {
183     PrerenderManager::SetMode(
184         PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
185   } else if (trial_group == experiment_multi_prerender_group) {
186     PrerenderManager::SetMode(
187         PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP);
188   } else if (trial_group == experiment_15_min_TTL_group) {
189     PrerenderManager::SetMode(
190         PrerenderManager::PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP);
191   } else if (trial_group == experiment_no_use_group) {
192     PrerenderManager::SetMode(
193         PrerenderManager::PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP);
194   } else if (trial_group == experiment_match_complete_group) {
195     PrerenderManager::SetMode(
196         PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
197   } else {
198     NOTREACHED();
199   }
200 }
201 
202 }  // end namespace
203 
204 void ConfigureOmniboxPrerender();
205 
ConfigurePrerender(const CommandLine & command_line)206 void ConfigurePrerender(const CommandLine& command_line) {
207   enum PrerenderOption {
208     PRERENDER_OPTION_AUTO,
209     PRERENDER_OPTION_DISABLED,
210     PRERENDER_OPTION_ENABLED,
211   };
212 
213   PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
214   if (command_line.HasSwitch(switches::kPrerenderMode)) {
215     const string switch_value =
216         command_line.GetSwitchValueASCII(switches::kPrerenderMode);
217 
218     if (switch_value == switches::kPrerenderModeSwitchValueAuto) {
219       prerender_option = PRERENDER_OPTION_AUTO;
220     } else if (switch_value == switches::kPrerenderModeSwitchValueDisabled) {
221       prerender_option = PRERENDER_OPTION_DISABLED;
222     } else if (switch_value.empty() ||
223                switch_value == switches::kPrerenderModeSwitchValueEnabled) {
224       // The empty string means the option was provided with no value, and that
225       // means enable.
226       prerender_option = PRERENDER_OPTION_ENABLED;
227     } else {
228       prerender_option = PRERENDER_OPTION_DISABLED;
229       LOG(ERROR) << "Invalid --prerender option received on command line: "
230                  << switch_value;
231       LOG(ERROR) << "Disabling prerendering!";
232     }
233   }
234 
235   switch (prerender_option) {
236     case PRERENDER_OPTION_AUTO:
237       SetupPrerenderFieldTrial();
238       break;
239     case PRERENDER_OPTION_DISABLED:
240       PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
241       break;
242     case PRERENDER_OPTION_ENABLED:
243       PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
244       break;
245     default:
246       NOTREACHED();
247   }
248 
249   ConfigureOmniboxPrerender();
250 }
251 
ConfigureOmniboxPrerender()252 void ConfigureOmniboxPrerender() {
253   // Field trial to see if we're enabled.
254   const FieldTrial::Probability kDivisor = 100;
255 
256   FieldTrial::Probability kDisabledProbability = 10;
257   chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
258   if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
259       channel == chrome::VersionInfo::CHANNEL_BETA) {
260     kDisabledProbability = 1;
261   }
262   scoped_refptr<FieldTrial> omnibox_prerender_trial(
263       FieldTrialList::FactoryGetFieldTrial(
264           kOmniboxTrialName, kDivisor, "OmniboxPrerenderEnabled",
265           2014, 12, 31, FieldTrial::SESSION_RANDOMIZED,
266           &g_omnibox_trial_default_group_number));
267   omnibox_prerender_trial->AppendGroup("OmniboxPrerenderDisabled",
268                                        kDisabledProbability);
269 }
270 
IsOmniboxEnabled(Profile * profile)271 bool IsOmniboxEnabled(Profile* profile) {
272   if (!profile)
273     return false;
274 
275   if (!PrerenderManager::IsPrerenderingPossible())
276     return false;
277 
278   // Override any field trial groups if the user has set a command line flag.
279   if (CommandLine::ForCurrentProcess()->HasSwitch(
280       switches::kPrerenderFromOmnibox)) {
281     const string switch_value =
282         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
283             switches::kPrerenderFromOmnibox);
284 
285     if (switch_value == switches::kPrerenderFromOmniboxSwitchValueEnabled)
286       return true;
287 
288     if (switch_value == switches::kPrerenderFromOmniboxSwitchValueDisabled)
289       return false;
290 
291     DCHECK_EQ(switches::kPrerenderFromOmniboxSwitchValueAuto, switch_value);
292   }
293 
294   const int group = FieldTrialList::FindValue(kOmniboxTrialName);
295   return group == FieldTrial::kNotFinalized ||
296          group == g_omnibox_trial_default_group_number;
297 }
298 
299 /*
300 PrerenderLocalPredictorSpec is a field trial, and its value must have the
301 following format:
302 key1=value1:key2=value2:key3=value3
303 eg "LocalPredictor=Enabled:SideEffectFreeWhitelist=Enabled"
304 The function below extracts the value corresponding to a key provided from the
305 LocalPredictorSpec.
306 */
GetLocalPredictorSpecValue(string spec_key)307 string GetLocalPredictorSpecValue(string spec_key) {
308   vector<string> elements;
309   base::SplitString(FieldTrialList::FindFullName(kLocalPredictorSpecTrialName),
310                     ':', &elements);
311   for (int i = 0; i < static_cast<int>(elements.size()); i++) {
312     vector<string> key_value;
313     base::SplitString(elements[i], '=', &key_value);
314     if (key_value.size() == 2 && key_value[0] == spec_key)
315       return key_value[1];
316   }
317   return string();
318 }
319 
IsUnencryptedSyncEnabled(Profile * profile)320 bool IsUnencryptedSyncEnabled(Profile* profile) {
321   ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
322       GetForProfile(profile);
323   return service && service->GetOpenTabsUIDelegate() &&
324       !service->EncryptEverythingEnabled();
325 }
326 
327 // Indicates whether the Local Predictor is enabled based on field trial
328 // selection.
IsLocalPredictorEnabled()329 bool IsLocalPredictorEnabled() {
330 #if defined(OS_ANDROID) || defined(OS_IOS)
331   return false;
332 #endif
333   return
334       !CommandLine::ForCurrentProcess()->HasSwitch(
335           switches::kDisablePrerenderLocalPredictor) &&
336       GetLocalPredictorSpecValue(kLocalPredictorKeyName) == kEnabledGroup;
337 }
338 
ShouldDisableLocalPredictorBasedOnSyncAndConfiguration(Profile * profile)339 bool ShouldDisableLocalPredictorBasedOnSyncAndConfiguration(Profile* profile) {
340   return
341       GetLocalPredictorSpecValue(kLocalPredictorUnencryptedSyncOnlyKeyName) ==
342           kEnabledGroup &&
343       !IsUnencryptedSyncEnabled(profile);
344 }
345 
ShouldDisableLocalPredictorDueToPreferencesAndNetwork(Profile * profile)346 bool ShouldDisableLocalPredictorDueToPreferencesAndNetwork(Profile* profile) {
347   bool on_cellular =
348       net::NetworkChangeNotifier::IsConnectionCellular(
349           net::NetworkChangeNotifier::GetConnectionType());
350   // If the user is not on a cellular connection, but we require a cellular
351   // connection, we must temporarily disable our local predictions.
352   if (!on_cellular &&
353       GetLocalPredictorSpecValue(kLocalPredictorOnCellularOnly) ==
354       kEnabledGroup) {
355     return true;
356   }
357 
358   // If we don't care whether or not network prediction will actually be
359   // exercised, we do not need to temporarily disable our predictions.
360   if (GetLocalPredictorSpecValue(kLocalPredictorNetworkPredictionEnabledOnly) !=
361       kEnabledGroup) {
362     return false;
363   }
364 
365   // We should temporarily disable iff the predictive network action would
366   // not be exercised.
367 
368   return !chrome_browser_net::CanPrefetchAndPrerenderUI(profile->GetPrefs());
369 }
370 
IsLoggedInPredictorEnabled()371 bool IsLoggedInPredictorEnabled() {
372   return IsLocalPredictorEnabled();
373 }
374 
IsSideEffectFreeWhitelistEnabled()375 bool IsSideEffectFreeWhitelistEnabled() {
376   return IsLocalPredictorEnabled() &&
377       GetLocalPredictorSpecValue(kSideEffectFreeWhitelistKeyName) !=
378       kDisabledGroup;
379 }
380 
IsLocalPredictorPrerenderLaunchEnabled()381 bool IsLocalPredictorPrerenderLaunchEnabled() {
382   return GetLocalPredictorSpecValue(kPrerenderLaunchKeyName) != kDisabledGroup;
383 }
384 
IsLocalPredictorPrerenderAlwaysControlEnabled()385 bool IsLocalPredictorPrerenderAlwaysControlEnabled() {
386   // If we prefetch rather than prerender, we automatically also prerender
387   // as a control group only.
388   return (GetLocalPredictorSpecValue(kPrerenderAlwaysControlKeyName) ==
389           kEnabledGroup) || IsLocalPredictorPrerenderPrefetchEnabled();
390 }
391 
IsLocalPredictorPrerenderPrefetchEnabled()392 bool IsLocalPredictorPrerenderPrefetchEnabled() {
393   return GetLocalPredictorSpecValue(kPrerenderPrefetchKeyName) ==
394       kEnabledGroup;
395 }
396 
ShouldQueryPrerenderService(Profile * profile)397 bool ShouldQueryPrerenderService(Profile* profile) {
398   return IsUnencryptedSyncEnabled(profile) &&
399       GetLocalPredictorSpecValue(kPrerenderQueryPrerenderServiceKeyName) ==
400       kEnabledGroup;
401 }
402 
ShouldQueryPrerenderServiceForCurrentURL()403 bool ShouldQueryPrerenderServiceForCurrentURL() {
404   return GetLocalPredictorSpecValue(
405       kPrerenderQueryPrerenderServiceCurrentURLKeyName) != kDisabledGroup;
406 }
407 
ShouldQueryPrerenderServiceForCandidateURLs()408 bool ShouldQueryPrerenderServiceForCandidateURLs() {
409   return GetLocalPredictorSpecValue(
410       kPrerenderQueryPrerenderServiceCandidateURLsKeyName) != kDisabledGroup;
411 }
412 
GetPrerenderServiceURLPrefix()413 string GetPrerenderServiceURLPrefix() {
414   string prefix = variations::GetVariationParamValue(
415       kLocalPredictorSpecTrialName,
416       kPrerenderServiceURLPrefixParameterName);
417   return prefix.empty() ? kDefaultPrerenderServiceURLPrefix : prefix;
418 }
419 
GetPrerenderServiceBehaviorID()420 int GetPrerenderServiceBehaviorID() {
421   int id;
422   StringToInt(GetLocalPredictorSpecValue(kPrerenderServiceBehaviorIDKeyName),
423               &id);
424   // The behavior ID must be non-negative.
425   return std::max(id, 0);
426 }
427 
GetPrerenderServiceFetchTimeoutMs()428 int GetPrerenderServiceFetchTimeoutMs() {
429   int result;
430   StringToInt(GetLocalPredictorSpecValue(kPrerenderServiceFetchTimeoutKeyName),
431               &result);
432   // If the value is outside the valid range, use the default value.
433   return (result < kMinPrerenderServiceTimeoutMs ||
434           result > kMaxPrerenderServiceTimeoutMs) ?
435       kDefaultPrerenderServiceTimeoutMs : result;
436 }
437 
GetPrerenderPrefetchListTimeoutSeconds()438 int GetPrerenderPrefetchListTimeoutSeconds() {
439   int result;
440   StringToInt(GetLocalPredictorSpecValue(kPrefetchListTimeoutKeyName), &result);
441   // If the value is outside the valid range, use the default value.
442   return (result < kMinPrefetchListTimeoutSeconds ||
443           result > kMaxPrefetchListTimeoutSeconds) ?
444       kDefaultPrefetchListTimeoutSeconds : result;
445 }
446 
GetLocalPredictorTTLSeconds()447 int GetLocalPredictorTTLSeconds() {
448   int ttl;
449   StringToInt(GetLocalPredictorSpecValue(kPrerenderTTLKeyName), &ttl);
450   // If the value is outside of 10s or 600s, use a default value of 180s.
451   return (ttl < 10 || ttl > 600) ? 180 : ttl;
452 }
453 
GetLocalPredictorPrerenderPriorityHalfLifeTimeSeconds()454 int GetLocalPredictorPrerenderPriorityHalfLifeTimeSeconds() {
455   int half_life_time;
456   StringToInt(GetLocalPredictorSpecValue(kPrerenderPriorityHalfLifeTimeKeyName),
457               &half_life_time);
458   // Sanity check: Ensure the half life time is non-negative.
459   return std::max(half_life_time, 0);
460 }
461 
GetLocalPredictorMaxConcurrentPrerenders()462 int GetLocalPredictorMaxConcurrentPrerenders() {
463   int num_prerenders;
464   StringToInt(GetLocalPredictorSpecValue(kMaxConcurrentPrerenderKeyName),
465               &num_prerenders);
466   // Sanity check: Ensure the number of prerenders is between 1 and 10.
467   return std::min(std::max(num_prerenders, 1), 10);
468 }
469 
GetLocalPredictorMaxLaunchPrerenders()470 int GetLocalPredictorMaxLaunchPrerenders() {
471   int num_prerenders;
472   StringToInt(GetLocalPredictorSpecValue(kMaxLaunchPrerenderKeyName),
473               &num_prerenders);
474   // Sanity check: Ensure the number of prerenders is between 1 and 10.
475   return std::min(std::max(num_prerenders, 1), 10);
476 }
477 
SkipLocalPredictorFragment()478 bool SkipLocalPredictorFragment() {
479   return GetLocalPredictorSpecValue(kSkipFragment) == kEnabledGroup;
480 }
481 
SkipLocalPredictorHTTPS()482 bool SkipLocalPredictorHTTPS() {
483   return GetLocalPredictorSpecValue(kSkipHTTPS) == kEnabledGroup;
484 }
485 
SkipLocalPredictorWhitelist()486 bool SkipLocalPredictorWhitelist() {
487   return GetLocalPredictorSpecValue(kSkipWhitelist) == kEnabledGroup;
488 }
489 
SkipLocalPredictorServiceWhitelist()490 bool SkipLocalPredictorServiceWhitelist() {
491   return GetLocalPredictorSpecValue(kSkipServiceWhitelist) == kEnabledGroup;
492 }
493 
SkipLocalPredictorLoggedIn()494 bool SkipLocalPredictorLoggedIn() {
495   return GetLocalPredictorSpecValue(kSkipLoggedIn) == kEnabledGroup;
496 }
497 
SkipLocalPredictorDefaultNoPrerender()498 bool SkipLocalPredictorDefaultNoPrerender() {
499   return GetLocalPredictorSpecValue(kSkipDefaultNoPrerender) == kEnabledGroup;
500 }
501 
SkipLocalPredictorLocalCandidates()502 bool SkipLocalPredictorLocalCandidates() {
503   return GetLocalPredictorSpecValue(kSkipPrerenderLocalCanadidates) ==
504       kEnabledGroup;
505 }
506 
SkipLocalPredictorServiceCandidates()507 bool SkipLocalPredictorServiceCandidates() {
508   return GetLocalPredictorSpecValue(kSkipPrerenderServiceCanadidates) ==
509       kEnabledGroup;
510 }
511 
ShouldMergeSessionStorageNamespaces()512 bool ShouldMergeSessionStorageNamespaces() {
513   return GetLocalPredictorSpecValue(kDisableSessionStorageNamespaceMerging) !=
514       kDisabledGroup;
515 }
516 
IsPrerenderCookieStoreEnabled()517 bool IsPrerenderCookieStoreEnabled() {
518   return GetLocalPredictorSpecValue(kPrerenderCookieStore) != kDisabledGroup &&
519       FieldTrialList::FindFullName(kPrerenderCookieStore) != kDisabledGroup;
520 }
521 
522 }  // namespace prerender
523