1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/autocomplete/autocomplete_field_trial.h"
#include <string>
#include "base/metrics/field_trial.h"
#include "base/string_number_conversions.h"
#include "chrome/common/metrics/experiments_helper.h"
#include "chrome/common/metrics/variation_ids.h"
namespace {
// Field trial names.
static const char kDisallowInlineHQPFieldTrialName[] =
"OmniboxDisallowInlineHQP";
static const char kSuggestFieldTrialName[] = "OmniboxSearchSuggest";
static const char kHQPNewScoringFieldTrialName[] = "OmniboxHQPNewScoring";
// Field trial experiment probabilities.
// For inline History Quick Provider field trial, put 10% ( = 10/100 )
// of the users in the disallow-inline experiment group.
const base::FieldTrial::Probability kDisallowInlineHQPFieldTrialDivisor = 100;
const base::FieldTrial::Probability
kDisallowInlineHQPFieldTrialExperimentFraction = 10;
// For the search suggestion field trial, divide the people in the
// trial into 20 equally-sized buckets. The suggest provider backend
// will decide what behavior (if any) to change based on the group.
const int kSuggestFieldTrialNumberOfGroups = 20;
// For History Quick Provider new scoring field trial, put 25% ( = 25/100 )
// of the users in the new scoring experiment group.
const base::FieldTrial::Probability kHQPNewScoringFieldTrialDivisor = 100;
const base::FieldTrial::Probability
kHQPNewScoringFieldTrialExperimentFraction = 25;
// Field trial IDs.
// Though they are not literally "const", they are set only once, in
// Activate() below.
// Field trial ID for the disallow-inline History Quick Provider
// experiment group.
int disallow_inline_hqp_experiment_group = 0;
// Field trial ID for the History Quick Provider new scoring experiment group.
int hqp_new_scoring_experiment_group = 0;
}
void AutocompleteFieldTrial::Activate() {
// Because users tend to use omnibox without attention to it--habits
// get ingrained, users tend to learn that a particular suggestion is
// at a particular spot in the drop-down--we're going to make these
// field trials sticky. We want users to stay in them once assigned
// so they have a better experience and also so we don't get weird
// effects as omnibox ranking keeps changing and users learn they can't
// trust the omnibox. Hence, to create the field trials we require
// that field trials can be made sticky.
if (base::FieldTrialList::IsOneTimeRandomizationEnabled()) { // sticky trials
// Create inline History Quick Provider field trial.
// Make it expire on November 8, 2012.
scoped_refptr<base::FieldTrial> trial(
base::FieldTrialList::FactoryGetFieldTrial(
kDisallowInlineHQPFieldTrialName, kDisallowInlineHQPFieldTrialDivisor,
"Standard", 2012, 11, 8, NULL));
trial->UseOneTimeRandomization();
disallow_inline_hqp_experiment_group = trial->AppendGroup("DisallowInline",
kDisallowInlineHQPFieldTrialExperimentFraction);
}
// Create the suggest field trial (regardless of sticky-ness status, but
// make it sticky if possible).
// Make it expire on October 1, 2012.
scoped_refptr<base::FieldTrial> trial(
base::FieldTrialList::FactoryGetFieldTrial(
kSuggestFieldTrialName, kSuggestFieldTrialNumberOfGroups,
"0", 2012, 10, 1, NULL));
if (base::FieldTrialList::IsOneTimeRandomizationEnabled())
trial->UseOneTimeRandomization();
// Mark this group in suggest requests to Google.
experiments_helper::AssociateGoogleVariationID(
kSuggestFieldTrialName, "0", chrome_variations::kSuggestIDMin);
DCHECK_EQ(kSuggestFieldTrialNumberOfGroups,
chrome_variations::kSuggestIDMax - chrome_variations::kSuggestIDMin + 1);
// We've already created one group; now just need to create
// kSuggestFieldTrialNumGroups - 1 more. Mark these groups in
// suggest requests to Google.
for (int i = 1; i < kSuggestFieldTrialNumberOfGroups; i++) {
const std::string group_name = base::IntToString(i);
trial->AppendGroup(group_name, 1);
experiments_helper::AssociateGoogleVariationID(
kSuggestFieldTrialName, group_name,
static_cast<chrome_variations::ID>(
chrome_variations::kSuggestIDMin + i));
}
// Create inline History Quick Provider new scoring field trial.
// Make it expire on January 14, 2013.
trial = base::FieldTrialList::FactoryGetFieldTrial(
kHQPNewScoringFieldTrialName, kHQPNewScoringFieldTrialDivisor,
"Standard", 2013, 1, 14, NULL);
if (base::FieldTrialList::IsOneTimeRandomizationEnabled())
trial->UseOneTimeRandomization();
hqp_new_scoring_experiment_group = trial->AppendGroup("NewScoring",
kHQPNewScoringFieldTrialExperimentFraction);
}
bool AutocompleteFieldTrial::InDisallowInlineHQPFieldTrial() {
return base::FieldTrialList::TrialExists(kDisallowInlineHQPFieldTrialName);
}
bool AutocompleteFieldTrial::InDisallowInlineHQPFieldTrialExperimentGroup() {
if (!base::FieldTrialList::TrialExists(kDisallowInlineHQPFieldTrialName))
return false;
// Return true if we're in the experiment group.
const int group = base::FieldTrialList::FindValue(
kDisallowInlineHQPFieldTrialName);
return group == disallow_inline_hqp_experiment_group;
}
bool AutocompleteFieldTrial::InSuggestFieldTrial() {
return base::FieldTrialList::TrialExists(kSuggestFieldTrialName);
}
std::string AutocompleteFieldTrial::GetSuggestGroupName() {
return base::FieldTrialList::FindFullName(kSuggestFieldTrialName);
}
// Yes, this is roundabout. It's easier to provide the group number as
// a string (simply by choosing group names appropriately) than provide
// it as an integer. It might look more straightforward to use group ids
// for the group number with respect to suggest. However, we don't want
// to assume that group ids are creates as 0, 1, 2, ... -- this isn't part
// of the field_trial.h specification. Hence, we use the group names to
// get numbers that we know are 0, 1, 2, ...
int AutocompleteFieldTrial::GetSuggestGroupNameAsNumber() {
int group_num;
base::StringToInt(GetSuggestGroupName(), &group_num);
return group_num;
}
int AutocompleteFieldTrial::GetSuggestNumberOfGroups() {
return kSuggestFieldTrialNumberOfGroups;
}
bool AutocompleteFieldTrial::InHQPNewScoringFieldTrial() {
return base::FieldTrialList::TrialExists(kHQPNewScoringFieldTrialName);
}
bool AutocompleteFieldTrial::InHQPNewScoringFieldTrialExperimentGroup() {
if (!InHQPNewScoringFieldTrial())
return false;
// Return true if we're in the experiment group.
const int group = base::FieldTrialList::FindValue(
kHQPNewScoringFieldTrialName);
return group == hqp_new_scoring_experiment_group;
}
|