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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
// Copyright 2014 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.
#ifndef COMPONENTS_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
#define COMPONENTS_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "components/metrics/proto/omnibox_event.pb.h"
#include "components/omnibox/autocomplete_match_type.h"
namespace base {
class TimeDelta;
}
// The set of parameters customizing the HUP scoring.
struct HUPScoringParams {
// A set of parameters describing how to cap a given count score. First,
// we apply a half-life based decay of the given count and then find the
// maximum relevance score in the corresponding bucket list.
class ScoreBuckets {
public:
// (decayed_count, max_relevance) pair.
typedef std::pair<double, int> CountMaxRelevance;
ScoreBuckets();
~ScoreBuckets();
// Computes a half-life time decay given the |elapsed_time|.
double HalfLifeTimeDecay(const base::TimeDelta& elapsed_time) const;
int relevance_cap() const { return relevance_cap_; }
void set_relevance_cap(int relevance_cap) {
relevance_cap_ = relevance_cap;
}
int half_life_days() const { return half_life_days_; }
void set_half_life_days(int half_life_days) {
half_life_days_ = half_life_days;
}
std::vector<CountMaxRelevance>& buckets() { return buckets_; }
const std::vector<CountMaxRelevance>& buckets() const { return buckets_; }
private:
// History matches with relevance score greater or equal to |relevance_cap_|
// are not affected by this experiment.
// Set to -1, if there is no relevance cap in place and all matches are
// subject to demotion.
int relevance_cap_;
// Half life time for a decayed count as measured since the last visit.
// Set to -1 if not used.
int half_life_days_;
// The relevance score caps for given decayed count values.
// Each pair (decayed_count, max_score) indicates what the maximum relevance
// score is of a decayed count equal or greater than decayed_count.
//
// Consider this example:
// [(1, 1000), (0.5, 500), (0, 100)]
// If decayed count is 2 (which is >= 1), the corresponding match's maximum
// relevance will be capped at 1000. In case of 0.5, the score is capped
// at 500. Anything below 0.5 is capped at 100.
//
// This list is sorted by the pair's first element in descending order.
std::vector<CountMaxRelevance> buckets_;
};
HUPScoringParams() : experimental_scoring_enabled(false) {}
bool experimental_scoring_enabled;
ScoreBuckets typed_count_buckets;
// Used only when the typed count is 0.
ScoreBuckets visited_count_buckets;
};
// This class manages the Omnibox field trials.
class OmniboxFieldTrial {
public:
// A mapping that contains multipliers indicating that matches of the
// specified type should have their relevance score multiplied by the
// given number. Omitted types are assumed to have multipliers of 1.0.
typedef std::map<AutocompleteMatchType::Type, float> DemotionMultipliers;
// Activates all dynamic field trials. The main difference between
// the autocomplete dynamic and static field trials is that the former
// don't require any code changes on the Chrome side as they are controlled
// on the server side. Chrome binary simply propagates all necessary
// information through the X-Client-Data header.
// This method may be called multiple times.
static void ActivateDynamicTrials();
// ---------------------------------------------------------
// For any experiment that's part of the bundled omnibox field trial.
// Returns a bitmap containing AutocompleteProvider::Type values
// that should be disabled in AutocompleteController.
static int GetDisabledProviderTypes();
// Returns whether the user is in any dynamic field trial where the
// group has a the prefix |group_prefix|.
static bool HasDynamicFieldTrialGroupPrefix(const char *group_prefix);
// ---------------------------------------------------------
// For the suggest field trial.
// Populates |field_trial_hash| with hashes of the active suggest field trial
// names, if any.
static void GetActiveSuggestFieldTrialHashes(
std::vector<uint32>* field_trial_hash);
// ---------------------------------------------------------
// For the AutocompleteController "stop timer" field trial.
// Returns the duration to be used for the AutocompleteController's stop
// timer. Returns the default value of 1.5 seconds if the stop timer
// override experiment isn't active or if parsing the experiment-provided
// duration fails.
static base::TimeDelta StopTimerFieldTrialDuration();
// ---------------------------------------------------------
// For the ZeroSuggestProvider field trial.
// Returns whether the user is in any field trial where the
// ZeroSuggestProvider should be used to get suggestions when the
// user clicks on the omnibox but has not typed anything yet.
static bool InZeroSuggestFieldTrial();
// Returns whether the user is in a ZeroSuggest field trial, which shows
// most visited URLs. This is true for both "MostVisited" and
// "MostVisitedWithoutSERP" trials.
static bool InZeroSuggestMostVisitedFieldTrial();
// Returns whether the user is in ZeroSuggest field trial showing most
// visited URLs except it doesn't show suggestions on Google search result
// pages.
static bool InZeroSuggestMostVisitedWithoutSerpFieldTrial();
// Returns whether the user is in a ZeroSuggest field trial and URL-based
// suggestions can continue to appear after the user has started typing.
static bool InZeroSuggestAfterTypingFieldTrial();
// Returns whether the user is in a ZeroSuggest field trial, but should
// show recently searched-for queries instead.
static bool InZeroSuggestPersonalizedFieldTrial();
// ---------------------------------------------------------
// For the ShortcutsScoringMaxRelevance experiment that's part of the
// bundled omnibox field trial.
// If the user is in an experiment group that, given the provided
// |current_page_classification| context, changes the maximum relevance
// ShortcutsProvider::CalculateScore() is supposed to assign, extract
// that maximum relevance score and put in in |max_relevance|. Returns
// true on a successful extraction. CalculateScore()'s return value is
// a product of this maximum relevance score and some attenuating factors
// that are all between 0 and 1. (Note that Shortcuts results may have
// their scores reduced later if the assigned score is higher than allowed
// for non-inlineable results. Shortcuts results are not allowed to be
// inlined.)
static bool ShortcutsScoringMaxRelevance(
metrics::OmniboxEventProto::PageClassification
current_page_classification,
int* max_relevance);
// ---------------------------------------------------------
// For the SearchHistory experiment that's part of the bundled omnibox
// field trial.
// Returns true if the user is in the experiment group that, given the
// provided |current_page_classification| context, scores search history
// query suggestions less aggressively so that they don't inline.
static bool SearchHistoryPreventInlining(
metrics::OmniboxEventProto::PageClassification
current_page_classification);
// Returns true if the user is in the experiment group that, given the
// provided |current_page_classification| context, disables all query
// suggestions from search history.
static bool SearchHistoryDisable(
metrics::OmniboxEventProto::PageClassification
current_page_classification);
// ---------------------------------------------------------
// For the DemoteByType experiment that's part of the bundled omnibox field
// trial.
// If the user is in an experiment group that, in the provided
// |current_page_classification| context, demotes the relevance scores
// of certain types of matches, populates the |demotions_by_type| map
// appropriately. Otherwise, sets |demotions_by_type| to its default
// value based on the context.
static void GetDemotionsByType(
metrics::OmniboxEventProto::PageClassification
current_page_classification,
DemotionMultipliers* demotions_by_type);
// ---------------------------------------------------------
// For the HistoryURL provider new scoring experiment that is part of the
// bundled omnibox field trial.
// Initializes the HUP |scoring_params| based on the active HUP scoring
// experiment. If there is no such experiment, this function simply sets
// |scoring_params|->experimental_scoring_enabled to false.
static void GetExperimentalHUPScoringParams(HUPScoringParams* scoring_params);
// For the HQPBookmarkValue experiment that's part of the
// bundled omnibox field trial.
// Returns the value an untyped visit to a bookmark should receive.
// Compare this value with the default of 1 for non-bookmarked untyped
// visits to pages and the default of 20 for typed visits. Returns
// 10 if the bookmark value experiment isn't active.
static int HQPBookmarkValue();
// ---------------------------------------------------------
// For the HQPAllowMatchInTLD experiment that's part of the
// bundled omnibox field trial.
// Returns true if HQP should allow an input term to match in the
// top level domain (e.g., .com) of a URL. Returns false if the
// allow match in TLD experiment isn't active.
static bool HQPAllowMatchInTLDValue();
// ---------------------------------------------------------
// For the HQPAllowMatchInScheme experiment that's part of the
// bundled omnibox field trial.
// Returns true if HQP should allow an input term to match in the
// scheme (e.g., http://) of a URL. Returns false if the allow
// match in scheme experiment isn't active.
static bool HQPAllowMatchInSchemeValue();
// ---------------------------------------------------------
// For the DisableInlining experiment that's part of the bundled omnibox
// field trial.
// Returns true if AutocompleteResult should prevent any suggestion with
// a non-empty |inline_autocomplete| from being the default match. In
// other words, prevent an inline autocompletion from appearing as the
// top suggestion / within the omnibox itself, reordering matches as
// necessary to make this true. Returns false if the experiment isn't
// active.
static bool DisableInlining();
// ---------------------------------------------------------
// For the AnswersInSuggest experiment that's part of the bundled omnibox
// field trial.
// Returns true if the AnswersInSuggest feature should be enabled causing
// query responses such as current weather conditions or stock quotes
// to be provided in the Omnibox suggestion list. Considers both the
// field trial state as well as the overriding command-line flags.
static bool EnableAnswersInSuggest();
// ---------------------------------------------------------
// For the AddUWYTMatchEvenIfPromotedURLs experiment that's part of the
// bundled omnibox field trial.
// Returns true if HistoryURL Provider should add the URL-what-you-typed match
// (if valid and reasonable) even if the provider has good inline
// autocompletions to offer. Normally HistoryURL does not add the UWYT match
// if there are good inline autocompletions, as the user could simply hit
// backspace to delete the completion and get the what-you-typed match.
// However, for the disabling inlining experiment we want to have the UWYT
// always explicitly displayed at an option if possible. Returns false if
// the experiment isn't active.
static bool AddUWYTMatchEvenIfPromotedURLs();
// ---------------------------------------------------------
// For the DisplayHintTextWhenPossible experiment that's part of the
// bundled omnibox field trial.
// Returns true if the omnibox should display hint text (Search
// <search engine> or type URL) when possible (i.e., the omnibox
// is otherwise non-empty).
static bool DisplayHintTextWhenPossible();
// ---------------------------------------------------------
// For SearchProvider related experiments.
// Returns true if the search provider should not be caching results.
static bool DisableResultsCaching();
// Returns how the search provider should poll Suggest. Currently, we support
// measuring polling delay from the last keystroke or last suggest request.
static void GetSuggestPollingStrategy(bool* from_last_keystroke,
int* polling_delay_ms);
// ---------------------------------------------------------
// Exposed publicly for the sake of unittests.
static const char kBundledExperimentFieldTrialName[];
// Rule names used by the bundled experiment.
static const char kDisableProvidersRule[];
static const char kShortcutsScoringMaxRelevanceRule[];
static const char kSearchHistoryRule[];
static const char kDemoteByTypeRule[];
static const char kHQPBookmarkValueRule[];
static const char kHQPDiscountFrecencyWhenFewVisitsRule[];
static const char kHQPAllowMatchInTLDRule[];
static const char kHQPAllowMatchInSchemeRule[];
static const char kZeroSuggestRule[];
static const char kZeroSuggestVariantRule[];
static const char kDisableInliningRule[];
static const char kAnswersInSuggestRule[];
static const char kAddUWYTMatchEvenIfPromotedURLsRule[];
static const char kDisplayHintTextWhenPossibleRule[];
static const char kDisableResultsCachingRule[];
static const char kMeasureSuggestPollingDelayFromLastKeystrokeRule[];
static const char kSuggestPollingDelayMsRule[];
// Parameter names used by the HUP new scoring experiments.
static const char kHUPNewScoringEnabledParam[];
static const char kHUPNewScoringTypedCountRelevanceCapParam[];
static const char kHUPNewScoringTypedCountHalfLifeTimeParam[];
static const char kHUPNewScoringTypedCountScoreBucketsParam[];
static const char kHUPNewScoringVisitedCountRelevanceCapParam[];
static const char kHUPNewScoringVisitedCountHalfLifeTimeParam[];
static const char kHUPNewScoringVisitedCountScoreBucketsParam[];
// The amount of time to wait before sending a new suggest request after the
// previous one unless overridden by a field trial parameter.
// Non-const because some unittests modify this value.
static int kDefaultMinimumTimeBetweenSuggestQueriesMs;
private:
friend class OmniboxFieldTrialTest;
// The bundled omnibox experiment comes with a set of parameters
// (key-value pairs). Each key indicates a certain rule that applies in
// a certain context. The value indicates what the consequences of
// applying the rule are. For example, the value of a SearchHistory rule
// in the context of a search results page might indicate that we should
// prevent search history matches from inlining.
//
// This function returns the value associated with the |rule| that applies
// in the current context (which currently consists of |page_classification|
// and whether Instant Extended is enabled). If no such rule exists in the
// current context, fall back to the rule in various wildcard contexts and
// return its value if found. If the rule remains unfound in the global
// context, returns the empty string. For more details, including how we
// prioritize different wildcard contexts, see the implementation. How to
// interpret the value is left to the caller; this is rule-dependent.
static std::string GetValueForRuleInContext(
const std::string& rule,
metrics::OmniboxEventProto::PageClassification page_classification);
DISALLOW_IMPLICIT_CONSTRUCTORS(OmniboxFieldTrial);
};
#endif // COMPONENTS_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
|