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