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