summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete/autocomplete_field_trial.cc
blob: 518304edf3ee274453e683931999c464bad63e0c (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// 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/variations/variation_ids.h"
#include "chrome/common/metrics/variations/variations_util.h"

namespace {

// Field trial names.
static const char kDisallowInlineHQPFieldTrialName[] =
    "OmniboxDisallowInlineHQP";
static const char kSuggestFieldTrialName[] = "OmniboxSearchSuggest";
static const char kHQPNewScoringFieldTrialName[] = "OmniboxHQPNewScoring";
static const char kHUPCullRedirectsFieldTrialName[] = "OmniboxHUPCullRedirects";
static const char kHUPCreateShorterMatchFieldTrialName[] =
    "OmniboxHUPCreateShorterMatch";

// Field trial experiment probabilities.

// For inline History Quick Provider field trial, put 0% ( = 0/100 )
// of the users in the disallow-inline experiment group.
const base::FieldTrial::Probability kDisallowInlineHQPFieldTrialDivisor = 100;
const base::FieldTrial::Probability
    kDisallowInlineHQPFieldTrialExperimentFraction = 0;

// 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 0% ( = 0/100 )
// of the users in the new scoring experiment group.
const base::FieldTrial::Probability kHQPNewScoringFieldTrialDivisor = 100;
const base::FieldTrial::Probability
    kHQPNewScoringFieldTrialExperimentFraction = 0;

// For HistoryURL provider cull redirects field trial, put 25% ( = 25/100 )
// of the users in the don't-cull-redirects experiment group.
const base::FieldTrial::Probability kHUPCullRedirectsFieldTrialDivisor = 100;
const base::FieldTrial::Probability
    kHUPCullRedirectsFieldTrialExperimentFraction = 25;

// For HistoryURL provider create shorter match field trial, put 25%
// ( = 25/100 ) of the users in the don't-create-a-shorter-match
// experiment group.
const base::FieldTrial::Probability
    kHUPCreateShorterMatchFieldTrialDivisor = 100;
const base::FieldTrial::Probability
    kHUPCreateShorterMatchFieldTrialExperimentFraction = 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;

// Field trial ID for the HistoryURL provider cull redirects experiment group.
int hup_dont_cull_redirects_experiment_group = 0;

// Field trial ID for the HistoryURL provider create shorter match
// experiment group.
int hup_dont_create_shorter_match_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.
  chrome_variations::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);
    chrome_variations::AssociateGoogleVariationID(
        kSuggestFieldTrialName, group_name,
        static_cast<chrome_variations::VariationID>(
            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);

  // Create the HistoryURL provider cull redirects field trial.
  // Make it expire on March 1, 2013.
  trial = base::FieldTrialList::FactoryGetFieldTrial(
      kHUPCullRedirectsFieldTrialName, kHUPCullRedirectsFieldTrialDivisor,
      "Standard", 2013, 3, 1, NULL);
  if (base::FieldTrialList::IsOneTimeRandomizationEnabled())
    trial->UseOneTimeRandomization();
  hup_dont_cull_redirects_experiment_group =
      trial->AppendGroup("DontCullRedirects",
                         kHUPCullRedirectsFieldTrialExperimentFraction);

  // Create the HistoryURL provider create shorter match field trial.
  // Make it expire on March 1, 2013.
  trial = base::FieldTrialList::FactoryGetFieldTrial(
      kHUPCreateShorterMatchFieldTrialName,
      kHUPCreateShorterMatchFieldTrialDivisor, "Standard", 2013, 3, 1, NULL);
  if (base::FieldTrialList::IsOneTimeRandomizationEnabled())
    trial->UseOneTimeRandomization();
  hup_dont_create_shorter_match_experiment_group =
      trial->AppendGroup("DontCreateShorterMatch",
                         kHUPCreateShorterMatchFieldTrialExperimentFraction);
}

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;
}

bool AutocompleteFieldTrial::InHUPCullRedirectsFieldTrial() {
  return base::FieldTrialList::TrialExists(kHUPCullRedirectsFieldTrialName);
}

bool AutocompleteFieldTrial::InHUPCullRedirectsFieldTrialExperimentGroup() {
  if (!base::FieldTrialList::TrialExists(kHUPCullRedirectsFieldTrialName))
    return false;

  // Return true if we're in the experiment group.
  const int group = base::FieldTrialList::FindValue(
      kHUPCullRedirectsFieldTrialName);
  return group == hup_dont_cull_redirects_experiment_group;
}

bool AutocompleteFieldTrial::InHUPCreateShorterMatchFieldTrial() {
  return
      base::FieldTrialList::TrialExists(kHUPCreateShorterMatchFieldTrialName);
}

bool AutocompleteFieldTrial::
    InHUPCreateShorterMatchFieldTrialExperimentGroup() {
  if (!base::FieldTrialList::TrialExists(kHUPCreateShorterMatchFieldTrialName))
    return false;

  // Return true if we're in the experiment group.
  const int group = base::FieldTrialList::FindValue(
      kHUPCreateShorterMatchFieldTrialName);
  return group == hup_dont_create_shorter_match_experiment_group;
}