Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / omnibox / omnibox_field_trial.h
1 // Copyright 2014 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 COMPONENTS_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_
6 #define COMPONENTS_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  // COMPONENTS_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_