15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_field_trial.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/field_trial.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/strings/string_split.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/metrics/metrics_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/predictors/autocomplete_action_predictor.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::FieldTrial;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::FieldTrialList;
232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochusing base::SplitStringUsingSubstr;
242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochusing base::StringToInt;
252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochusing std::string;
262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochusing std::vector;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace prerender {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOmniboxTrialName[] = "PrerenderFromOmnibox";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int g_omnibox_trial_default_group_number = kint32min;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kDisabledGroup[] = "Disabled";
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kEnabledGroup[] = "Enabled";
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kLocalPredictorSpecTrialName[] = "PrerenderLocalPredictorSpec";
392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kLocalPredictorKeyName[] = "LocalPredictor";
402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kSideEffectFreeWhitelistKeyName[] = "SideEffectFreeWhitelist";
412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kPrerenderLaunchKeyName[] = "PrerenderLaunch";
422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kPrerenderAlwaysControlKeyName[] = "PrerenderAlwaysControl";
432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kPrerenderTTLKeyName[] = "PrerenderTTLSeconds";
442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kPrerenderPriorityHalfLifeTimeKeyName[] =
452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    "PrerenderPriorityHalfLifeTimeSeconds";
462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kMaxConcurrentPrerenderKeyName[] = "MaxConcurrentPrerenders";
472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kSkipFragment[] = "SkipFragment";
482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kSkipHTTPS[] = "SkipHTTPS";
492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kSkipWhitelist[] = "SkipWhitelist";
502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kSkipLoggedIn[] = "SkipLoggedIn";
512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kSkipDefaultNoPrerender[] = "SkipDefaultNoPrerender";
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetupPrefetchFieldTrial() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel == chrome::VersionInfo::CHANNEL_BETA) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldTrial::Probability divisor = 1000;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldTrial::Probability prefetch_probability = 500;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FieldTrial> trial(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FieldTrialList::FactoryGetFieldTrial(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Prefetch", divisor, "ContentPrefetchPrefetchOff",
65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          2013, 12, 31, FieldTrial::SESSION_RANDOMIZED, NULL));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kPrefetchOnGroup = trial->AppendGroup("ContentPrefetchPrefetchOn",
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  prefetch_probability);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrerenderManager::SetIsPrefetchEnabled(trial->group() == kPrefetchOnGroup);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetupPrerenderFieldTrial() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldTrial::Probability divisor = 1000;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldTrial::Probability control_probability;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldTrial::Probability experiment_multi_prerender_probability;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldTrial::Probability experiment_15min_ttl_probability;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldTrial::Probability experiment_no_use_probability;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel == chrome::VersionInfo::CHANNEL_BETA) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use very conservatives and stable settings in beta and stable.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability release_prerender_enabled_probability = 980;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability release_control_probability = 10;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_experiment_multi_prerender_probability = 0;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability release_experiment_15min_ttl_probability = 10;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability release_experiment_no_use_probability = 0;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COMPILE_ASSERT(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_prerender_enabled_probability + release_control_probability +
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_experiment_multi_prerender_probability +
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_experiment_15min_ttl_probability +
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_experiment_no_use_probability == divisor,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_experiment_probabilities_must_equal_divisor);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    control_probability = release_control_probability;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    experiment_multi_prerender_probability =
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_experiment_multi_prerender_probability;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    experiment_15min_ttl_probability = release_experiment_15min_ttl_probability;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    experiment_no_use_probability = release_experiment_no_use_probability;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In testing channels, use more experiments and a larger control group to
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // improve quality of data.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability dev_prerender_enabled_probability = 250;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability dev_control_probability = 250;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dev_experiment_multi_prerender_probability = 250;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability dev_experiment_15min_ttl_probability = 125;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldTrial::Probability dev_experiment_no_use_probability = 125;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COMPILE_ASSERT(dev_prerender_enabled_probability + dev_control_probability +
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   dev_experiment_multi_prerender_probability +
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   dev_experiment_15min_ttl_probability +
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   dev_experiment_no_use_probability == divisor,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   dev_experiment_probabilities_must_equal_divisor);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    control_probability = dev_control_probability;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    experiment_multi_prerender_probability =
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dev_experiment_multi_prerender_probability;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    experiment_15min_ttl_probability = dev_experiment_15min_ttl_probability;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    experiment_no_use_probability = dev_experiment_no_use_probability;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int prerender_enabled_group = -1;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FieldTrial> trial(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FieldTrialList::FactoryGetFieldTrial(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Prerender", divisor, "PrerenderEnabled",
127d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          2013, 12, 31, FieldTrial::SESSION_RANDOMIZED,
128d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          &prerender_enabled_group));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int control_group =
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trial->AppendGroup("PrerenderControl",
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         control_probability);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int experiment_multi_prerender_group =
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trial->AppendGroup("PrerenderMulti",
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         experiment_multi_prerender_probability);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int experiment_15_min_TTL_group =
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trial->AppendGroup("Prerender15minTTL",
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         experiment_15min_ttl_probability);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int experiment_no_use_group =
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trial->AppendGroup("PrerenderNoUse",
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         experiment_no_use_probability);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int trial_group = trial->group();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (trial_group == prerender_enabled_group) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrerenderManager::SetMode(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (trial_group == control_group) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrerenderManager::SetMode(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (trial_group == experiment_multi_prerender_group) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrerenderManager::SetMode(
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (trial_group == experiment_15_min_TTL_group) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrerenderManager::SetMode(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PrerenderManager::PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (trial_group == experiment_no_use_group) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrerenderManager::SetMode(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PrerenderManager::PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // end namespace
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfigureOmniboxPrerender();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfigurePrefetchAndPrerender(const CommandLine& command_line) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum PrerenderOption {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRERENDER_OPTION_AUTO,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRERENDER_OPTION_DISABLED,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRERENDER_OPTION_ENABLED,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRERENDER_OPTION_PREFETCH_ONLY,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kPrerenderMode)) {
1772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const string switch_value =
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_line.GetSwitchValueASCII(switches::kPrerenderMode);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (switch_value == switches::kPrerenderModeSwitchValueAuto) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prerender_option = PRERENDER_OPTION_AUTO;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (switch_value == switches::kPrerenderModeSwitchValueDisabled) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prerender_option = PRERENDER_OPTION_DISABLED;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (switch_value.empty() ||
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               switch_value == switches::kPrerenderModeSwitchValueEnabled) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The empty string means the option was provided with no value, and that
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // means enable.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prerender_option = PRERENDER_OPTION_ENABLED;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (switch_value ==
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               switches::kPrerenderModeSwitchValuePrefetchOnly) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prerender_option = PRERENDER_OPTION_PREFETCH_ONLY;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prerender_option = PRERENDER_OPTION_DISABLED;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid --prerender option received on command line: "
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << switch_value;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Disabling prerendering!";
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (prerender_option) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PRERENDER_OPTION_AUTO:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetupPrefetchFieldTrial();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetupPrerenderFieldTrial();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PRERENDER_OPTION_DISABLED:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PrerenderManager::SetIsPrefetchEnabled(false);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PRERENDER_OPTION_ENABLED:
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PrerenderManager::SetIsPrefetchEnabled(true);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PRERENDER_OPTION_PREFETCH_ONLY:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PrerenderManager::SetIsPrefetchEnabled(true);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigureOmniboxPrerender();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfigureOmniboxPrerender() {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Field trial to see if we're enabled.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldTrial::Probability kDivisor = 100;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldTrial::Probability kDisabledProbability = 10;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel == chrome::VersionInfo::CHANNEL_BETA) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kDisabledProbability = 1;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FieldTrial> omnibox_prerender_trial(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FieldTrialList::FactoryGetFieldTrial(
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kOmniboxTrialName, kDivisor, "OmniboxPrerenderEnabled",
237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          2013, 12, 31, FieldTrial::SESSION_RANDOMIZED,
238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          &g_omnibox_trial_default_group_number));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  omnibox_prerender_trial->AppendGroup("OmniboxPrerenderDisabled",
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       kDisabledProbability);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsOmniboxEnabled(Profile* profile) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!profile)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!PrerenderManager::IsPrerenderingPossible())
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override any field trial groups if the user has set a command line flag.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kPrerenderFromOmnibox)) {
2532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const string switch_value =
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            switches::kPrerenderFromOmnibox);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueEnabled)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueDisabled)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(switch_value == switches::kPrerenderFromOmniboxSwitchValueAuto);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int group = FieldTrialList::FindValue(kOmniboxTrialName);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return group == FieldTrial::kNotFinalized ||
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         group == g_omnibox_trial_default_group_number;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch/*
2722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochPrerenderLocalPredictorSpec is a field trial, and its value must have the
2732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochfollowing format:
2742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochkey1=value1:key2=value2:key3=value3
2752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdocheg "LocalPredictor=Enabled:SideEffectFreeWhitelist=Enabled"
2762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochThe function below extracts the value corresponding to a key provided from the
2772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochLocalPredictorSpec.
2782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch*/
2792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstring GetLocalPredictorSpecValue(string spec_key) {
2802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  vector<string> elements;
2812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SplitStringUsingSubstr(
2822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      FieldTrialList::FindFullName(kLocalPredictorSpecTrialName),
2832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      ":",
2842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      &elements);
2852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (int i = 0; i < static_cast<int>(elements.size()); i++) {
2862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    vector<string> key_value;
2872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SplitStringUsingSubstr(elements[i], "=", &key_value);
2882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (key_value.size() == 2 && key_value[0] == spec_key)
2892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return key_value[1];
2902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return string();
2922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
2932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsLocalPredictorEnabled() {
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_IOS)
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return false;
297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif
298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          switches::kDisablePrerenderLocalPredictor)) {
300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return false;
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
3022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kLocalPredictorKeyName) == kEnabledGroup;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IsLoggedInPredictorEnabled() {
3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return IsLocalPredictorEnabled();
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IsSideEffectFreeWhitelistEnabled() {
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return IsLocalPredictorEnabled() &&
3112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      GetLocalPredictorSpecValue(kSideEffectFreeWhitelistKeyName) !=
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kDisabledGroup;
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool IsLocalPredictorPrerenderLaunchEnabled() {
3162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kPrerenderLaunchKeyName) != kDisabledGroup;
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool IsLocalPredictorPrerenderAlwaysControlEnabled() {
3202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kPrerenderAlwaysControlKeyName) ==
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kEnabledGroup;
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int GetLocalPredictorTTLSeconds() {
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int ttl;
3262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringToInt(GetLocalPredictorSpecValue(kPrerenderTTLKeyName), &ttl);
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If the value is outside of 10s or 600s, use a default value of 180s.
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (ttl < 10 || ttl > 600)
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ttl = 180;
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return ttl;
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int GetLocalPredictorPrerenderPriorityHalfLifeTimeSeconds() {
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int half_life_time;
3352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringToInt(GetLocalPredictorSpecValue(kPrerenderPriorityHalfLifeTimeKeyName),
3362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch              &half_life_time);
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Sanity check: Ensure the half life time is non-negative.
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (half_life_time < 0)
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    half_life_time = 0;
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return half_life_time;
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int GetLocalPredictorMaxConcurrentPrerenders() {
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int num_prerenders;
3452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringToInt(GetLocalPredictorSpecValue(kMaxConcurrentPrerenderKeyName),
3462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch              &num_prerenders);
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Sanity check: Ensure the number of prerenders is at least 1.
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (num_prerenders < 1)
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    num_prerenders = 1;
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Sanity check: Ensure the number of prerenders is at most 10.
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (num_prerenders > 10)
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    num_prerenders = 10;
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return num_prerenders;
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool SkipLocalPredictorFragment() {
3572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kSkipFragment) == kEnabledGroup;
3582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool SkipLocalPredictorHTTPS() {
3612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kSkipHTTPS) == kEnabledGroup;
3622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool SkipLocalPredictorWhitelist() {
3652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kSkipWhitelist) == kEnabledGroup;
3662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool SkipLocalPredictorLoggedIn() {
3692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kSkipLoggedIn) == kEnabledGroup;
3702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool SkipLocalPredictorDefaultNoPrerender() {
3732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return GetLocalPredictorSpecValue(kSkipDefaultNoPrerender) == kEnabledGroup;
3742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace prerender
377