Commit bf3c8ab9 authored by manuk's avatar manuk Committed by Commit Bot

[omnibox] Debounce document provider.

Prior to this CL, only the search provider debounced requests. This CL
introduces AutocompleteProviderDebouncer which can be reused by other providers.

Debouncing doc provider is behind a feature "OmniboxDebounceDocumentProvider"
and configured by the params "DebounceDocumentProviderFromLastRun" and
"DebounceDocumentProviderDelayMs".

Bug: 1015820, 864302
Change-Id: I397a29848e8d1abde3c8ecdaec91cef2e416e37a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1869393Reviewed-by: default avatarJustin Donnelly <jdonnelly@chromium.org>
Commit-Queue: manuk hovanesian <manukh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709084}
parent 81be4cc8
...@@ -94,6 +94,8 @@ jumbo_static_library("browser") { ...@@ -94,6 +94,8 @@ jumbo_static_library("browser") {
"autocomplete_provider.h", "autocomplete_provider.h",
"autocomplete_provider_client.cc", "autocomplete_provider_client.cc",
"autocomplete_provider_client.h", "autocomplete_provider_client.h",
"autocomplete_provider_debouncer.cc",
"autocomplete_provider_debouncer.h",
"autocomplete_result.cc", "autocomplete_result.cc",
"autocomplete_result.h", "autocomplete_result.h",
"autocomplete_scheme_classifier.h", "autocomplete_scheme_classifier.h",
......
// Copyright 2019 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.
#include "autocomplete_provider_debouncer.h"
AutocompleteProviderDebouncer::AutocompleteProviderDebouncer(bool from_last_run,
int delay_ms)
: from_last_run_(from_last_run), delay_ms_(delay_ms) {}
AutocompleteProviderDebouncer::~AutocompleteProviderDebouncer() = default;
void AutocompleteProviderDebouncer::RequestRun(
base::OnceCallback<void()> callback) {
callback_ = std::move(callback);
base::TimeDelta delay(base::TimeDelta::FromMilliseconds(delay_ms_));
if (from_last_run_)
delay -= base::TimeTicks::Now() - time_last_run_;
if (delay <= base::TimeDelta())
Run();
else {
timer_.Start(FROM_HERE, delay,
base::BindOnce(&AutocompleteProviderDebouncer::Run,
base::Unretained(this)));
}
}
void AutocompleteProviderDebouncer::CancelRequest() {
timer_.Stop();
}
void AutocompleteProviderDebouncer::Run() {
time_last_run_ = base::TimeTicks::Now();
std::move(callback_).Run();
}
// Copyright 2019 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_AUTOCOMPLETE_PROVIDER_DEBOUNCER_H_
#define COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_PROVIDER_DEBOUNCER_H_
#include "base/callback.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
// Debounces a method call, i.e. throttles its call rate by delaying its
// invocations and cancelling pending ones when new ones are requested.
class AutocompleteProviderDebouncer {
public:
AutocompleteProviderDebouncer(bool from_last_run, int delay_ms);
~AutocompleteProviderDebouncer();
// Request |callback| to be invoked after the debouncing delay. If called
// while a previous request is still pending, the previous request will be
// cancelled.
void RequestRun(base::OnceCallback<void()> callback);
// Cancels any pending request.
void CancelRequest();
private:
void Run();
// Whether debounce delays are calculated since |time_last_run_| or the last
// invocation of |RequestRun|.
bool from_last_run_ = false;
// The debounce delay.
int delay_ms_ = 0;
// Tracks when to next invoke |callback_|.
base::OneShotTimer timer_;
// The last time |Run| was invoked.
base::TimeTicks time_last_run_;
// The callback to invoke once |timer_| expires.
base::OnceCallback<void()> callback_;
};
#endif // COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_PROVIDER_DEBOUNCER_H_
...@@ -479,9 +479,14 @@ void DocumentProvider::Start(const AutocompleteInput& input, ...@@ -479,9 +479,14 @@ void DocumentProvider::Start(const AutocompleteInput& input,
} }
done_ = false; // Set true in callbacks. done_ = false; // Set true in callbacks.
debouncer_->RequestRun(
base::BindOnce(&DocumentProvider::Run, base::Unretained(this)));
}
void DocumentProvider::Run() {
client_->GetDocumentSuggestionsService(/*create_if_necessary=*/true) client_->GetDocumentSuggestionsService(/*create_if_necessary=*/true)
->CreateDocumentSuggestionsRequest( ->CreateDocumentSuggestionsRequest(
input.text(), client_->IsOffTheRecord(), input_.text(), client_->IsOffTheRecord(),
base::BindOnce( base::BindOnce(
&DocumentProvider::OnDocumentSuggestionsLoaderAvailable, &DocumentProvider::OnDocumentSuggestionsLoaderAvailable,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
...@@ -493,6 +498,7 @@ void DocumentProvider::Start(const AutocompleteInput& input, ...@@ -493,6 +498,7 @@ void DocumentProvider::Start(const AutocompleteInput& input,
void DocumentProvider::Stop(bool clear_cached_results, void DocumentProvider::Stop(bool clear_cached_results,
bool due_to_user_inactivity) { bool due_to_user_inactivity) {
TRACE_EVENT0("omnibox", "DocumentProvider::Stop"); TRACE_EVENT0("omnibox", "DocumentProvider::Stop");
debouncer_->CancelRequest();
if (loader_) if (loader_)
LogOmniboxDocumentRequest(DOCUMENT_REQUEST_INVALIDATED); LogOmniboxDocumentRequest(DOCUMENT_REQUEST_INVALIDATED);
loader_.reset(); loader_.reset();
...@@ -579,7 +585,19 @@ DocumentProvider::DocumentProvider(AutocompleteProviderClient* client, ...@@ -579,7 +585,19 @@ DocumentProvider::DocumentProvider(AutocompleteProviderClient* client,
client_(client), client_(client),
listener_(listener), listener_(listener),
cache_size_(cache_size), cache_size_(cache_size),
matches_cache_(MatchesCache::NO_AUTO_EVICT) {} matches_cache_(MatchesCache::NO_AUTO_EVICT) {
if (base::FeatureList::IsEnabled(omnibox::kDebounceDocumentProvider)) {
bool from_last_run = base::GetFieldTrialParamByFeatureAsBool(
omnibox::kDebounceDocumentProvider,
"DebounceDocumentProviderFromLastRun", true);
int delay_ms = base::GetFieldTrialParamByFeatureAsInt(
omnibox::kDebounceDocumentProvider, "DebounceDocumentProviderDelayMs",
100);
debouncer_ = std::make_unique<AutocompleteProviderDebouncer>(from_last_run,
delay_ms);
} else
debouncer_ = std::make_unique<AutocompleteProviderDebouncer>(false, 0);
}
DocumentProvider::~DocumentProvider() {} DocumentProvider::~DocumentProvider() {}
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "components/history/core/browser/history_types.h" #include "components/history/core/browser/history_types.h"
#include "components/omnibox/browser/autocomplete_provider.h" #include "components/omnibox/browser/autocomplete_provider.h"
#include "components/omnibox/browser/autocomplete_provider_debouncer.h"
#include "components/omnibox/browser/search_provider.h" #include "components/omnibox/browser/search_provider.h"
#include "third_party/metrics_proto/omnibox_event.pb.h" #include "third_party/metrics_proto/omnibox_event.pb.h"
...@@ -125,6 +126,9 @@ class DocumentProvider : public AutocompleteProvider { ...@@ -125,6 +126,9 @@ class DocumentProvider : public AutocompleteProvider {
// We avoid queries for these cases for quality and scaling reasons. // We avoid queries for these cases for quality and scaling reasons.
static bool IsInputLikelyURL(const AutocompleteInput& input); static bool IsInputLikelyURL(const AutocompleteInput& input);
// Called by |debouncer_|, queued when |start| is called.
void Run();
// Called when the network request for suggestions has completed. // Called when the network request for suggestions has completed.
void OnURLLoadComplete(const network::SimpleURLLoader* source, void OnURLLoadComplete(const network::SimpleURLLoader* source,
std::unique_ptr<std::string> response_body); std::unique_ptr<std::string> response_body);
...@@ -212,6 +216,8 @@ class DocumentProvider : public AutocompleteProvider { ...@@ -212,6 +216,8 @@ class DocumentProvider : public AutocompleteProvider {
const size_t cache_size_; const size_t cache_size_;
MatchesCache matches_cache_; MatchesCache matches_cache_;
std::unique_ptr<AutocompleteProviderDebouncer> debouncer_;
// For callbacks that may be run after destruction. Must be declared last. // For callbacks that may be run after destruction. Must be declared last.
base::WeakPtrFactory<DocumentProvider> weak_ptr_factory_{this}; base::WeakPtrFactory<DocumentProvider> weak_ptr_factory_{this};
......
...@@ -686,6 +686,8 @@ void SearchProvider::DoHistoryQuery(bool minimal_changes) { ...@@ -686,6 +686,8 @@ void SearchProvider::DoHistoryQuery(bool minimal_changes) {
} }
base::TimeDelta SearchProvider::GetSuggestQueryDelay() const { base::TimeDelta SearchProvider::GetSuggestQueryDelay() const {
// TODO(manukh): Reuse AutocompleteProviderDebouncer which duplicates all
// this logic and would avoid polling field trial params repeatedly.
bool from_last_keystroke; bool from_last_keystroke;
int polling_delay_ms; int polling_delay_ms;
OmniboxFieldTrial::GetSuggestPollingStrategy(&from_last_keystroke, OmniboxFieldTrial::GetSuggestPollingStrategy(&from_last_keystroke,
......
...@@ -257,6 +257,19 @@ const base::Feature kOmniboxDisableInstantExtendedLimit{ ...@@ -257,6 +257,19 @@ const base::Feature kOmniboxDisableInstantExtendedLimit{
const base::Feature kOmniboxSearchEngineLogo{"OmniboxSearchEngineLogo", const base::Feature kOmniboxSearchEngineLogo{"OmniboxSearchEngineLogo",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
// Feature used to allow users to remove suggestions from clipboard.
const base::Feature kOmniboxRemoveSuggestionsFromClipboard{
"OmniboxRemoveSuggestionsFromClipboard", base::FEATURE_DISABLED_BY_DEFAULT};
// Feature to provide non personalized head search suggestion from a compact
// on device model.
const base::Feature kOnDeviceHeadProvider{"OmniboxOnDeviceHeadProvider",
base::FEATURE_DISABLED_BY_DEFAULT};
// Feature to debounce drive requests from the document provider.
const base::Feature kDebounceDocumentProvider{
"OmniboxDebounceDocumentProvider", base::FEATURE_DISABLED_BY_DEFAULT};
// Exempts the default match from demotion-by-type. // Exempts the default match from demotion-by-type.
const base::Feature kOmniboxPreserveDefaultMatchScore { const base::Feature kOmniboxPreserveDefaultMatchScore {
"OmniboxPreserveDefaultMatchScore", "OmniboxPreserveDefaultMatchScore",
...@@ -275,10 +288,6 @@ const base::Feature kOmniboxPreserveDefaultMatchAgainstAsyncUpdate{ ...@@ -275,10 +288,6 @@ const base::Feature kOmniboxPreserveDefaultMatchAgainstAsyncUpdate{
"OmniboxPreserveDefaultMatchAgainstAsyncUpdate", "OmniboxPreserveDefaultMatchAgainstAsyncUpdate",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
// Feature used to allow users to remove suggestions from clipboard.
const base::Feature kOmniboxRemoveSuggestionsFromClipboard{
"OmniboxRemoveSuggestionsFromClipboard", base::FEATURE_DISABLED_BY_DEFAULT};
// Feature to configure on-focus suggestions provided by ZeroSuggestProvider. // Feature to configure on-focus suggestions provided by ZeroSuggestProvider.
// This feature's main job is to contain some field trial parameters such as: // This feature's main job is to contain some field trial parameters such as:
// - "ZeroSuggestVariant" configures the per-page-classification mode of // - "ZeroSuggestVariant" configures the per-page-classification mode of
...@@ -300,11 +309,6 @@ const base::Feature kZeroSuggestionsOnNTPRealbox{ ...@@ -300,11 +309,6 @@ const base::Feature kZeroSuggestionsOnNTPRealbox{
const base::Feature kZeroSuggestionsOnSERP{"OmniboxZeroSuggestionsOnSERP", const base::Feature kZeroSuggestionsOnSERP{"OmniboxZeroSuggestionsOnSERP",
base::FEATURE_ENABLED_BY_DEFAULT}; base::FEATURE_ENABLED_BY_DEFAULT};
// Feature to provide non personalized head search suggestion from a compact
// on device model.
const base::Feature kOnDeviceHeadProvider{"OmniboxOnDeviceHeadProvider",
base::FEATURE_DISABLED_BY_DEFAULT};
// If enabled, shows a confirm dialog before removing search suggestions from // If enabled, shows a confirm dialog before removing search suggestions from
// the omnibox. See ConfirmNtpSuggestionRemovals for the NTP equivalent. // the omnibox. See ConfirmNtpSuggestionRemovals for the NTP equivalent.
const base::Feature kConfirmOmniboxSuggestionRemovals{ const base::Feature kConfirmOmniboxSuggestionRemovals{
......
...@@ -35,19 +35,20 @@ extern const base::Feature kEnableClipboardProviderTextSuggestions; ...@@ -35,19 +35,20 @@ extern const base::Feature kEnableClipboardProviderTextSuggestions;
extern const base::Feature kEnableClipboardProviderImageSuggestions; extern const base::Feature kEnableClipboardProviderImageSuggestions;
extern const base::Feature kSearchProviderWarmUpOnFocus; extern const base::Feature kSearchProviderWarmUpOnFocus;
extern const base::Feature kDisplayTitleForCurrentUrl; extern const base::Feature kDisplayTitleForCurrentUrl;
extern const base::Feature kQueryInOmnibox;
extern const base::Feature kUIExperimentMaxAutocompleteMatches; extern const base::Feature kUIExperimentMaxAutocompleteMatches;
extern const base::Feature kQueryInOmnibox;
extern const base::Feature kUIExperimentShowSuggestionFavicons; extern const base::Feature kUIExperimentShowSuggestionFavicons;
extern const base::Feature kUIExperimentSwapTitleAndUrl; extern const base::Feature kUIExperimentSwapTitleAndUrl;
extern const base::Feature kSpeculativeServiceWorkerStartOnQueryInput; extern const base::Feature kSpeculativeServiceWorkerStartOnQueryInput;
extern const base::Feature kDocumentProvider; extern const base::Feature kDocumentProvider;
extern const base::Feature kOnDeviceHeadProvider;
extern const base::Feature kAutocompleteTitles; extern const base::Feature kAutocompleteTitles;
extern const base::Feature kOmniboxPopupShortcutIconsInZeroState; extern const base::Feature kOmniboxPopupShortcutIconsInZeroState;
extern const base::Feature kOmniboxMaterialDesignWeatherIcons; extern const base::Feature kOmniboxMaterialDesignWeatherIcons;
extern const base::Feature kOmniboxDisableInstantExtendedLimit; extern const base::Feature kOmniboxDisableInstantExtendedLimit;
extern const base::Feature kOmniboxSearchEngineLogo; extern const base::Feature kOmniboxSearchEngineLogo;
extern const base::Feature kOmniboxRemoveSuggestionsFromClipboard; extern const base::Feature kOmniboxRemoveSuggestionsFromClipboard;
extern const base::Feature kOnDeviceHeadProvider;
extern const base::Feature kDebounceDocumentProvider;
// Flags that affect the "twiddle" step of AutocompleteResult, i.e. SortAndCull. // Flags that affect the "twiddle" step of AutocompleteResult, i.e. SortAndCull.
// TODO(tommycli): There are more flags above that belong in this category. // TODO(tommycli): There are more flags above that belong in this category.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment