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.
5 #ifndef CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
6 #define CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
12 #include "base/basictypes.h"
13 #include "base/gtest_prod_util.h"
14 #include "chrome/browser/autocomplete/autocomplete_input.h"
15 #include "chrome/common/autocomplete_match_type.h"
21 // The set of parameters customizing the HUP scoring.
22 struct HUPScoringParams
{
23 // A set of parameters describing how to cap a given count score. First,
24 // we apply a half-life based decay of the given count and then find the
25 // maximum relevance score in the corresponding bucket list.
28 // (decayed_count, max_relevance) pair.
29 typedef std::pair
<double, int> CountMaxRelevance
;
34 // Computes a half-life time decay given the |elapsed_time|.
35 double HalfLifeTimeDecay(const base::TimeDelta
& elapsed_time
) const;
37 int relevance_cap() const { return relevance_cap_
; }
38 void set_relevance_cap(int relevance_cap
) {
39 relevance_cap_
= relevance_cap
;
42 int half_life_days() const { return half_life_days_
; }
43 void set_half_life_days(int half_life_days
) {
44 half_life_days_
= half_life_days
;
47 std::vector
<CountMaxRelevance
>& buckets() { return buckets_
; }
48 const std::vector
<CountMaxRelevance
>& buckets() const { return buckets_
; }
51 // History matches with relevance score greater or equal to |relevance_cap_|
52 // are not affected by this experiment.
53 // Set to -1, if there is no relevance cap in place and all matches are
54 // subject to demotion.
57 // Half life time for a decayed count as measured since the last visit.
58 // Set to -1 if not used.
61 // The relevance score caps for given decayed count values.
62 // Each pair (decayed_count, max_score) indicates what the maximum relevance
63 // score is of a decayed count equal or greater than decayed_count.
65 // Consider this example:
66 // [(1, 1000), (0.5, 500), (0, 100)]
67 // If decayed count is 2 (which is >= 1), the corresponding match's maximum
68 // relevance will be capped at 1000. In case of 0.5, the score is capped
69 // at 500. Anything below 0.5 is capped at 100.
71 // This list is sorted by the pair's first element in descending order.
72 std::vector
<CountMaxRelevance
> buckets_
;
75 HUPScoringParams() : experimental_scoring_enabled(false) {}
77 bool experimental_scoring_enabled
;
79 ScoreBuckets typed_count_buckets
;
81 // Used only when the typed count is 0.
82 ScoreBuckets visited_count_buckets
;
85 // This class manages the Omnibox field trials.
86 class OmniboxFieldTrial
{
88 // A mapping that contains multipliers indicating that matches of the
89 // specified type should have their relevance score multiplied by the
90 // given number. Omitted types are assumed to have multipliers of 1.0.
91 typedef std::map
<AutocompleteMatchType::Type
, float> DemotionMultipliers
;
93 // Creates the static field trial groups.
94 // *** MUST NOT BE CALLED MORE THAN ONCE. ***
95 static void ActivateStaticTrials();
97 // Activates all dynamic field trials. The main difference between
98 // the autocomplete dynamic and static field trials is that the former
99 // don't require any code changes on the Chrome side as they are controlled
100 // on the server side. Chrome binary simply propagates all necessary
101 // information through the X-Client-Data header.
102 // This method, unlike ActivateStaticTrials(), may be called multiple times.
103 static void ActivateDynamicTrials();
105 // Returns a bitmap containing AutocompleteProvider::Type values
106 // that should be disabled in AutocompleteController.
107 // This method simply goes over all autocomplete dynamic field trial groups
108 // and looks for group names like "ProvidersDisabled_NNN" where NNN is
109 // an integer corresponding to a bitmap mask. All extracted bitmaps
110 // are OR-ed together and returned as the final result.
111 static int GetDisabledProviderTypes();
113 // Returns whether the user is in any dynamic field trial where the
114 // group has a the prefix |group_prefix|.
115 static bool HasDynamicFieldTrialGroupPrefix(const char *group_prefix
);
117 // ---------------------------------------------------------
118 // For the suggest field trial.
120 // Populates |field_trial_hash| with hashes of the active suggest field trial
122 static void GetActiveSuggestFieldTrialHashes(
123 std::vector
<uint32
>* field_trial_hash
);
125 // ---------------------------------------------------------
126 // For the HistoryURL provider disable culling redirects field trial.
128 // Returns whether the user is in any group for this field trial.
129 // (Should always be true unless initialization went wrong.)
130 static bool InHUPCullRedirectsFieldTrial();
132 // Returns whether we should disable culling of redirects in
133 // HistoryURL provider.
134 static bool InHUPCullRedirectsFieldTrialExperimentGroup();
136 // ---------------------------------------------------------
137 // For the HistoryURL provider disable creating a shorter match
140 // Returns whether the user is in any group for this field trial.
141 // (Should always be true unless initialization went wrong.)
142 static bool InHUPCreateShorterMatchFieldTrial();
144 // Returns whether we should disable creating a shorter match in
145 // HistoryURL provider.
146 static bool InHUPCreateShorterMatchFieldTrialExperimentGroup();
148 // ---------------------------------------------------------
149 // For the AutocompleteController "stop timer" field trial.
151 // Returns the duration to be used for the AutocompleteController's stop
152 // timer. Returns the default value of 1.5 seconds if the stop timer
153 // override experiment isn't active or if parsing the experiment-provided
155 static base::TimeDelta
StopTimerFieldTrialDuration();
157 // ---------------------------------------------------------
158 // For the ZeroSuggestProvider field trial.
160 // Returns whether the user is in any field trial where the
161 // ZeroSuggestProvider should be used to get suggestions when the
162 // user clicks on the omnibox but has not typed anything yet.
163 static bool InZeroSuggestFieldTrial();
165 // Returns whether the user is in a ZeroSuggest field trial, but should
166 // show most visited URL instead. This is used to compare metrics of
167 // ZeroSuggest and most visited suggestions.
168 static bool InZeroSuggestMostVisitedFieldTrial();
170 // Returns whether the user is in a ZeroSuggest field trial and URL-based
171 // suggestions can continue to appear after the user has started typing.
172 static bool InZeroSuggestAfterTypingFieldTrial();
174 // Returns whether the user is in a ZeroSuggest field trial, but should
175 // show recently searched-for queries instead.
176 static bool InZeroSuggestPersonalizedFieldTrial();
178 // ---------------------------------------------------------
179 // For the ShortcutsScoringMaxRelevance experiment that's part of the
180 // bundled omnibox field trial.
182 // If the user is in an experiment group that, given the provided
183 // |current_page_classification| context, changes the maximum relevance
184 // ShortcutsProvider::CalculateScore() is supposed to assign, extract
185 // that maximum relevance score and put in in |max_relevance|. Returns
186 // true on a successful extraction. CalculateScore()'s return value is
187 // a product of this maximum relevance score and some attenuating factors
188 // that are all between 0 and 1. (Note that Shortcuts results may have
189 // their scores reduced later if the assigned score is higher than allowed
190 // for non-inlineable results. Shortcuts results are not allowed to be
192 static bool ShortcutsScoringMaxRelevance(
193 AutocompleteInput::PageClassification current_page_classification
,
196 // ---------------------------------------------------------
197 // For the SearchHistory experiment that's part of the bundled omnibox
200 // Returns true if the user is in the experiment group that, given the
201 // provided |current_page_classification| context, scores search history
202 // query suggestions less aggressively so that they don't inline.
203 static bool SearchHistoryPreventInlining(
204 AutocompleteInput::PageClassification current_page_classification
);
206 // Returns true if the user is in the experiment group that, given the
207 // provided |current_page_classification| context, disables all query
208 // suggestions from search history.
209 static bool SearchHistoryDisable(
210 AutocompleteInput::PageClassification current_page_classification
);
212 // ---------------------------------------------------------
213 // For the DemoteByType experiment that's part of the bundled omnibox field
216 // If the user is in an experiment group that, in the provided
217 // |current_page_classification| context, demotes the relevance scores
218 // of certain types of matches, populates the |demotions_by_type| map
219 // appropriately. Otherwise, sets |demotions_by_type| to its default
220 // value based on the context.
221 static void GetDemotionsByType(
222 AutocompleteInput::PageClassification current_page_classification
,
223 DemotionMultipliers
* demotions_by_type
);
225 // ---------------------------------------------------------
226 // For the HistoryURL provider new scoring experiment that is part of the
227 // bundled omnibox field trial.
229 // Initializes the HUP |scoring_params| based on the active HUP scoring
230 // experiment. If there is no such experiment, this function simply sets
231 // |scoring_params|->experimental_scoring_enabled to false.
232 static void GetExperimentalHUPScoringParams(HUPScoringParams
* scoring_params
);
234 // For the HQPBookmarkValue experiment that's part of the
235 // bundled omnibox field trial.
237 // Returns the value an untyped visit to a bookmark should receive.
238 // Compare this value with the default of 1 for non-bookmarked untyped
239 // visits to pages and the default of 20 for typed visits. Returns
240 // 1 if the bookmark value experiment isn't active.
241 static int HQPBookmarkValue();
243 // ---------------------------------------------------------
244 // For the HQPAllowMatchInTLD experiment that's part of the
245 // bundled omnibox field trial.
247 // Returns true if HQP should allow an input term to match in the
248 // top level domain (e.g., .com) of a URL. Returns false if the
249 // allow match in TLD experiment isn't active.
250 static bool HQPAllowMatchInTLDValue();
252 // ---------------------------------------------------------
253 // For the HQPAllowMatchInScheme experiment that's part of the
254 // bundled omnibox field trial.
256 // Returns true if HQP should allow an input term to match in the
257 // scheme (e.g., http://) of a URL. Returns false if the allow
258 // match in scheme experiment isn't active.
259 static bool HQPAllowMatchInSchemeValue();
261 // ---------------------------------------------------------
262 // For the BookmarksIndexURLs experiment that's part of the
263 // bundled omnibox field trial.
265 // Returns true if BookmarkIndex should index the URL of bookmarks
266 // (not only the titles) and search for / mark matches in the URLs,
267 // and BookmarkProvider should score bookmarks based on both the
268 // matches in bookmark title and URL. Returns false if the bookmarks
269 // index URLs experiment isn't active.
270 static bool BookmarksIndexURLsValue();
272 // ---------------------------------------------------------
273 // Exposed publicly for the sake of unittests.
274 static const char kBundledExperimentFieldTrialName
[];
275 // Rule names used by the bundled experiment.
276 static const char kShortcutsScoringMaxRelevanceRule
[];
277 static const char kSearchHistoryRule
[];
278 static const char kDemoteByTypeRule
[];
279 static const char kHQPBookmarkValueRule
[];
280 static const char kHQPDiscountFrecencyWhenFewVisitsRule
[];
281 static const char kHQPAllowMatchInTLDRule
[];
282 static const char kHQPAllowMatchInSchemeRule
[];
283 static const char kZeroSuggestRule
[];
284 static const char kZeroSuggestVariantRule
[];
285 static const char kBookmarksIndexURLsRule
[];
287 // Parameter names used by the HUP new scoring experiments.
288 static const char kHUPNewScoringEnabledParam
[];
289 static const char kHUPNewScoringTypedCountRelevanceCapParam
[];
290 static const char kHUPNewScoringTypedCountHalfLifeTimeParam
[];
291 static const char kHUPNewScoringTypedCountScoreBucketsParam
[];
292 static const char kHUPNewScoringVisitedCountRelevanceCapParam
[];
293 static const char kHUPNewScoringVisitedCountHalfLifeTimeParam
[];
294 static const char kHUPNewScoringVisitedCountScoreBucketsParam
[];
297 friend class OmniboxFieldTrialTest
;
299 // The bundled omnibox experiment comes with a set of parameters
300 // (key-value pairs). Each key indicates a certain rule that applies in
301 // a certain context. The value indicates what the consequences of
302 // applying the rule are. For example, the value of a SearchHistory rule
303 // in the context of a search results page might indicate that we should
304 // prevent search history matches from inlining.
306 // This function returns the value associated with the |rule| that applies
307 // in the current context (which currently consists of |page_classification|
308 // and whether Instant Extended is enabled). If no such rule exists in the
309 // current context, fall back to the rule in various wildcard contexts and
310 // return its value if found. If the rule remains unfound in the global
311 // context, returns the empty string. For more details, including how we
312 // prioritize different wildcard contexts, see the implementation. How to
313 // interpret the value is left to the caller; this is rule-dependent.
314 static std::string
GetValueForRuleInContext(
315 const std::string
& rule
,
316 AutocompleteInput::PageClassification page_classification
);
318 DISALLOW_IMPLICIT_CONSTRUCTORS(OmniboxFieldTrial
);
321 #endif // CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_