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 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
|
// 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_BROWSER_OMNIBOX_FIELD_TRIAL_H_
#define COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_FIELD_TRIAL_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include "base/macros.h"
#include "components/metrics/proto/omnibox_event.pb.h"
#include "components/metrics/proto/omnibox_input_type.pb.h"
#include "components/omnibox/browser/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 based on the decay factor or counts specified
// in the corresponding bucket list. See comment on |buckets_| for details.
class ScoreBuckets {
public:
// Stores the max relevance at each count/decay factor threshold.
typedef std::pair<double, int> CountMaxRelevance;
ScoreBuckets();
ScoreBuckets(const ScoreBuckets& other);
~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;
}
bool use_decay_factor() const { return use_decay_factor_; }
void set_use_decay_factor(bool use_decay_factor) {
use_decay_factor_ = use_decay_factor;
}
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 at successively decreasing threshold values.
// The thresholds are either decayed counts or decay factors, depending on
// the value of |use_decay_factor_|.
//
// Consider this example specifying the decayed counts:
// [(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_;
// True when the bucket thresholds are decay factors rather than counts.
bool use_decay_factor_;
};
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;
// A vector that maps from the number of matching pages to the document
// specificity score used in HistoryQuick provider / ScoredHistoryMatch
// scoring. The vector is sorted by the size_t (the number of matching pages).
// If an entry is omitted, the appropriate value is assumed to be the one in
// the later bucket. For example, with a vector containing {{1, 2.0},
// {3, 1.5}}, the score for 2 is inferred to be 1.5. Values beyond the
// end of the vector are assumed to have scores of 1.0.
typedef std::vector<std::pair<size_t, double>> NumMatchesScores;
// Do not change these values as they need to be in sync with values
// specified in experiment configs on the variations server.
enum EmphasizeTitlesCondition {
EMPHASIZE_WHEN_NONEMPTY = 0,
EMPHASIZE_WHEN_TITLE_MATCHES = 1,
EMPHASIZE_WHEN_ONLY_TITLE_MATCHES = 2,
EMPHASIZE_NEVER = 3
};
// ---------------------------------------------------------
// 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_t>* 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 GetDefaultHUPScoringParams(HUPScoringParams* scoring_params);
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 float 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 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);
// ---------------------------------------------------------
// For HQP scoring related experiments to control the topicality and scoring
// ranges of relevancy scores.
// Returns the scoring buckets for HQP experiments. Returns an empty string
// if scoring buckets are not specified in the field trial. Scoring buckets
// are stored in string form giving mapping from (topicality_score,
// frequency_score) to final relevance score. Please see GetRelevancyScore()
// under chrome/browser/history::ScoredHistoryMatch for details.
static std::string HQPExperimentalScoringBuckets();
// Returns the topicality threshold for HQP experiments. Returns a default
// value of 0.8 if no threshold is specified in the field trial.
static float HQPExperimentalTopicalityThreshold();
// ---------------------------------------------------------
// For the HQPFixFrequencyScoring experiment that's part of the
// bundled omnibox field trial.
// Returns true if HQP should apply the bug fix to discount the visits to
// pages visited less than ten times.
static bool HQPFixFewVisitsBug();
// Returns true if HQP should use the weighted sum when computing frequency
// scores. False means to use the weighted average. Returns false if the
// experiment isn't active.
static bool HQPFreqencyUsesSum();
// Returns the number of visits HQP should use when computing frequency
// scores. Returns 10 if the epxeriment isn't active.
static size_t HQPMaxVisitsToScore();
// Returns the score that should be given to typed transitions. (The score
// of non-typed transitions is 1.) Returns 20 if the experiment isn't active.
static float HQPTypedValue();
// Returns NumMatchesScores; see comment by the declaration of it.
// Returns an empty NumMatchesScores if the experiment isn't active.
static NumMatchesScores HQPNumMatchesScores();
// ---------------------------------------------------------
// For the HQPNumTitleWords experiment that's part of the
// bundled omnibox field trial.
// Returns the number of title words that are allowed to contribute
// to the topicality score. Words later in the title are ignored.
// Returns 20 as a default if the experiment isn't active.
static size_t HQPNumTitleWordsToAllow();
// ---------------------------------------------------------
// For the replace HUP experiment that's part of the bundled omnibox field
// trial.
// Returns whether HistoryQuick provider (HQP) should attempt to score
// suggestions also with a HistoryURL-provider-like (HUP-like) mode, and
// assign suggestions the max of this score and the normal score.
// Returns false if the experiment isn't active.
static bool HQPAlsoDoHUPLikeScoring();
// Returns whether HistoryURL provider (HUP) should search its database for
// URLs and suggest them. If false, HistoryURL provider merely creates the
// URL-what-you-typed match when appropriate. Return true if the experiment
// isn't active.
static bool HUPSearchDatabase();
// ---------------------------------------------------------
// For the aggressive keyword matching experiment that's part of the bundled
// omnibox field trial.
// Returns whether KeywordProvider should consider the registry portion
// (e.g., co.uk) of keywords that look like hostnames as an important part of
// the keyword name for matching purposes. Returns true if the experiment
// isn't active.
static bool KeywordRequiresRegistry();
// For keywords that look like hostnames, returns whether KeywordProvider
// should require users to type a prefix of the hostname to match against
// them, rather than just the domain name portion. In other words, returns
// whether the prefix before the domain name should be considered important
// for matching purposes. Returns true if the experiment isn't active.
static bool KeywordRequiresPrefixMatch();
// Returns the relevance score that KeywordProvider should assign to keywords
// with sufficiently-complete matches, i.e., the user has typed all of the
// important part of the keyword. Returns -1 if the experiment isn't active.
static int KeywordScoreForSufficientlyCompleteMatch();
// ---------------------------------------------------------
// For the EmphasizeTitles experiment that's part of the bundled omnibox
// field trial.
// Returns the conditions under which the UI code should display the title
// of a URL more prominently than the URL for an input of type |input_type|.
// Normally the URL is displayed more prominently. Returns NEVER_EMPHASIZE
// if the experiment isn't active.
static EmphasizeTitlesCondition GetEmphasizeTitlesConditionForInput(
metrics::OmniboxInputType::Type input_type);
// ---------------------------------------------------------
// For PhysicalWebProvider related experiments.
// Returns whether the user is in a Physical Web field trial where the
// PhysicalWebProvider should be used to get suggestions when the user clicks
// on the omnibox but has not typed anything yet.
static bool InPhysicalWebZeroSuggestFieldTrial();
// Returns whether the user is in a Physical Web field trial and URL-based
// suggestions can continue to appear after the user has started typing.
static bool InPhysicalWebAfterTypingFieldTrial();
// Returns the base relevance score for Physical Web omnibox suggestions when
// the user has clicked on the omnibox but has not typed anything yet.
static int GetPhysicalWebZeroSuggestBaseRelevance();
// Returns the base relevance score for Physical Web omnibox suggestions when
// the user has started typing in the omnibox.
static int GetPhysicalWebAfterTypingBaseRelevance();
// ---------------------------------------------------------
// 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 kHQPTypedValueRule[];
static const char kHQPDiscountFrecencyWhenFewVisitsRule[];
static const char kHQPAllowMatchInTLDRule[];
static const char kHQPAllowMatchInSchemeRule[];
static const char kZeroSuggestRule[];
static const char kZeroSuggestVariantRule[];
static const char kSuggestVariantRule[];
static const char kDisableResultsCachingRule[];
static const char kMeasureSuggestPollingDelayFromLastKeystrokeRule[];
static const char kSuggestPollingDelayMsRule[];
static const char kHQPFixFewVisitsBugRule[];
static const char kHQPFreqencyUsesSumRule[];
static const char kHQPMaxVisitsToScoreRule[];
static const char kHQPNumMatchesScoresRule[];
static const char kHQPNumTitleWordsRule[];
static const char kHQPAlsoDoHUPLikeScoringRule[];
static const char kHUPSearchDatabaseRule[];
static const char kPreventUWYTDefaultForNonURLInputsRule[];
static const char kKeywordRequiresRegistryRule[];
static const char kKeywordRequiresPrefixMatchRule[];
static const char kKeywordScoreForSufficientlyCompleteMatchRule[];
static const char kHQPAllowDupMatchesForScoringRule[];
static const char kEmphasizeTitlesRule[];
static const char kPhysicalWebZeroSuggestRule[];
static const char kPhysicalWebAfterTypingRule[];
// 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 kHUPNewScoringTypedCountUseDecayFactorParam[];
static const char kHUPNewScoringVisitedCountRelevanceCapParam[];
static const char kHUPNewScoringVisitedCountHalfLifeTimeParam[];
static const char kHUPNewScoringVisitedCountScoreBucketsParam[];
static const char kHUPNewScoringVisitedCountUseDecayFactorParam[];
// Parameter names used by the HQP experimental scoring experiments.
static const char kHQPExperimentalScoringBucketsParam[];
static const char kHQPExperimentalScoringTopicalityThresholdParam[];
// Parameter names used by the Physical Web experimental scoring experiments.
static const char kPhysicalWebZeroSuggestBaseRelevanceParam[];
static const char kPhysicalWebAfterTypingBaseRelevanceParam[];
// 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_BROWSER_OMNIBOX_FIELD_TRIAL_H_
|