omnibox_field_trial.cc revision d3868032626d59662ff73b372b5d584c1d144c53
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/omnibox/omnibox_field_trial.h" 6 7#include <string> 8 9#include "base/metrics/field_trial.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/strings/string_util.h" 12#include "base/strings/stringprintf.h" 13#include "chrome/common/metrics/metrics_util.h" 14#include "chrome/common/metrics/variations/variation_ids.h" 15#include "chrome/common/metrics/variations/variations_util.h" 16 17namespace { 18 19// Field trial names. 20const char kHUPCullRedirectsFieldTrialName[] = "OmniboxHUPCullRedirects"; 21const char kHUPCreateShorterMatchFieldTrialName[] = 22 "OmniboxHUPCreateShorterMatch"; 23const char kStopTimerFieldTrialName[] = "OmniboxStopTimer"; 24const char kShortcutsScoringFieldTrialName[] = "OmniboxShortcutsScoring"; 25const char kSearchHistoryFieldTrialName[] = "OmniboxSearchHistory"; 26 27// The autocomplete dynamic field trial name prefix. Each field trial is 28// configured dynamically and is retrieved automatically by Chrome during 29// the startup. 30const char kAutocompleteDynamicFieldTrialPrefix[] = "AutocompleteDynamicTrial_"; 31// The maximum number of the autocomplete dynamic field trials (aka layers). 32const int kMaxAutocompleteDynamicFieldTrials = 5; 33 34// Field trial experiment probabilities. 35 36// For HistoryURL provider cull redirects field trial, put 0% ( = 0/100 ) 37// of the users in the don't-cull-redirects experiment group. 38// TODO(mpearson): Remove this field trial and the code it uses once I'm 39// sure it's no longer needed. 40const base::FieldTrial::Probability kHUPCullRedirectsFieldTrialDivisor = 100; 41const base::FieldTrial::Probability 42 kHUPCullRedirectsFieldTrialExperimentFraction = 0; 43 44// For HistoryURL provider create shorter match field trial, put 0% 45// ( = 25/100 ) of the users in the don't-create-a-shorter-match 46// experiment group. 47// TODO(mpearson): Remove this field trial and the code it uses once I'm 48// sure it's no longer needed. 49const base::FieldTrial::Probability 50 kHUPCreateShorterMatchFieldTrialDivisor = 100; 51const base::FieldTrial::Probability 52 kHUPCreateShorterMatchFieldTrialExperimentFraction = 0; 53 54// Experiment group names. 55 56const char kStopTimerExperimentGroupName[] = "UseStopTimer"; 57 58// Field trial IDs. 59// Though they are not literally "const", they are set only once, in 60// ActivateStaticTrials() below. 61 62// Whether the static field trials have been initialized by 63// ActivateStaticTrials() method. 64bool static_field_trials_initialized = false; 65 66// Field trial ID for the HistoryURL provider cull redirects experiment group. 67int hup_dont_cull_redirects_experiment_group = 0; 68 69// Field trial ID for the HistoryURL provider create shorter match 70// experiment group. 71int hup_dont_create_shorter_match_experiment_group = 0; 72 73 74// Concatenates the autocomplete dynamic field trial prefix with a field trial 75// ID to form a complete autocomplete field trial name. 76std::string DynamicFieldTrialName(int id) { 77 return base::StringPrintf("%s%d", kAutocompleteDynamicFieldTrialPrefix, id); 78} 79 80} // namespace 81 82 83void OmniboxFieldTrial::ActivateStaticTrials() { 84 DCHECK(!static_field_trials_initialized); 85 86 // Create the HistoryURL provider cull redirects field trial. 87 // Make it expire on March 1, 2013. 88 scoped_refptr<base::FieldTrial> trial( 89 base::FieldTrialList::FactoryGetFieldTrial( 90 kHUPCullRedirectsFieldTrialName, kHUPCullRedirectsFieldTrialDivisor, 91 "Standard", 2013, 3, 1, base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); 92 hup_dont_cull_redirects_experiment_group = 93 trial->AppendGroup("DontCullRedirects", 94 kHUPCullRedirectsFieldTrialExperimentFraction); 95 96 // Create the HistoryURL provider create shorter match field trial. 97 // Make it expire on March 1, 2013. 98 trial = base::FieldTrialList::FactoryGetFieldTrial( 99 kHUPCreateShorterMatchFieldTrialName, 100 kHUPCreateShorterMatchFieldTrialDivisor, "Standard", 2013, 3, 1, 101 base::FieldTrial::ONE_TIME_RANDOMIZED, NULL); 102 hup_dont_create_shorter_match_experiment_group = 103 trial->AppendGroup("DontCreateShorterMatch", 104 kHUPCreateShorterMatchFieldTrialExperimentFraction); 105 106 static_field_trials_initialized = true; 107} 108 109void OmniboxFieldTrial::ActivateDynamicTrials() { 110 // Initialize all autocomplete dynamic field trials. This method may be 111 // called multiple times. 112 for (int i = 0; i < kMaxAutocompleteDynamicFieldTrials; ++i) 113 base::FieldTrialList::FindValue(DynamicFieldTrialName(i)); 114} 115 116int OmniboxFieldTrial::GetDisabledProviderTypes() { 117 // Make sure that Autocomplete dynamic field trials are activated. It's OK to 118 // call this method multiple times. 119 ActivateDynamicTrials(); 120 121 // Look for group names in form of "DisabledProviders_<mask>" where "mask" 122 // is a bitmap of disabled provider types (AutocompleteProvider::Type). 123 int provider_types = 0; 124 for (int i = 0; i < kMaxAutocompleteDynamicFieldTrials; ++i) { 125 std::string group_name = base::FieldTrialList::FindFullName( 126 DynamicFieldTrialName(i)); 127 const char kDisabledProviders[] = "DisabledProviders_"; 128 if (!StartsWithASCII(group_name, kDisabledProviders, true)) 129 continue; 130 int types = 0; 131 if (!base::StringToInt(base::StringPiece( 132 group_name.substr(strlen(kDisabledProviders))), &types)) { 133 LOG(WARNING) << "Malformed DisabledProviders string: " << group_name; 134 continue; 135 } 136 if (types == 0) 137 LOG(WARNING) << "Expecting a non-zero bitmap; group = " << group_name; 138 else 139 provider_types |= types; 140 } 141 return provider_types; 142} 143 144void OmniboxFieldTrial::GetActiveSuggestFieldTrialHashes( 145 std::vector<uint32>* field_trial_hashes) { 146 field_trial_hashes->clear(); 147 for (int i = 0; i < kMaxAutocompleteDynamicFieldTrials; ++i) { 148 const std::string& trial_name = DynamicFieldTrialName(i); 149 if (base::FieldTrialList::TrialExists(trial_name)) 150 field_trial_hashes->push_back(metrics::HashName(trial_name)); 151 } 152} 153 154bool OmniboxFieldTrial::InHUPCullRedirectsFieldTrial() { 155 return base::FieldTrialList::TrialExists(kHUPCullRedirectsFieldTrialName); 156} 157 158bool OmniboxFieldTrial::InHUPCullRedirectsFieldTrialExperimentGroup() { 159 if (!base::FieldTrialList::TrialExists(kHUPCullRedirectsFieldTrialName)) 160 return false; 161 162 // Return true if we're in the experiment group. 163 const int group = base::FieldTrialList::FindValue( 164 kHUPCullRedirectsFieldTrialName); 165 return group == hup_dont_cull_redirects_experiment_group; 166} 167 168bool OmniboxFieldTrial::InHUPCreateShorterMatchFieldTrial() { 169 return 170 base::FieldTrialList::TrialExists(kHUPCreateShorterMatchFieldTrialName); 171} 172 173bool OmniboxFieldTrial::InHUPCreateShorterMatchFieldTrialExperimentGroup() { 174 if (!base::FieldTrialList::TrialExists(kHUPCreateShorterMatchFieldTrialName)) 175 return false; 176 177 // Return true if we're in the experiment group. 178 const int group = base::FieldTrialList::FindValue( 179 kHUPCreateShorterMatchFieldTrialName); 180 return group == hup_dont_create_shorter_match_experiment_group; 181} 182 183bool OmniboxFieldTrial::InStopTimerFieldTrialExperimentGroup() { 184 return (base::FieldTrialList::FindFullName(kStopTimerFieldTrialName) == 185 kStopTimerExperimentGroupName); 186} 187 188bool OmniboxFieldTrial::InZeroSuggestFieldTrial() { 189 // Make sure that Autocomplete dynamic field trials are activated. It's OK to 190 // call this method multiple times. 191 ActivateDynamicTrials(); 192 193 // Look for group names starting with "EnableZeroSuggest" 194 for (int i = 0; i < kMaxAutocompleteDynamicFieldTrials; ++i) { 195 const std::string& group_name = base::FieldTrialList::FindFullName( 196 DynamicFieldTrialName(i)); 197 const char kEnableZeroSuggest[] = "EnableZeroSuggest"; 198 if (StartsWithASCII(group_name, kEnableZeroSuggest, true)) 199 return true; 200 } 201 return false; 202} 203 204// If the active group name starts with "MaxRelevance_", extract the 205// int that immediately following that, returning true on success. 206bool OmniboxFieldTrial::ShortcutsScoringMaxRelevance(int* max_relevance) { 207 std::string group_name = 208 base::FieldTrialList::FindFullName(kShortcutsScoringFieldTrialName); 209 const char kMaxRelevanceGroupPrefix[] = "MaxRelevance_"; 210 if (!StartsWithASCII(group_name, kMaxRelevanceGroupPrefix, true)) 211 return false; 212 if (!base::StringToInt(base::StringPiece( 213 group_name.substr(strlen(kMaxRelevanceGroupPrefix))), 214 max_relevance)) { 215 LOG(WARNING) << "Malformed MaxRelevance string: " << group_name; 216 return false; 217 } 218 return true; 219} 220 221bool OmniboxFieldTrial::SearchHistoryPreventInlining() { 222 return (base::FieldTrialList::FindFullName(kSearchHistoryFieldTrialName) == 223 "PreventInlining"); 224} 225 226bool OmniboxFieldTrial::SearchHistoryDisable() { 227 return (base::FieldTrialList::FindFullName(kSearchHistoryFieldTrialName) == 228 "Disable"); 229} 230