OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_ | |
6 #define CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_ | |
7 | |
8 #include <map> | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/gtest_prod_util.h" | |
14 #include "components/metrics/proto/omnibox_event.pb.h" | |
15 #include "components/omnibox/autocomplete_match_type.h" | |
16 | |
17 namespace base { | |
18 class TimeDelta; | |
19 } | |
20 | |
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. | |
26 class ScoreBuckets { | |
27 public: | |
28 // (decayed_count, max_relevance) pair. | |
29 typedef std::pair<double, int> CountMaxRelevance; | |
30 | |
31 ScoreBuckets(); | |
32 ~ScoreBuckets(); | |
33 | |
34 // Computes a half-life time decay given the |elapsed_time|. | |
35 double HalfLifeTimeDecay(const base::TimeDelta& elapsed_time) const; | |
36 | |
37 int relevance_cap() const { return relevance_cap_; } | |
38 void set_relevance_cap(int relevance_cap) { | |
39 relevance_cap_ = relevance_cap; | |
40 } | |
41 | |
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; | |
45 } | |
46 | |
47 std::vector<CountMaxRelevance>& buckets() { return buckets_; } | |
48 const std::vector<CountMaxRelevance>& buckets() const { return buckets_; } | |
49 | |
50 private: | |
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. | |
55 int relevance_cap_; | |
56 | |
57 // Half life time for a decayed count as measured since the last visit. | |
58 // Set to -1 if not used. | |
59 int half_life_days_; | |
60 | |
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. | |
64 // | |
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. | |
70 // | |
71 // This list is sorted by the pair's first element in descending order. | |
72 std::vector<CountMaxRelevance> buckets_; | |
73 }; | |
74 | |
75 HUPScoringParams() : experimental_scoring_enabled(false) {} | |
76 | |
77 bool experimental_scoring_enabled; | |
78 | |
79 ScoreBuckets typed_count_buckets; | |
80 | |
81 // Used only when the typed count is 0. | |
82 ScoreBuckets visited_count_buckets; | |
83 }; | |
84 | |
85 // This class manages the Omnibox field trials. | |
86 class OmniboxFieldTrial { | |
87 public: | |
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; | |
92 | |
93 // Activates all dynamic field trials. The main difference between | |
94 // the autocomplete dynamic and static field trials is that the former | |
95 // don't require any code changes on the Chrome side as they are controlled | |
96 // on the server side. Chrome binary simply propagates all necessary | |
97 // information through the X-Client-Data header. | |
98 // This method may be called multiple times. | |
99 static void ActivateDynamicTrials(); | |
100 | |
101 // Returns a bitmap containing AutocompleteProvider::Type values | |
102 // that should be disabled in AutocompleteController. | |
103 // This method simply goes over all autocomplete dynamic field trial groups | |
104 // and looks for group names like "ProvidersDisabled_NNN" where NNN is | |
105 // an integer corresponding to a bitmap mask. All extracted bitmaps | |
106 // are OR-ed together and returned as the final result. | |
107 static int GetDisabledProviderTypes(); | |
108 | |
109 // Returns whether the user is in any dynamic field trial where the | |
110 // group has a the prefix |group_prefix|. | |
111 static bool HasDynamicFieldTrialGroupPrefix(const char *group_prefix); | |
112 | |
113 // --------------------------------------------------------- | |
114 // For the suggest field trial. | |
115 | |
116 // Populates |field_trial_hash| with hashes of the active suggest field trial | |
117 // names, if any. | |
118 static void GetActiveSuggestFieldTrialHashes( | |
119 std::vector<uint32>* field_trial_hash); | |
120 | |
121 // --------------------------------------------------------- | |
122 // For the AutocompleteController "stop timer" field trial. | |
123 | |
124 // Returns the duration to be used for the AutocompleteController's stop | |
125 // timer. Returns the default value of 1.5 seconds if the stop timer | |
126 // override experiment isn't active or if parsing the experiment-provided | |
127 // duration fails. | |
128 static base::TimeDelta StopTimerFieldTrialDuration(); | |
129 | |
130 // --------------------------------------------------------- | |
131 // For the ZeroSuggestProvider field trial. | |
132 | |
133 // Returns whether the user is in any field trial where the | |
134 // ZeroSuggestProvider should be used to get suggestions when the | |
135 // user clicks on the omnibox but has not typed anything yet. | |
136 static bool InZeroSuggestFieldTrial(); | |
137 | |
138 // Returns whether the user is in a ZeroSuggest field trial, but should | |
139 // show most visited URL instead. This is used to compare metrics of | |
140 // ZeroSuggest and most visited suggestions. | |
141 static bool InZeroSuggestMostVisitedFieldTrial(); | |
142 | |
143 // Returns whether the user is in a ZeroSuggest field trial and URL-based | |
144 // suggestions can continue to appear after the user has started typing. | |
145 static bool InZeroSuggestAfterTypingFieldTrial(); | |
146 | |
147 // Returns whether the user is in a ZeroSuggest field trial, but should | |
148 // show recently searched-for queries instead. | |
149 static bool InZeroSuggestPersonalizedFieldTrial(); | |
150 | |
151 // --------------------------------------------------------- | |
152 // For the ShortcutsScoringMaxRelevance experiment that's part of the | |
153 // bundled omnibox field trial. | |
154 | |
155 // If the user is in an experiment group that, given the provided | |
156 // |current_page_classification| context, changes the maximum relevance | |
157 // ShortcutsProvider::CalculateScore() is supposed to assign, extract | |
158 // that maximum relevance score and put in in |max_relevance|. Returns | |
159 // true on a successful extraction. CalculateScore()'s return value is | |
160 // a product of this maximum relevance score and some attenuating factors | |
161 // that are all between 0 and 1. (Note that Shortcuts results may have | |
162 // their scores reduced later if the assigned score is higher than allowed | |
163 // for non-inlineable results. Shortcuts results are not allowed to be | |
164 // inlined.) | |
165 static bool ShortcutsScoringMaxRelevance( | |
166 metrics::OmniboxEventProto::PageClassification | |
167 current_page_classification, | |
168 int* max_relevance); | |
169 | |
170 // --------------------------------------------------------- | |
171 // For the SearchHistory experiment that's part of the bundled omnibox | |
172 // field trial. | |
173 | |
174 // Returns true if the user is in the experiment group that, given the | |
175 // provided |current_page_classification| context, scores search history | |
176 // query suggestions less aggressively so that they don't inline. | |
177 static bool SearchHistoryPreventInlining( | |
178 metrics::OmniboxEventProto::PageClassification | |
179 current_page_classification); | |
180 | |
181 // Returns true if the user is in the experiment group that, given the | |
182 // provided |current_page_classification| context, disables all query | |
183 // suggestions from search history. | |
184 static bool SearchHistoryDisable( | |
185 metrics::OmniboxEventProto::PageClassification | |
186 current_page_classification); | |
187 | |
188 // --------------------------------------------------------- | |
189 // For the DemoteByType experiment that's part of the bundled omnibox field | |
190 // trial. | |
191 | |
192 // If the user is in an experiment group that, in the provided | |
193 // |current_page_classification| context, demotes the relevance scores | |
194 // of certain types of matches, populates the |demotions_by_type| map | |
195 // appropriately. Otherwise, sets |demotions_by_type| to its default | |
196 // value based on the context. | |
197 static void GetDemotionsByType( | |
198 metrics::OmniboxEventProto::PageClassification | |
199 current_page_classification, | |
200 DemotionMultipliers* demotions_by_type); | |
201 | |
202 // --------------------------------------------------------- | |
203 // For the HistoryURL provider new scoring experiment that is part of the | |
204 // bundled omnibox field trial. | |
205 | |
206 // Initializes the HUP |scoring_params| based on the active HUP scoring | |
207 // experiment. If there is no such experiment, this function simply sets | |
208 // |scoring_params|->experimental_scoring_enabled to false. | |
209 static void GetExperimentalHUPScoringParams(HUPScoringParams* scoring_params); | |
210 | |
211 // For the HQPBookmarkValue experiment that's part of the | |
212 // bundled omnibox field trial. | |
213 | |
214 // Returns the value an untyped visit to a bookmark should receive. | |
215 // Compare this value with the default of 1 for non-bookmarked untyped | |
216 // visits to pages and the default of 20 for typed visits. Returns | |
217 // 10 if the bookmark value experiment isn't active. | |
218 static int HQPBookmarkValue(); | |
219 | |
220 // --------------------------------------------------------- | |
221 // For the HQPAllowMatchInTLD experiment that's part of the | |
222 // bundled omnibox field trial. | |
223 | |
224 // Returns true if HQP should allow an input term to match in the | |
225 // top level domain (e.g., .com) of a URL. Returns false if the | |
226 // allow match in TLD experiment isn't active. | |
227 static bool HQPAllowMatchInTLDValue(); | |
228 | |
229 // --------------------------------------------------------- | |
230 // For the HQPAllowMatchInScheme experiment that's part of the | |
231 // bundled omnibox field trial. | |
232 | |
233 // Returns true if HQP should allow an input term to match in the | |
234 // scheme (e.g., http://) of a URL. Returns false if the allow | |
235 // match in scheme experiment isn't active. | |
236 static bool HQPAllowMatchInSchemeValue(); | |
237 | |
238 // --------------------------------------------------------- | |
239 // For the BookmarksIndexURLs experiment that's part of the | |
240 // bundled omnibox field trial. | |
241 | |
242 // Returns true if BookmarkIndex should index the URL of bookmarks | |
243 // (not only the titles) and search for / mark matches in the URLs, | |
244 // and BookmarkProvider should score bookmarks based on both the | |
245 // matches in bookmark title and URL. Returns false if the bookmarks | |
246 // index URLs experiment isn't active. | |
247 static bool BookmarksIndexURLsValue(); | |
248 | |
249 // --------------------------------------------------------- | |
250 // For the DisableInlining experiment that's part of the bundled omnibox | |
251 // field trial. | |
252 | |
253 // Returns true if AutocompleteResult should prevent any suggestion with | |
254 // a non-empty |inline_autocomplete| from being the default match. In | |
255 // other words, prevent an inline autocompletion from appearing as the | |
256 // top suggestion / within the omnibox itself, reordering matches as | |
257 // necessary to make this true. Returns false if the experiment isn't | |
258 // active. | |
259 static bool DisableInlining(); | |
260 | |
261 // --------------------------------------------------------- | |
262 // For the AnswersInSuggest experiment that's part of the bundled omnibox | |
263 // field trial. | |
264 | |
265 // Returns true if the AnswersInSuggest feature should be enabled causing | |
266 // query responses such as current weather conditions or stock quotes | |
267 // to be provided in the Omnibox suggestion list. Considers both the | |
268 // field trial state as well as the overriding command-line flags. | |
269 static bool EnableAnswersInSuggest(); | |
270 | |
271 // --------------------------------------------------------- | |
272 // For the AddUWYTMatchEvenIfPromotedURLs experiment that's part of the | |
273 // bundled omnibox field trial. | |
274 | |
275 // Returns true if HistoryURL Provider should add the URL-what-you-typed match | |
276 // (if valid and reasonable) even if the provider has good inline | |
277 // autocompletions to offer. Normally HistoryURL does not add the UWYT match | |
278 // if there are good inline autocompletions, as the user could simply hit | |
279 // backspace to delete the completion and get the what-you-typed match. | |
280 // However, for the disabling inlining experiment we want to have the UWYT | |
281 // always explicitly displayed at an option if possible. Returns false if | |
282 // the experiment isn't active. | |
283 static bool AddUWYTMatchEvenIfPromotedURLs(); | |
284 | |
285 // --------------------------------------------------------- | |
286 // For the DisplayHintTextWhenPossible experiment that's part of the | |
287 // bundled omnibox field trial. | |
288 | |
289 // Returns true if the omnibox should display hint text (Search | |
290 // <search engine> or type URL) when possible (i.e., the omnibox | |
291 // is otherwise non-empty). | |
292 static bool DisplayHintTextWhenPossible(); | |
293 | |
294 // --------------------------------------------------------- | |
295 // Exposed publicly for the sake of unittests. | |
296 static const char kBundledExperimentFieldTrialName[]; | |
297 // Rule names used by the bundled experiment. | |
298 static const char kShortcutsScoringMaxRelevanceRule[]; | |
299 static const char kSearchHistoryRule[]; | |
300 static const char kDemoteByTypeRule[]; | |
301 static const char kHQPBookmarkValueRule[]; | |
302 static const char kHQPDiscountFrecencyWhenFewVisitsRule[]; | |
303 static const char kHQPAllowMatchInTLDRule[]; | |
304 static const char kHQPAllowMatchInSchemeRule[]; | |
305 static const char kZeroSuggestRule[]; | |
306 static const char kZeroSuggestVariantRule[]; | |
307 static const char kBookmarksIndexURLsRule[]; | |
308 static const char kDisableInliningRule[]; | |
309 static const char kAnswersInSuggestRule[]; | |
310 static const char kAddUWYTMatchEvenIfPromotedURLsRule[]; | |
311 static const char kDisplayHintTextWhenPossibleRule[]; | |
312 | |
313 // Parameter names used by the HUP new scoring experiments. | |
314 static const char kHUPNewScoringEnabledParam[]; | |
315 static const char kHUPNewScoringTypedCountRelevanceCapParam[]; | |
316 static const char kHUPNewScoringTypedCountHalfLifeTimeParam[]; | |
317 static const char kHUPNewScoringTypedCountScoreBucketsParam[]; | |
318 static const char kHUPNewScoringVisitedCountRelevanceCapParam[]; | |
319 static const char kHUPNewScoringVisitedCountHalfLifeTimeParam[]; | |
320 static const char kHUPNewScoringVisitedCountScoreBucketsParam[]; | |
321 | |
322 private: | |
323 friend class OmniboxFieldTrialTest; | |
324 | |
325 // The bundled omnibox experiment comes with a set of parameters | |
326 // (key-value pairs). Each key indicates a certain rule that applies in | |
327 // a certain context. The value indicates what the consequences of | |
328 // applying the rule are. For example, the value of a SearchHistory rule | |
329 // in the context of a search results page might indicate that we should | |
330 // prevent search history matches from inlining. | |
331 // | |
332 // This function returns the value associated with the |rule| that applies | |
333 // in the current context (which currently consists of |page_classification| | |
334 // and whether Instant Extended is enabled). If no such rule exists in the | |
335 // current context, fall back to the rule in various wildcard contexts and | |
336 // return its value if found. If the rule remains unfound in the global | |
337 // context, returns the empty string. For more details, including how we | |
338 // prioritize different wildcard contexts, see the implementation. How to | |
339 // interpret the value is left to the caller; this is rule-dependent. | |
340 static std::string GetValueForRuleInContext( | |
341 const std::string& rule, | |
342 metrics::OmniboxEventProto::PageClassification page_classification); | |
343 | |
344 DISALLOW_IMPLICIT_CONSTRUCTORS(OmniboxFieldTrial); | |
345 }; | |
346 | |
347 #endif // CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_ | |
OLD | NEW |