| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/instant/instant_field_trial.h" | 5 #include "chrome/browser/instant/instant_field_trial.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "chrome/browser/metrics/metrics_service.h" | 9 #include "chrome/browser/metrics/metrics_service.h" |
| 10 #include "chrome/browser/prefs/pref_service.h" | 10 #include "chrome/browser/prefs/pref_service.h" |
| 11 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
| 12 #include "chrome/common/chrome_switches.h" | 12 #include "chrome/common/chrome_switches.h" |
| 13 #include "chrome/common/pref_names.h" | 13 #include "chrome/common/pref_names.h" |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 // Field trial IDs of the control and experiment groups. Though they are not | 17 // Field trial IDs of the control and experiment groups. Though they are not |
| 18 // literally "const", they are set only once, in Activate() below. See the .h | 18 // literally "const", they are set only once, in Activate() below. See the .h |
| 19 // file for what these groups represent. | 19 // file for what these groups represent. |
| 20 int g_instant_experiment_a = 0; | 20 int g_instant_experiment_a = 0; |
| 21 int g_instant_experiment_b = 0; | 21 int g_instant_experiment_b = 0; |
| 22 |
| 22 int g_hidden_experiment_a = 0; | 23 int g_hidden_experiment_a = 0; |
| 23 int g_hidden_experiment_b = 0; | 24 int g_hidden_experiment_b = 0; |
| 25 |
| 24 int g_silent_experiment_a = 0; | 26 int g_silent_experiment_a = 0; |
| 25 int g_silent_experiment_b = 0; | 27 int g_silent_experiment_b = 0; |
| 26 | 28 |
| 29 int g_suggest_experiment_a = 0; |
| 30 int g_suggest_experiment_b = 0; |
| 31 |
| 27 int g_uma_control_a = 0; | 32 int g_uma_control_a = 0; |
| 28 int g_uma_control_b = 0; | 33 int g_uma_control_b = 0; |
| 34 |
| 29 int g_all_control_a = 0; | 35 int g_all_control_a = 0; |
| 30 int g_all_control_b = 0; | 36 int g_all_control_b = 0; |
| 31 | 37 |
| 32 } | 38 } |
| 33 | 39 |
| 34 // static | 40 // static |
| 35 void InstantFieldTrial::Activate() { | 41 void InstantFieldTrial::Activate() { |
| 36 scoped_refptr<base::FieldTrial> trial( | 42 scoped_refptr<base::FieldTrial> trial( |
| 37 new base::FieldTrial("Instant", 1000, "Inactive", 2012, 7, 1)); | 43 new base::FieldTrial("Instant", 1000, "Inactive", 2012, 7, 1)); |
| 38 | 44 |
| 39 // Try to give the user a consistent experience, if possible. | 45 // Try to give the user a consistent experience, if possible. |
| 40 if (base::FieldTrialList::IsOneTimeRandomizationEnabled()) | 46 if (base::FieldTrialList::IsOneTimeRandomizationEnabled()) |
| 41 trial->UseOneTimeRandomization(); | 47 trial->UseOneTimeRandomization(); |
| 42 | 48 |
| 43 // Each group is of total size 10% (5% each for the _a and _b variants). | 49 // Each group is of total size 10% (5% each for the _a and _b variants). |
| 44 g_instant_experiment_a = trial->AppendGroup("InstantExperimentA", 50); | 50 g_instant_experiment_a = trial->AppendGroup("InstantExperimentA", 50); |
| 45 g_instant_experiment_b = trial->AppendGroup("InstantExperimentB", 50); | 51 g_instant_experiment_b = trial->AppendGroup("InstantExperimentB", 50); |
| 52 |
| 46 g_hidden_experiment_a = trial->AppendGroup("HiddenExperimentA", 50); | 53 g_hidden_experiment_a = trial->AppendGroup("HiddenExperimentA", 50); |
| 47 g_hidden_experiment_b = trial->AppendGroup("HiddenExperimentB", 50); | 54 g_hidden_experiment_b = trial->AppendGroup("HiddenExperimentB", 50); |
| 55 |
| 48 g_silent_experiment_a = trial->AppendGroup("SilentExperimentA", 50); | 56 g_silent_experiment_a = trial->AppendGroup("SilentExperimentA", 50); |
| 49 g_silent_experiment_b = trial->AppendGroup("SilentExperimentB", 50); | 57 g_silent_experiment_b = trial->AppendGroup("SilentExperimentB", 50); |
| 50 | 58 |
| 59 g_suggest_experiment_a = trial->AppendGroup("SuggestExperimentA", 50); |
| 60 g_suggest_experiment_b = trial->AppendGroup("SuggestExperimentB", 50); |
| 61 |
| 51 g_uma_control_a = trial->AppendGroup("UmaControlA", 50); | 62 g_uma_control_a = trial->AppendGroup("UmaControlA", 50); |
| 52 g_uma_control_b = trial->AppendGroup("UmaControlB", 50); | 63 g_uma_control_b = trial->AppendGroup("UmaControlB", 50); |
| 64 |
| 53 g_all_control_a = trial->AppendGroup("AllControlA", 50); | 65 g_all_control_a = trial->AppendGroup("AllControlA", 50); |
| 54 g_all_control_b = trial->AppendGroup("AllControlB", 50); | 66 g_all_control_b = trial->AppendGroup("AllControlB", 50); |
| 55 } | 67 } |
| 56 | 68 |
| 57 // static | 69 // static |
| 58 InstantFieldTrial::Group InstantFieldTrial::GetGroup(Profile* profile) { | 70 InstantFieldTrial::Group InstantFieldTrial::GetGroup(Profile* profile) { |
| 59 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 71 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 60 if (command_line->HasSwitch(switches::kInstantFieldTrial)) { | 72 if (command_line->HasSwitch(switches::kInstantFieldTrial)) { |
| 61 std::string switch_value = | 73 std::string switch_value = |
| 62 command_line->GetSwitchValueASCII(switches::kInstantFieldTrial); | 74 command_line->GetSwitchValueASCII(switches::kInstantFieldTrial); |
| 63 if (switch_value == switches::kInstantFieldTrialInstant) | 75 if (switch_value == switches::kInstantFieldTrialInstant) |
| 64 return INSTANT_EXPERIMENT_A; | 76 return INSTANT_EXPERIMENT_A; |
| 65 else if (switch_value == switches::kInstantFieldTrialHidden) | 77 else if (switch_value == switches::kInstantFieldTrialHidden) |
| 66 return HIDDEN_EXPERIMENT_A; | 78 return HIDDEN_EXPERIMENT_A; |
| 67 else if (switch_value == switches::kInstantFieldTrialSilent) | 79 else if (switch_value == switches::kInstantFieldTrialSilent) |
| 68 return SILENT_EXPERIMENT_A; | 80 return SILENT_EXPERIMENT_A; |
| 81 else if (switch_value == switches::kInstantFieldTrialSuggest) |
| 82 return SUGGEST_EXPERIMENT_A; |
| 69 else | 83 else |
| 70 return INACTIVE; | 84 return INACTIVE; |
| 71 } | 85 } |
| 72 | 86 |
| 73 const int group = base::FieldTrialList::FindValue("Instant"); | 87 const int group = base::FieldTrialList::FindValue("Instant"); |
| 74 if (group == base::FieldTrial::kNotFinalized || | 88 if (group == base::FieldTrial::kNotFinalized || |
| 75 group == base::FieldTrial::kDefaultGroupNumber) { | 89 group == base::FieldTrial::kDefaultGroupNumber) { |
| 76 return INACTIVE; | 90 return INACTIVE; |
| 77 } | 91 } |
| 78 | 92 |
| 79 const PrefService* prefs = profile ? profile->GetPrefs() : NULL; | 93 const PrefService* prefs = profile ? profile->GetPrefs() : NULL; |
| 80 if (!prefs || | 94 if (!prefs || |
| 81 prefs->GetBoolean(prefs::kInstantEnabledOnce) || | 95 prefs->GetBoolean(prefs::kInstantEnabledOnce) || |
| 82 prefs->IsManagedPreference(prefs::kInstantEnabled)) { | 96 prefs->IsManagedPreference(prefs::kInstantEnabled)) { |
| 83 return INACTIVE; | 97 return INACTIVE; |
| 84 } | 98 } |
| 85 | 99 |
| 86 // First, deal with the groups that don't require UMA opt-in. | 100 // First, deal with the groups that don't require UMA opt-in. |
| 87 if (group == g_silent_experiment_a) | 101 if (group == g_silent_experiment_a) |
| 88 return SILENT_EXPERIMENT_A; | 102 return SILENT_EXPERIMENT_A; |
| 89 if (group == g_silent_experiment_b) | 103 if (group == g_silent_experiment_b) |
| 90 return SILENT_EXPERIMENT_B; | 104 return SILENT_EXPERIMENT_B; |
| 105 |
| 91 if (group == g_all_control_a) | 106 if (group == g_all_control_a) |
| 92 return ALL_CONTROL_A; | 107 return ALL_CONTROL_A; |
| 93 if (group == g_all_control_b) | 108 if (group == g_all_control_b) |
| 94 return ALL_CONTROL_B; | 109 return ALL_CONTROL_B; |
| 95 | 110 |
| 96 // All other groups require UMA and suggest, else bounce back to INACTIVE. | 111 // All other groups require UMA and suggest, else bounce back to INACTIVE. |
| 97 if (profile->IsOffTheRecord() || | 112 if (profile->IsOffTheRecord() || |
| 98 !MetricsServiceHelper::IsMetricsReportingEnabled() || | 113 !MetricsServiceHelper::IsMetricsReportingEnabled() || |
| 99 !prefs->GetBoolean(prefs::kSearchSuggestEnabled)) { | 114 !prefs->GetBoolean(prefs::kSearchSuggestEnabled)) { |
| 100 return INACTIVE; | 115 return INACTIVE; |
| 101 } | 116 } |
| 102 | 117 |
| 103 if (group == g_instant_experiment_a) | 118 if (group == g_instant_experiment_a) |
| 104 return INSTANT_EXPERIMENT_A; | 119 return INSTANT_EXPERIMENT_A; |
| 105 if (group == g_instant_experiment_b) | 120 if (group == g_instant_experiment_b) |
| 106 return INSTANT_EXPERIMENT_B; | 121 return INSTANT_EXPERIMENT_B; |
| 122 |
| 107 if (group == g_hidden_experiment_a) | 123 if (group == g_hidden_experiment_a) |
| 108 return HIDDEN_EXPERIMENT_A; | 124 return HIDDEN_EXPERIMENT_A; |
| 109 if (group == g_hidden_experiment_b) | 125 if (group == g_hidden_experiment_b) |
| 110 return HIDDEN_EXPERIMENT_B; | 126 return HIDDEN_EXPERIMENT_B; |
| 127 |
| 128 if (group == g_suggest_experiment_a) |
| 129 return SUGGEST_EXPERIMENT_A; |
| 130 if (group == g_suggest_experiment_b) |
| 131 return SUGGEST_EXPERIMENT_B; |
| 132 |
| 111 if (group == g_uma_control_a) | 133 if (group == g_uma_control_a) |
| 112 return UMA_CONTROL_A; | 134 return UMA_CONTROL_A; |
| 113 if (group == g_uma_control_b) | 135 if (group == g_uma_control_b) |
| 114 return UMA_CONTROL_B; | 136 return UMA_CONTROL_B; |
| 115 | 137 |
| 116 NOTREACHED(); | 138 NOTREACHED(); |
| 117 return INACTIVE; | 139 return INACTIVE; |
| 118 } | 140 } |
| 119 | 141 |
| 120 // static | 142 // static |
| 121 bool InstantFieldTrial::IsInstantExperiment(Profile* profile) { | 143 bool InstantFieldTrial::IsInstantExperiment(Profile* profile) { |
| 122 Group group = GetGroup(profile); | 144 Group group = GetGroup(profile); |
| 123 return group == INSTANT_EXPERIMENT_A || group == INSTANT_EXPERIMENT_B || | 145 return group == INSTANT_EXPERIMENT_A || group == INSTANT_EXPERIMENT_B || |
| 124 group == HIDDEN_EXPERIMENT_A || group == HIDDEN_EXPERIMENT_B || | 146 group == HIDDEN_EXPERIMENT_A || group == HIDDEN_EXPERIMENT_B || |
| 125 group == SILENT_EXPERIMENT_A || group == SILENT_EXPERIMENT_B; | 147 group == SILENT_EXPERIMENT_A || group == SILENT_EXPERIMENT_B || |
| 148 group == SUGGEST_EXPERIMENT_A || group == SUGGEST_EXPERIMENT_B; |
| 126 } | 149 } |
| 127 | 150 |
| 128 // static | 151 // static |
| 129 bool InstantFieldTrial::IsHiddenExperiment(Profile* profile) { | 152 bool InstantFieldTrial::IsHiddenExperiment(Profile* profile) { |
| 130 Group group = GetGroup(profile); | 153 Group group = GetGroup(profile); |
| 131 return group == HIDDEN_EXPERIMENT_A || group == HIDDEN_EXPERIMENT_B || | 154 return group == HIDDEN_EXPERIMENT_A || group == HIDDEN_EXPERIMENT_B || |
| 132 group == SILENT_EXPERIMENT_A || group == SILENT_EXPERIMENT_B; | 155 group == SILENT_EXPERIMENT_A || group == SILENT_EXPERIMENT_B || |
| 156 group == SUGGEST_EXPERIMENT_A || group == SUGGEST_EXPERIMENT_B; |
| 133 } | 157 } |
| 134 | 158 |
| 135 // static | 159 // static |
| 136 bool InstantFieldTrial::IsSilentExperiment(Profile* profile) { | 160 bool InstantFieldTrial::IsSilentExperiment(Profile* profile) { |
| 137 Group group = GetGroup(profile); | 161 Group group = GetGroup(profile); |
| 138 return group == SILENT_EXPERIMENT_A || group == SILENT_EXPERIMENT_B; | 162 return group == SILENT_EXPERIMENT_A || group == SILENT_EXPERIMENT_B; |
| 139 } | 163 } |
| 140 | 164 |
| 141 // static | 165 // static |
| 142 std::string InstantFieldTrial::GetGroupName(Profile* profile) { | 166 std::string InstantFieldTrial::GetGroupName(Profile* profile) { |
| 143 switch (GetGroup(profile)) { | 167 switch (GetGroup(profile)) { |
| 144 case INACTIVE: return std::string(); | 168 case INACTIVE: return std::string(); |
| 145 | 169 |
| 146 case INSTANT_EXPERIMENT_A: return "_InstantExperimentA"; | 170 case INSTANT_EXPERIMENT_A: return "_InstantExperimentA"; |
| 147 case INSTANT_EXPERIMENT_B: return "_InstantExperimentB"; | 171 case INSTANT_EXPERIMENT_B: return "_InstantExperimentB"; |
| 172 |
| 148 case HIDDEN_EXPERIMENT_A: return "_HiddenExperimentA"; | 173 case HIDDEN_EXPERIMENT_A: return "_HiddenExperimentA"; |
| 149 case HIDDEN_EXPERIMENT_B: return "_HiddenExperimentB"; | 174 case HIDDEN_EXPERIMENT_B: return "_HiddenExperimentB"; |
| 175 |
| 150 case SILENT_EXPERIMENT_A: return "_SilentExperimentA"; | 176 case SILENT_EXPERIMENT_A: return "_SilentExperimentA"; |
| 151 case SILENT_EXPERIMENT_B: return "_SilentExperimentB"; | 177 case SILENT_EXPERIMENT_B: return "_SilentExperimentB"; |
| 152 | 178 |
| 179 case SUGGEST_EXPERIMENT_A: return "_SuggestExperimentA"; |
| 180 case SUGGEST_EXPERIMENT_B: return "_SuggestExperimentB"; |
| 181 |
| 153 case UMA_CONTROL_A: return "_UmaControlA"; | 182 case UMA_CONTROL_A: return "_UmaControlA"; |
| 154 case UMA_CONTROL_B: return "_UmaControlB"; | 183 case UMA_CONTROL_B: return "_UmaControlB"; |
| 184 |
| 155 case ALL_CONTROL_A: return "_AllControlA"; | 185 case ALL_CONTROL_A: return "_AllControlA"; |
| 156 case ALL_CONTROL_B: return "_AllControlB"; | 186 case ALL_CONTROL_B: return "_AllControlB"; |
| 157 } | 187 } |
| 158 | 188 |
| 159 NOTREACHED(); | 189 NOTREACHED(); |
| 160 return std::string(); | 190 return std::string(); |
| 161 } | 191 } |
| 162 | 192 |
| 163 // static | 193 // static |
| 164 std::string InstantFieldTrial::GetGroupAsUrlParam(Profile* profile) { | 194 std::string InstantFieldTrial::GetGroupAsUrlParam(Profile* profile) { |
| 165 switch (GetGroup(profile)) { | 195 switch (GetGroup(profile)) { |
| 166 case INACTIVE: return std::string(); | 196 case INACTIVE: return std::string(); |
| 167 | 197 |
| 168 case INSTANT_EXPERIMENT_A: return "ix=iea&"; | 198 case INSTANT_EXPERIMENT_A: return "ix=iea&"; |
| 169 case INSTANT_EXPERIMENT_B: return "ix=ieb&"; | 199 case INSTANT_EXPERIMENT_B: return "ix=ieb&"; |
| 200 |
| 170 case HIDDEN_EXPERIMENT_A: return "ix=hea&"; | 201 case HIDDEN_EXPERIMENT_A: return "ix=hea&"; |
| 171 case HIDDEN_EXPERIMENT_B: return "ix=heb&"; | 202 case HIDDEN_EXPERIMENT_B: return "ix=heb&"; |
| 203 |
| 172 case SILENT_EXPERIMENT_A: return "ix=sea&"; | 204 case SILENT_EXPERIMENT_A: return "ix=sea&"; |
| 173 case SILENT_EXPERIMENT_B: return "ix=seb&"; | 205 case SILENT_EXPERIMENT_B: return "ix=seb&"; |
| 174 | 206 |
| 207 case SUGGEST_EXPERIMENT_A: return "ix=tea&"; |
| 208 case SUGGEST_EXPERIMENT_B: return "ix=teb&"; |
| 209 |
| 175 case UMA_CONTROL_A: return "ix=uca&"; | 210 case UMA_CONTROL_A: return "ix=uca&"; |
| 176 case UMA_CONTROL_B: return "ix=ucb&"; | 211 case UMA_CONTROL_B: return "ix=ucb&"; |
| 212 |
| 177 case ALL_CONTROL_A: return "ix=aca&"; | 213 case ALL_CONTROL_A: return "ix=aca&"; |
| 178 case ALL_CONTROL_B: return "ix=acb&"; | 214 case ALL_CONTROL_B: return "ix=acb&"; |
| 179 } | 215 } |
| 180 | 216 |
| 181 NOTREACHED(); | 217 NOTREACHED(); |
| 182 return std::string(); | 218 return std::string(); |
| 183 } | 219 } |
| 220 |
| 221 // static |
| 222 bool InstantFieldTrial::ShouldSetSuggestedText(Profile* profile) { |
| 223 Group group = GetGroup(profile); |
| 224 return !(group == HIDDEN_EXPERIMENT_A || group == HIDDEN_EXPERIMENT_B || |
| 225 group == SILENT_EXPERIMENT_A || group == SILENT_EXPERIMENT_B); |
| 226 } |
| OLD | NEW |