diff options
Diffstat (limited to 'components/omnibox')
-rw-r--r-- | components/omnibox/omnibox_field_trial.cc | 32 | ||||
-rw-r--r-- | components/omnibox/omnibox_field_trial.h | 19 | ||||
-rw-r--r-- | components/omnibox/omnibox_field_trial_unittest.cc | 82 | ||||
-rw-r--r-- | components/omnibox/search_provider.cc | 35 | ||||
-rw-r--r-- | components/omnibox/search_provider.h | 7 |
5 files changed, 160 insertions, 15 deletions
diff --git a/components/omnibox/omnibox_field_trial.cc b/components/omnibox/omnibox_field_trial.cc index 62cd8ec..7ad2956 100644 --- a/components/omnibox/omnibox_field_trial.cc +++ b/components/omnibox/omnibox_field_trial.cc @@ -343,6 +343,28 @@ bool OmniboxFieldTrial::DisplayHintTextWhenPossible() { kDisplayHintTextWhenPossibleRule) == "true"; } +bool OmniboxFieldTrial::DisableResultsCaching() { + return variations::GetVariationParamValue( + kBundledExperimentFieldTrialName, + kDisableResultsCachingRule) == "true"; +} + +void OmniboxFieldTrial::GetSuggestPollingStrategy(bool* from_last_keystroke, + int* polling_delay_ms) { + *from_last_keystroke = variations::GetVariationParamValue( + kBundledExperimentFieldTrialName, + kMeasureSuggestPollingDelayFromLastKeystrokeRule) == "true"; + + const std::string& polling_delay_string = variations::GetVariationParamValue( + kBundledExperimentFieldTrialName, + kSuggestPollingDelayMsRule); + if (polling_delay_string.empty() || + !base::StringToInt(polling_delay_string, polling_delay_ms) || + (*polling_delay_ms <= 0)) { + *polling_delay_ms = kDefaultMinimumTimeBetweenSuggestQueriesMs; + } +} + const char OmniboxFieldTrial::kBundledExperimentFieldTrialName[] = "OmniboxBundledExperimentV1"; const char OmniboxFieldTrial::kShortcutsScoringMaxRelevanceRule[] = @@ -362,6 +384,13 @@ const char OmniboxFieldTrial::kAddUWYTMatchEvenIfPromotedURLsRule[] = "AddUWYTMatchEvenIfPromotedURLs"; const char OmniboxFieldTrial::kDisplayHintTextWhenPossibleRule[] = "DisplayHintTextWhenPossible"; +const char OmniboxFieldTrial::kDisableResultsCachingRule[] = + "DisableResultsCaching"; +const char +OmniboxFieldTrial::kMeasureSuggestPollingDelayFromLastKeystrokeRule[] = + "MeasureSuggestPollingDelayFromLastKeystroke"; +const char OmniboxFieldTrial::kSuggestPollingDelayMsRule[] = + "SuggestPollingDelayMs"; const char OmniboxFieldTrial::kHUPNewScoringEnabledParam[] = "HUPExperimentalScoringEnabled"; @@ -378,6 +407,9 @@ const char OmniboxFieldTrial::kHUPNewScoringVisitedCountHalfLifeTimeParam[] = const char OmniboxFieldTrial::kHUPNewScoringVisitedCountScoreBucketsParam[] = "VisitedCountScoreBuckets"; +// static +int OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs = 100; + // Background and implementation details: // // Each experiment group in any field trial can come with an optional set of diff --git a/components/omnibox/omnibox_field_trial.h b/components/omnibox/omnibox_field_trial.h index c659b83..d54b2b3 100644 --- a/components/omnibox/omnibox_field_trial.h +++ b/components/omnibox/omnibox_field_trial.h @@ -286,6 +286,17 @@ class OmniboxFieldTrial { 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. @@ -302,6 +313,9 @@ class OmniboxFieldTrial { 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[]; @@ -312,6 +326,11 @@ class OmniboxFieldTrial { 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; diff --git a/components/omnibox/omnibox_field_trial_unittest.cc b/components/omnibox/omnibox_field_trial_unittest.cc index 9a78a67..47f7467 100644 --- a/components/omnibox/omnibox_field_trial_unittest.cc +++ b/components/omnibox/omnibox_field_trial_unittest.cc @@ -52,7 +52,7 @@ class OmniboxFieldTrialTest : public testing::Test { OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); } - // EXPECTS that demotions[match_type] exists with value expected_value. + // EXPECT()s that demotions[match_type] exists with value expected_value. static void VerifyDemotion( const OmniboxFieldTrial::DemotionMultipliers& demotions, AutocompleteMatchType::Type match_type, @@ -65,6 +65,17 @@ class OmniboxFieldTrialTest : public testing::Test { const std::string& rule, OmniboxEventProto::PageClassification page_classification); + // EXPECT()s that OmniboxFieldTrial::GetSuggestPollingStrategy returns + // |expected_from_last_keystroke| and |expected_delay_ms| for the given + // experiment params. If one the rule values is NULL, the corresponding + // variation parameter won't be set thus allowing to test the default + // behavior. + void VerifySuggestPollingStrategy( + const char* from_last_keystroke_rule_value, + const char* polling_delay_ms_rule_value, + bool expected_from_last_keystroke, + int expected_delay_ms); + private: scoped_ptr<base::FieldTrialList> field_trial_list_; @@ -92,6 +103,35 @@ void OmniboxFieldTrialTest::ExpectRuleValue( rule, page_classification)); } +void OmniboxFieldTrialTest::VerifySuggestPollingStrategy( + const char* from_last_keystroke_rule_value, + const char* polling_delay_ms_rule_value, + bool expected_from_last_keystroke, + int expected_delay_ms) { + ResetFieldTrialList(); + std::map<std::string, std::string> params; + if (from_last_keystroke_rule_value != NULL) { + params[std::string( + OmniboxFieldTrial::kMeasureSuggestPollingDelayFromLastKeystrokeRule)] = + from_last_keystroke_rule_value; + } + if (polling_delay_ms_rule_value != NULL) { + params[std::string( + OmniboxFieldTrial::kSuggestPollingDelayMsRule)] = + polling_delay_ms_rule_value; + } + ASSERT_TRUE(variations::AssociateVariationParams( + OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); + base::FieldTrialList::CreateFieldTrial( + OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); + + bool from_last_keystroke; + int delay_ms; + OmniboxFieldTrial::GetSuggestPollingStrategy(&from_last_keystroke, &delay_ms); + EXPECT_EQ(expected_from_last_keystroke, from_last_keystroke); + EXPECT_EQ(expected_delay_ms, delay_ms); +} + // Test if GetDisabledProviderTypes() properly parses various field trial // group names. TEST_F(OmniboxFieldTrialTest, GetDisabledProviderTypes) { @@ -378,3 +418,43 @@ TEST_F(OmniboxFieldTrialTest, HalfLifeTimeDecay) { EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::TimeDelta::FromDays(0))); EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::TimeDelta::FromDays(-1))); } + +TEST_F(OmniboxFieldTrialTest, DisableResultsCaching) { + EXPECT_FALSE(OmniboxFieldTrial::DisableResultsCaching()); + + { + std::map<std::string, std::string> params; + params[std::string(OmniboxFieldTrial::kDisableResultsCachingRule)] = "true"; + ASSERT_TRUE(variations::AssociateVariationParams( + OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); + base::FieldTrialList::CreateFieldTrial( + OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); + + EXPECT_TRUE(OmniboxFieldTrial::DisableResultsCaching()); + } +} + +TEST_F(OmniboxFieldTrialTest, GetSuggestPollingStrategy) { + // Invalid params. + VerifySuggestPollingStrategy( + "", "", false, + OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs); + VerifySuggestPollingStrategy( + "foo", "-1", false, + OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs); + VerifySuggestPollingStrategy( + "TRUE", "xyz", false, + OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs); + + // Default values. + VerifySuggestPollingStrategy( + NULL, NULL, false, + OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs); + + // Valid params. + VerifySuggestPollingStrategy("true", "50", true, 50); + VerifySuggestPollingStrategy(NULL, "35", false, 35); + VerifySuggestPollingStrategy( + "true", NULL, true, + OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs); +} diff --git a/components/omnibox/search_provider.cc b/components/omnibox/search_provider.cc index 5cd42c6..f2d2a59 100644 --- a/components/omnibox/search_provider.cc +++ b/components/omnibox/search_provider.cc @@ -116,9 +116,6 @@ class SearchProvider::CompareScoredResults { // SearchProvider ------------------------------------------------------------- -// static -int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100; - SearchProvider::SearchProvider( AutocompleteProviderListener* listener, TemplateURLService* template_url_service, @@ -579,6 +576,21 @@ void SearchProvider::DoHistoryQuery(bool minimal_changes) { } } +base::TimeDelta SearchProvider::GetSuggestQueryDelay() const { + bool from_last_keystroke; + int polling_delay_ms; + OmniboxFieldTrial::GetSuggestPollingStrategy(&from_last_keystroke, + &polling_delay_ms); + + base::TimeDelta delay(base::TimeDelta::FromMilliseconds(polling_delay_ms)); + if (from_last_keystroke) + return delay; + + base::TimeDelta time_since_last_suggest_request = + base::TimeTicks::Now() - time_suggest_request_sent_; + return std::max(base::TimeDelta(), delay - time_since_last_suggest_request); +} + void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { if (!IsQuerySuitableForSuggest()) { StopSuggest(); @@ -586,6 +598,9 @@ void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { return; } + if (OmniboxFieldTrial::DisableResultsCaching()) + ClearAllResults(); + // For the minimal_changes case, if we finished the previous query and still // have its results, or are allowed to keep running it, just do that, rather // than starting a new query. @@ -612,16 +627,16 @@ void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { if (!input_.want_asynchronous_matches()) return; - // To avoid flooding the suggest server, don't send a query until at - // least 100 ms since the last query. - base::TimeTicks next_suggest_time(time_suggest_request_sent_ + - base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenSuggestQueriesMs)); - base::TimeTicks now(base::TimeTicks::Now()); - if (now >= next_suggest_time) { + // Kick off a timer that will start the URL fetch if it completes before + // the user types another character. Requests may be delayed to avoid + // flooding the server with requests that are likely to be thrown away later + // anyway. + const base::TimeDelta delay = GetSuggestQueryDelay(); + if (delay <= base::TimeDelta()) { Run(); return; } - timer_.Start(FROM_HERE, next_suggest_time - now, this, &SearchProvider::Run); + timer_.Start(FROM_HERE, delay, this, &SearchProvider::Run); } bool SearchProvider::IsQuerySuitableForSuggest() const { diff --git a/components/omnibox/search_provider.h b/components/omnibox/search_provider.h index 19696bc..13f81dc 100644 --- a/components/omnibox/search_provider.h +++ b/components/omnibox/search_provider.h @@ -200,6 +200,9 @@ class SearchProvider : public BaseSearchProvider, // This does not update |done_|. void DoHistoryQuery(bool minimal_changes); + // Returns the time to delay before sending the Suggest request. + base::TimeDelta GetSuggestQueryDelay() const; + // Determines whether an asynchronous subcomponent query should run for the // current input. If so, starts it if necessary; otherwise stops it. // NOTE: This function does not update |done_|. Callers must do so. @@ -340,10 +343,6 @@ class SearchProvider : public BaseSearchProvider, // AnswersQueryData. AnswersQueryData FindAnswersPrefetchData(); - // The amount of time to wait before sending a new suggest request after the - // previous one. Non-const because some unittests modify this value. - static int kMinimumTimeBetweenSuggestQueriesMs; - AutocompleteProviderListener* listener_; // The number of suggest results that haven't yet arrived. If it's greater |