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 <set> 10 #include <string> 11 #include <vector> 12 13 #include "base/basictypes.h" 14 #include "base/gtest_prod_util.h" 15 #include "chrome/browser/autocomplete/autocomplete_input.h" 16 #include "chrome/common/autocomplete_match_type.h" 17 18 // This class manages the Omnibox field trials. 19 class OmniboxFieldTrial { 20 public: 21 // A mapping that contains multipliers indicating that matches of the 22 // specified type should have their relevance score multiplied by the 23 // given number. Omitted types are assumed to have multipliers of 1.0. 24 typedef std::map<AutocompleteMatchType::Type, float> DemotionMultipliers; 25 26 // A set of types that should not be demoted when they are the top match. 27 typedef std::set<AutocompleteMatchType::Type> UndemotableTopMatchTypes; 28 29 // Creates the static field trial groups. 30 // *** MUST NOT BE CALLED MORE THAN ONCE. *** 31 static void ActivateStaticTrials(); 32 33 // Activates all dynamic field trials. The main difference between 34 // the autocomplete dynamic and static field trials is that the former 35 // don't require any code changes on the Chrome side as they are controlled 36 // on the server side. Chrome binary simply propagates all necessary 37 // information through the X-Client-Data header. 38 // This method, unlike ActivateStaticTrials(), may be called multiple times. 39 static void ActivateDynamicTrials(); 40 41 // Returns a bitmap containing AutocompleteProvider::Type values 42 // that should be disabled in AutocompleteController. 43 // This method simply goes over all autocomplete dynamic field trial groups 44 // and looks for group names like "ProvidersDisabled_NNN" where NNN is 45 // an integer corresponding to a bitmap mask. All extracted bitmaps 46 // are OR-ed together and returned as the final result. 47 static int GetDisabledProviderTypes(); 48 49 // Returns whether the user is in any dynamic field trial where the 50 // group has a the prefix |group_prefix|. 51 static bool HasDynamicFieldTrialGroupPrefix(const char *group_prefix); 52 53 // --------------------------------------------------------- 54 // For the suggest field trial. 55 56 // Populates |field_trial_hash| with hashes of the active suggest field trial 57 // names, if any. 58 static void GetActiveSuggestFieldTrialHashes( 59 std::vector<uint32>* field_trial_hash); 60 61 // --------------------------------------------------------- 62 // For the HistoryURL provider disable culling redirects field trial. 63 64 // Returns whether the user is in any group for this field trial. 65 // (Should always be true unless initialization went wrong.) 66 static bool InHUPCullRedirectsFieldTrial(); 67 68 // Returns whether we should disable culling of redirects in 69 // HistoryURL provider. 70 static bool InHUPCullRedirectsFieldTrialExperimentGroup(); 71 72 // --------------------------------------------------------- 73 // For the HistoryURL provider disable creating a shorter match 74 // field trial. 75 76 // Returns whether the user is in any group for this field trial. 77 // (Should always be true unless initialization went wrong.) 78 static bool InHUPCreateShorterMatchFieldTrial(); 79 80 // Returns whether we should disable creating a shorter match in 81 // HistoryURL provider. 82 static bool InHUPCreateShorterMatchFieldTrialExperimentGroup(); 83 84 // --------------------------------------------------------- 85 // For the AutocompleteController "stop timer" field trial. 86 87 // Returns whether the user should get the experimental setup or the 88 // default setup for this field trial. The experiment group uses 89 // a timer in AutocompleteController to tell the providers to stop 90 // looking for matches after too much time has passed. In other words, 91 // it tries to tell the providers to stop updating the list of suggested 92 // matches if updating the matches would probably be disruptive because 93 // they're arriving so late. 94 static bool InStopTimerFieldTrialExperimentGroup(); 95 96 // --------------------------------------------------------- 97 // For the ZeroSuggestProvider field trial. 98 99 // Returns whether the user is in any field trial where the 100 // ZeroSuggestProvider should be used to get suggestions when the 101 // user clicks on the omnibox but has not typed anything yet. 102 static bool InZeroSuggestFieldTrial(); 103 104 // Returns whether the user is in a ZeroSuggest field trial, but should 105 // show most visited URL instead. This is used to compare metrics of 106 // ZeroSuggest and most visited suggestions. 107 static bool InZeroSuggestMostVisitedFieldTrial(); 108 109 // Returns whether the user is in a ZeroSuggest field trial and URL-based 110 // suggestions can continue to appear after the user has started typing. 111 static bool InZeroSuggestAfterTypingFieldTrial(); 112 113 // --------------------------------------------------------- 114 // For the ShortcutsScoringMaxRelevance experiment that's part of the 115 // bundled omnibox field trial. 116 117 // If the user is in an experiment group that, given the provided 118 // |current_page_classification| context, changes the maximum relevance 119 // ShortcutsProvider::CalculateScore() is supposed to assign, extract 120 // that maximum relevance score and put in in |max_relevance|. Returns 121 // true on a successful extraction. CalculateScore()'s return value is 122 // a product of this maximum relevance score and some attenuating factors 123 // that are all between 0 and 1. (Note that Shortcuts results may have 124 // their scores reduced later if the assigned score is higher than allowed 125 // for non-inlineable results. Shortcuts results are not allowed to be 126 // inlined.) 127 static bool ShortcutsScoringMaxRelevance( 128 AutocompleteInput::PageClassification current_page_classification, 129 int* max_relevance); 130 131 // --------------------------------------------------------- 132 // For the SearchHistory experiment that's part of the bundled omnibox 133 // field trial. 134 135 // Returns true if the user is in the experiment group that, given the 136 // provided |current_page_classification| context, scores search history 137 // query suggestions less aggressively so that they don't inline. 138 static bool SearchHistoryPreventInlining( 139 AutocompleteInput::PageClassification current_page_classification); 140 141 // Returns true if the user is in the experiment group that, given the 142 // provided |current_page_classification| context, disables all query 143 // suggestions from search history. 144 static bool SearchHistoryDisable( 145 AutocompleteInput::PageClassification current_page_classification); 146 147 // --------------------------------------------------------- 148 // For the DemoteByType experiment that's part of the bundled omnibox field 149 // trial. 150 151 // If the user is in an experiment group that, in the provided 152 // |current_page_classification| context, demotes the relevance scores 153 // of certain types of matches, populates the |demotions_by_type| map 154 // appropriately. Otherwise, clears |demotions_by_type|. 155 static void GetDemotionsByType( 156 AutocompleteInput::PageClassification current_page_classification, 157 DemotionMultipliers* demotions_by_type); 158 159 // Get the set of types that should not be demoted if they are the top 160 // match. 161 static UndemotableTopMatchTypes GetUndemotableTopTypes( 162 AutocompleteInput::PageClassification current_page_classification); 163 164 // --------------------------------------------------------- 165 // For the ReorderForLegalDefaultMatch experiment that's part of the 166 // bundled omnibox field trial. 167 168 // Returns true if the omnibox will reorder matches, in the provided 169 // |current_page_classification| context so that a match that's allowed to 170 // be the default match will appear first. This means AutocompleteProviders 171 // can score matches however they desire without regard to making sure the 172 // top match when all the matches from all providers are merged is a legal 173 // default match. 174 static bool ReorderForLegalDefaultMatch( 175 AutocompleteInput::PageClassification current_page_classification); 176 177 // --------------------------------------------------------- 178 // For the HQPBookmarkValue experiment that's part of the 179 // bundled omnibox field trial. 180 181 // Returns the value an untyped visit to a bookmark should receive. 182 // Compare this value with the default of 1 for non-bookmarked untyped 183 // visits to pages and the default of 20 for typed visits. Returns 184 // 1 if the bookmark value experiment isn't active. 185 static int HQPBookmarkValue(); 186 187 // --------------------------------------------------------- 188 // For the HQPDiscountFrecencyWhenFewVisits experiment that's part of 189 // the bundled omnibox field trial. 190 191 // Returns whether to discount the frecency score estimates when a 192 // URL has fewer than ScoredHistoryMatch::kMaxVisitsToScore visits. 193 // See comments in scored_history_match.h for details. Returns false 194 // if the discount frecency experiment isn't active. 195 static bool HQPDiscountFrecencyWhenFewVisits(); 196 197 // --------------------------------------------------------- 198 // For the HQPAllowMatchInTLD experiment that's part of the 199 // bundled omnibox field trial. 200 201 // Returns true if HQP should allow an input term to match in the 202 // top level domain (e.g., .com) of a URL. Returns false if the 203 // allow match in TLD experiment isn't active. 204 static bool HQPAllowMatchInTLDValue(); 205 206 // --------------------------------------------------------- 207 // For the HQPAllowMatchInScheme experiment that's part of the 208 // bundled omnibox field trial. 209 210 // Returns true if HQP should allow an input term to match in the 211 // scheme (e.g., http://) of a URL. Returns false if the allow 212 // match in scheme experiment isn't active. 213 static bool HQPAllowMatchInSchemeValue(); 214 215 // --------------------------------------------------------- 216 // Exposed publicly for the sake of unittests. 217 static const char kBundledExperimentFieldTrialName[]; 218 // Rule names used by the bundled experiment. 219 static const char kShortcutsScoringMaxRelevanceRule[]; 220 static const char kSearchHistoryRule[]; 221 static const char kDemoteByTypeRule[]; 222 static const char kUndemotableTopTypeRule[]; 223 static const char kReorderForLegalDefaultMatchRule[]; 224 static const char kHQPBookmarkValueRule[]; 225 static const char kHQPDiscountFrecencyWhenFewVisitsRule[]; 226 static const char kHQPAllowMatchInTLDRule[]; 227 static const char kHQPAllowMatchInSchemeRule[]; 228 // Rule values. 229 static const char kReorderForLegalDefaultMatchRuleDisabled[]; 230 231 private: 232 friend class OmniboxFieldTrialTest; 233 234 // The bundled omnibox experiment comes with a set of parameters 235 // (key-value pairs). Each key indicates a certain rule that applies in 236 // a certain context. The value indicates what the consequences of 237 // applying the rule are. For example, the value of a SearchHistory rule 238 // in the context of a search results page might indicate that we should 239 // prevent search history matches from inlining. 240 // 241 // This function returns the value associated with the |rule| that applies 242 // in the current context (which currently consists of |page_classification| 243 // and whether Instant Extended is enabled). If no such rule exists in the 244 // current context, fall back to the rule in various wildcard contexts and 245 // return its value if found. If the rule remains unfound in the global 246 // context, returns the empty string. For more details, including how we 247 // prioritize different wildcard contexts, see the implementation. How to 248 // interpret the value is left to the caller; this is rule-dependent. 249 static std::string GetValueForRuleInContext( 250 const std::string& rule, 251 AutocompleteInput::PageClassification page_classification); 252 253 DISALLOW_IMPLICIT_CONSTRUCTORS(OmniboxFieldTrial); 254 }; 255 256 #endif // CHROME_BROWSER_OMNIBOX_OMNIBOX_FIELD_TRIAL_H_ 257