0

Change ContextualSearchProvider to get Lens inputs async

Lens suggest inputs are an async process, that require a handshake with
the server. If the ContextualSearchProvider makes the suggest request
before the inputs are ready, the request will fail. To fix this, the
ContextualSearchProvider will now wait for the suggest inputs
asynchronously, and issue the suggest request when they are ready. This
CL also must change the autocomplete controller to allow the CSP to
provide suggestions after done, since the suggest inputs might take
longer than the request.

Note: Other flows the use Lens suggest inputs still grab them
synchronously, and were not included in this CL in favor of a longer
term rework.

Bug: 408227398
Change-Id: I620e40e3e47d4236438216ccc322a7e59d849fce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6435196
Reviewed-by: Orin Jaworski <orinj@chromium.org>
Reviewed-by: Moe Ahmadi <mahmadi@chromium.org>
Reviewed-by: Sergio Collazos <sczs@chromium.org>
Commit-Queue: Duncan Mercer <mercerd@google.com>
Cr-Commit-Position: refs/heads/main@{#1444445}
This commit is contained in:
Duncan Mercer
2025-04-08 16:25:08 -07:00
committed by Chromium LUCI CQ
parent 638242dc1b
commit be0b8966fc
16 changed files with 227 additions and 29 deletions

@ -54,6 +54,7 @@
#include "components/omnibox/browser/actions/omnibox_pedal_provider.h"
#include "components/omnibox/browser/autocomplete_classifier.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/lens_suggest_inputs_utils.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/omnibox_triggered_feature_service.h"
#include "components/omnibox/browser/shortcuts_backend.h"
@ -504,6 +505,24 @@ bool ChromeAutocompleteProviderClient::IsHistoryEmbeddingsSettingVisible()
return history_embeddings::IsHistoryEmbeddingsSettingVisible(profile_);
}
base::CallbackListSubscription
ChromeAutocompleteProviderClient::GetLensSuggestInputsWhenReady(
LensOverlaySuggestInputsCallback callback) const {
// TODO(crbug.com/408513470): This is a temporary prototype solution. Long term,
// `BrowserList::GetInstance()->GetLastActive()` shouldn't be used.
#if !BUILDFLAG(IS_ANDROID)
if (Browser* browser = BrowserList::GetInstance()->GetLastActive()) {
CHECK(browser->GetActiveTabInterface());
return browser->GetActiveTabInterface()
->GetTabFeatures()
->lens_overlay_controller()
->GetLensSuggestInputsWhenReady(std::move(callback));
}
#endif // !BUILDFLAG(IS_ANDROID)
std::move(callback).Run(std::nullopt);
return {};
}
base::WeakPtr<AutocompleteProviderClient>
ChromeAutocompleteProviderClient::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
@ -577,8 +596,9 @@ bool ChromeAutocompleteProviderClient::OpenJourneys(const std::string& query) {
}
void ChromeAutocompleteProviderClient::OpenLensOverlay(bool show) {
// TODO(crbug.com/408513470): This is a temporary prototype solution. Long term,
// `BrowserList::GetInstance()->GetLastActive()` shouldn't be used.
#if !BUILDFLAG(IS_ANDROID)
// TODO(crbug.com/401583049): Prepare lens overlay controller directly.
if (Browser* browser = BrowserList::GetInstance()->GetLastActive()) {
CHECK(browser->GetActiveTabInterface());
// TODO(crbug.com/402497756): For prototyping, reusing the existing
@ -604,6 +624,8 @@ void ChromeAutocompleteProviderClient::IssueContextualSearchRequest(
const GURL& destination_url,
AutocompleteMatchType::Type match_type,
bool is_zero_prefix_suggestion) {
// TODO(crbug.com/408513470): This is a temporary prototype solution. Long term,
// `BrowserList::GetInstance()->GetLastActive()` shouldn't be used.
#if !BUILDFLAG(IS_ANDROID)
if (Browser* browser = BrowserList::GetInstance()->GetLastActive()) {
CHECK(browser->GetActiveTabInterface());

@ -114,6 +114,8 @@ class ChromeAutocompleteProviderClient : public AutocompleteProviderClient {
bool IsSharingHubAvailable() const override;
bool IsHistoryEmbeddingsEnabled() const override;
bool IsHistoryEmbeddingsSettingVisible() const override;
base::CallbackListSubscription GetLensSuggestInputsWhenReady(
LensOverlaySuggestInputsCallback callback) const override;
base::WeakPtr<AutocompleteProviderClient> GetWeakPtr() override;
// OmniboxAction::Client:

@ -22,6 +22,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
#include "components/omnibox/browser/lens_suggest_inputs_utils.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
@ -2592,7 +2593,7 @@ void LensOverlayController::InitializeOverlayUI(
if (pending_region_) {
page_->SetPostRegionSelection(pending_region_->Clone());
}
if (init_data.suggest_inputs_.has_encoded_request_id()) {
if (IsHandshakeComplete()) {
// Notify the overlay that it is safe to query autocomplete.
page_->NotifyHandshakeComplete();
}
@ -2783,6 +2784,17 @@ void LensOverlayController::OnImmersiveFullscreenExited() {
}
}
void LensOverlayController::OnHandshakeComplete() {
CHECK(IsHandshakeComplete());
// Notify the overlay that the handshake is complete if its initialized.
if (page_) {
page_->NotifyHandshakeComplete();
}
// Send the suggest inputs to any pending callbacks.
pending_suggest_inputs_callbacks_.Notify(GetLensSuggestInputs());
}
const GURL& LensOverlayController::GetPageURL() const {
if (lens::CanSharePageURLWithLensOverlay(pref_service_)) {
return tab_->GetContents()->GetVisibleURL();
@ -2813,9 +2825,11 @@ std::string& LensOverlayController::GetThumbnail() {
const lens::proto::LensOverlaySuggestInputs&
LensOverlayController::GetLensSuggestInputs() const {
return initialization_data_
? initialization_data_->suggest_inputs_
: lens::proto::LensOverlaySuggestInputs().default_instance();
if (!initialization_data_ && !pre_initialization_suggest_inputs_) {
return lens::proto::LensOverlaySuggestInputs().default_instance();
}
return initialization_data_ ? initialization_data_->suggest_inputs_
: pre_initialization_suggest_inputs_.value();
}
void LensOverlayController::OnTextModified() {
@ -2935,6 +2949,23 @@ void LensOverlayController::OnZeroSuggestShown() {
}
}
base::CallbackListSubscription
LensOverlayController::GetLensSuggestInputsWhenReady(
LensOverlaySuggestInputsCallback callback) {
// Exit early if the overlay is either off or going to soon be off.
if (state() == State::kOff || IsOverlayClosing()) {
std::move(callback).Run(std::nullopt);
return {};
}
// If the handshake is complete, return the Lens suggest inputs immediately.
if (IsHandshakeComplete()) {
std::move(callback).Run(initialization_data_->suggest_inputs_);
return {};
}
return pending_suggest_inputs_callbacks_.Add(std::move(callback));
}
std::optional<std::string> LensOverlayController::GetPageTitle() {
std::optional<std::string> page_title;
content::WebContents* active_web_contents = tab_->GetContents();
@ -3570,19 +3601,22 @@ void LensOverlayController::HandleSuggestInputsResponse(
return;
}
// Check if the handshake with the server has been completed. This is
// signified bysuggest inputs having an encoded request ID. If the previous
// `suggest_inputs` already had an encoded request ID, then the handshake was
// already completed and we do not need to notify again. If `page_` doesn't
// exist, then it will be notified when it is created.
if (page_ &&
!initialization_data_->suggest_inputs_.has_encoded_request_id() &&
suggest_inputs.has_encoded_request_id()) {
// Notify the overlay that it is now safe to query autocomplete.
page_->NotifyHandshakeComplete();
// If the handshake was already complete, without the new suggest inputs,
// exit early so that we do not notify OnHandshakeComplete() multiple times.
if (IsHandshakeComplete()) {
initialization_data_->suggest_inputs_ = suggest_inputs;
return;
}
// Check if the handshake with the server has been completed with the new
// inputs. If so, this is the first time we are receiving the suggest inputs,
// so we need to notify OnHandshakeComplete() to allow the searchbox to query
// autocomplete.
initialization_data_->suggest_inputs_ = suggest_inputs;
if (IsHandshakeComplete()) {
// Notify the overlay that it is now safe to query autocomplete.
OnHandshakeComplete();
}
}
void LensOverlayController::HandlePageContentUploadProgress(uint64_t position,
@ -3899,6 +3933,16 @@ void LensOverlayController::UpdateNavigationMetrics() {
contextual_searchbox_focused_after_navigation_ = false;
}
bool LensOverlayController::IsHandshakeComplete() {
if (!initialization_data_ && !pre_initialization_suggest_inputs_) {
return false;
}
const auto& suggest_inputs = initialization_data_
? initialization_data_->suggest_inputs_
: pre_initialization_suggest_inputs_;
return AreLensSuggestInputsReady(suggest_inputs);
}
bool LensOverlayController::IsUrlEligibleForTutorialIPH(const GURL& url) {
if (!tutorial_iph_url_matcher_) {
return false;

@ -48,6 +48,7 @@
#include "components/lens/lens_overlay_side_panel_result.h"
#include "components/lens/proto/server/lens_overlay_response.pb.h"
#include "components/omnibox/browser/autocomplete_match_type.h"
#include "components/omnibox/browser/lens_suggest_inputs_utils.h"
#include "components/optimization_guide/proto/features/common_quality_data.pb.h"
#include "components/sessions/core/session_id.h"
#include "components/tabs/public/tab_interface.h"
@ -454,6 +455,12 @@ class LensOverlayController : public LensSearchboxClient,
// Whether it's possible to capture a screenshot. virtual for testing.
virtual bool IsScreenshotPossible(content::RenderWidgetHostView* view);
// Waits for the handshake with the Lens backend to complete and then invokes
// the callback with the LensOverlaySuggestInputs. Callback will be invoked
// immediately if the handshake is already complete.
base::CallbackListSubscription GetLensSuggestInputsWhenReady(
LensOverlaySuggestInputsCallback callback);
// Called before the lens results panel begins hiding. This is called before
// any side panel closing animations begin.
void OnSidePanelWillHide(SidePanelEntryHideReason reason);
@ -491,6 +498,9 @@ class LensOverlayController : public LensSearchboxClient,
// Updates the metrics related to navigations for the current page.
void UpdateNavigationMetrics();
// Returns whether the handshake with the Lens backend is complete.
bool IsHandshakeComplete();
// Testing function to issue a Lens region selection request.
void IssueLensRegionRequestForTesting(lens::mojom::CenterRotatedBoxPtr region,
bool is_click);
@ -956,6 +966,9 @@ class LensOverlayController : public LensSearchboxClient,
void OnImmersiveFullscreenEntered() override;
void OnImmersiveFullscreenExited() override;
// Called when the Lens backend handshake is complete.
void OnHandshakeComplete();
// Overridden from LensSearchboxClient:
const GURL& GetPageURL() const override;
SessionID GetTabId() const override;
@ -974,6 +987,11 @@ class LensOverlayController : public LensSearchboxClient,
void ShowGhostLoaderErrorState() override;
void OnZeroSuggestShown() override;
// Adds a callback to be called when the Lens backend handshake is finished.
// If the handshake is already finished, the callback will be called
// immediately.
void OnLensBackendHandshakeFinished(base::OnceClosure callback);
// Gets the page title.
std::optional<std::string> GetPageTitle();
@ -1298,6 +1316,12 @@ class LensOverlayController : public LensSearchboxClient,
// Holds subscriptions for TabInterface callbacks.
std::vector<base::CallbackListSubscription> tab_subscriptions_;
// The callbacks pending the handshake to complete so the Lens suggest inputs
// can be retrieved.
base::OnceCallbackList<void(
std::optional<lens::proto::LensOverlaySuggestInputs>)>
pending_suggest_inputs_callbacks_;
// Owned by Profile, and thus guaranteed to outlive this instance.
raw_ptr<variations::VariationsClient> variations_client_;

@ -235,6 +235,7 @@ static_library("browser") {
"keyword_extensions_delegate.h",
"keyword_provider.cc",
"keyword_provider.h",
"lens_suggest_inputs_utils.h",
"local_history_zero_suggest_provider.cc",
"local_history_zero_suggest_provider.h",
"match_compare.h",

@ -865,10 +865,14 @@ void AutocompleteController::OnProviderUpdate(
// Allow some providers to trigger updates after `stop_timer_` has fired.
// TODO(crbug.com/364303536) This is a temporary fix for allowing history
// embedding answers to `UpdateResults()` after `stop_timer_` has fired.
// TODO(crbug.com/408512535): This is a temporary fix for allowing the
// contextual search provider to `UpdateResults()` after `stop_timer_` has
// fired.
bool allow_post_done_updates =
provider &&
(provider->type() == AutocompleteProvider::TYPE_HISTORY_EMBEDDINGS ||
provider->type() == AutocompleteProvider::TYPE_UNSCOPED_EXTENSION ||
provider->type() == AutocompleteProvider::TYPE_CONTEXTUAL_SEARCH ||
provider->type() ==
AutocompleteProvider::TYPE_ENTERPRISE_SEARCH_AGGREGATOR);

@ -4,6 +4,8 @@
#include "components/omnibox/browser/autocomplete_provider_client.h"
#include "base/notreached.h"
history_clusters::HistoryClustersService*
AutocompleteProviderClient::GetHistoryClustersService() {
return nullptr;

@ -9,10 +9,12 @@
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "components/history/core/browser/keyword_id.h"
#include "components/omnibox/browser/actions/omnibox_action.h"
#include "components/omnibox/browser/lens_suggest_inputs_utils.h"
#include "third_party/metrics_proto/omnibox_event.pb.h"
class AutocompleteClassifier;
@ -107,6 +109,8 @@ class AutocompleteProviderClient : public OmniboxAction::Client {
const = 0;
virtual OnDeviceTailModelService* GetOnDeviceTailModelService() const = 0;
virtual ProviderStateService* GetProviderStateService() const = 0;
virtual base::CallbackListSubscription GetLensSuggestInputsWhenReady(
LensOverlaySuggestInputsCallback callback) const = 0;
// The value to use for Accept-Languages HTTP header when making an HTTP
// request.

@ -6,6 +6,7 @@
#include <stddef.h>
#include <cmath>
#include <optional>
#include <string>
#include <utility>
@ -28,6 +29,7 @@
#include "components/omnibox/browser/autocomplete_provider_client.h"
#include "components/omnibox/browser/autocomplete_provider_debouncer.h"
#include "components/omnibox/browser/autocomplete_provider_listener.h"
#include "components/omnibox/browser/lens_suggest_inputs_utils.h"
#include "components/omnibox/browser/match_compare.h"
#include "components/omnibox/browser/page_classification_functions.h"
#include "components/omnibox/browser/remote_suggestions_service.h"
@ -87,7 +89,9 @@ void ContextualSearchProvider::Start(
const AutocompleteInput& autocomplete_input,
bool minimal_changes) {
TRACE_EVENT0("omnibox", "ContextualSearchProvider::Start");
Stop(true, false);
// Clear the cached results to remove the page search action matches. Also,
// matches the behavior of the `ZeroSuggestProvider`.
Stop(/*clear_cached_results=*/true, /*due_to_user_inactivity=*/false);
if (client()->IsOffTheRecord()) {
done_ = true;
@ -112,21 +116,27 @@ void ContextualSearchProvider::Start(
AddDefaultVerbatimMatch(input);
if (input.lens_overlay_suggest_inputs().has_value()) {
if(!input.text().empty()) {
// Only make the suggest request for zero suggest in keyword mode.
done_ = true;
return;
}
done_ = false;
StartSuggestRequest(std::move(input));
} else {
done_ = true;
}
}
void ContextualSearchProvider::Stop(bool clear_cached_results,
bool due_to_user_inactivity) {
if (!due_to_user_inactivity) {
// Stop the pending request if the sotp is not due to user inactivity. If
// it is due to user inactivity, the request will continue so the
// suggestions can be shown when they are ready.
AutocompleteProvider::Stop(clear_cached_results, due_to_user_inactivity);
input_keyword_.clear();
if (loader_) {
lens_suggest_inputs_subscription_ = {};
loader_.reset();
}
input_keyword_.clear();
}
void ContextualSearchProvider::AddProviderInfo(
@ -153,6 +163,34 @@ bool ContextualSearchProvider::ShouldAppendExtraParams(
}
void ContextualSearchProvider::StartSuggestRequest(AutocompleteInput input) {
if (AreLensSuggestInputsReady(input.lens_overlay_suggest_inputs()) ||
!base::FeatureList::IsEnabled(
omnibox::kContextualSearchProviderAsyncSuggestInputs)) {
// If the suggest inputs are ready, make the suggest request immediately.
// Also, skip the async wait if the feature is disabled.
MakeSuggestRequest(std::move(input));
return;
}
// Wait for the suggest inputs to be generated and then make the suggest
// request. Safe to use base::Unretained(this) because the subscription is
// reset and cancelled if this provider is destroyed.
lens_suggest_inputs_subscription_ = client()->GetLensSuggestInputsWhenReady(
base::BindOnce(&ContextualSearchProvider::OnLensSuggestInputsReady,
base::Unretained(this), std::move(input)));
}
void ContextualSearchProvider::OnLensSuggestInputsReady(
AutocompleteInput input,
std::optional<lens::proto::LensOverlaySuggestInputs> lens_suggest_inputs) {
CHECK(!AreLensSuggestInputsReady(input.lens_overlay_suggest_inputs()));
if (lens_suggest_inputs) {
input.set_lens_overlay_suggest_inputs(*lens_suggest_inputs);
}
MakeSuggestRequest(std::move(input));
}
void ContextualSearchProvider::MakeSuggestRequest(AutocompleteInput input) {
TemplateURLRef::SearchTermsArgs search_terms_args;
// TODO(crbug.com/404608703): Consider new types or taking from `input`.
@ -166,6 +204,9 @@ void ContextualSearchProvider::StartSuggestRequest(AutocompleteInput input) {
search_terms_args.lens_overlay_suggest_inputs =
input.lens_overlay_suggest_inputs();
// Make the request and store the loader to keep it alive. Destroying the
// loader will cancel the request. Safe to use base::Unretained(this) because
// the loader is reset and destroyed if this provider is destroyed.
loader_ =
client()
->GetRemoteSuggestionsService(/*create_if_necessary=*/true)
@ -175,7 +216,7 @@ void ContextualSearchProvider::StartSuggestRequest(AutocompleteInput input) {
search_terms_args,
client()->GetTemplateURLService()->search_terms_data(),
base::BindOnce(&ContextualSearchProvider::SuggestRequestCompleted,
weak_ptr_factory_.GetWeakPtr(), std::move(input)));
base::Unretained(this), std::move(input)));
}
void ContextualSearchProvider::SuggestRequestCompleted(

@ -8,7 +8,7 @@
#include <memory>
#include <string>
#include "base/memory/weak_ptr.h"
#include "base/callback_list.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/base_search_provider.h"
@ -45,10 +45,19 @@ class ContextualSearchProvider : public BaseSearchProvider {
const SearchSuggestionParser::SuggestResult& result) const override;
void RecordDeletionResult(bool success) override {}
// Sends request to remote suggest server. Invoked after all inputs
// are ready, including page context.
// Waits for the Lens suggest inputs to be ready and then sends the request to
// the remote suggest server. If the inputs are already ready, the request is
//sent immediately.
void StartSuggestRequest(AutocompleteInput input);
// Attaches the lens suggest inputs to `input` and makes the suggest request.
void OnLensSuggestInputsReady(
AutocompleteInput input,
std::optional<lens::proto::LensOverlaySuggestInputs> lens_suggest_inputs);
// Makes the suggest request with the given input.
void MakeSuggestRequest(AutocompleteInput input);
// Called when the suggest network request has completed.
void SuggestRequestCompleted(AutocompleteInput input,
const network::SimpleURLLoader* source,
@ -79,8 +88,9 @@ class ContextualSearchProvider : public BaseSearchProvider {
// Loader used to retrieve suggest results.
std::unique_ptr<network::SimpleURLLoader> loader_;
// For callbacks that may be run after destruction.
base::WeakPtrFactory<ContextualSearchProvider> weak_ptr_factory_{this};
// Holds the subscription to get the Lens suggest inputs. If the subscription
// is freed, the callback will not be run.
base::CallbackListSubscription lens_suggest_inputs_subscription_;
};
#endif // COMPONENTS_OMNIBOX_BROWSER_CONTEXTUAL_SEARCH_PROVIDER_H_

@ -0,0 +1,24 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_OMNIBOX_BROWSER_LENS_SUGGEST_INPUTS_UTILS_H_
#define COMPONENTS_OMNIBOX_BROWSER_LENS_SUGGEST_INPUTS_UTILS_H_
#include "base/functional/callback.h"
#include "components/lens/proto/server/lens_overlay_response.pb.h"
// A callback that returns the LensOverlaySuggestInputs when they are ready if
// they exist. Returns std::nullopt if they do not exist.
using LensOverlaySuggestInputsCallback = base::OnceCallback<void(
std::optional<lens::proto::LensOverlaySuggestInputs>)>;
inline bool AreLensSuggestInputsReady(
std::optional<lens::proto::LensOverlaySuggestInputs> suggest_inputs) {
return suggest_inputs.has_value() &&
suggest_inputs->has_search_session_id() &&
suggest_inputs->has_contextual_visual_input_type() &&
suggest_inputs->has_encoded_request_id();
}
#endif // COMPONENTS_OMNIBOX_BROWSER_LENS_SUGGEST_INPUTS_UTILS_H_

@ -145,6 +145,9 @@ class MockAutocompleteProviderClient
MOCK_CONST_METHOD0(IsSyncActive, bool());
MOCK_CONST_METHOD0(IsHistoryEmbeddingsEnabled, bool());
MOCK_CONST_METHOD0(IsHistoryEmbeddingsSettingVisible, bool());
MOCK_CONST_METHOD1(GetLensSuggestInputsWhenReady,
base::CallbackListSubscription(
LensOverlaySuggestInputsCallback callback));
MOCK_METHOD6(
Classify,

@ -141,6 +141,12 @@ BASE_FEATURE(kContextualZeroSuggestLensFulfillment,
"ContextualZeroSuggestLensFulfillment",
DISABLED);
// Enables the contextual search provider to wait for the Lens suggest inputs
// to be ready before making the suggest request.
BASE_FEATURE(kContextualSearchProviderAsyncSuggestInputs,
"ContextualSearchProviderAsyncSuggestInputs",
ENABLED);
// Features to provide head and tail non personalized search suggestion from
// compact on device models. More specifically, feature name with suffix
// Incognito / NonIncognito will only controls behaviors under incognito /

@ -54,6 +54,8 @@ BASE_DECLARE_FEATURE(kZeroSuggestPrefetchingOnWeb);
// current page, by using more than the URL, i.e. the page content.
BASE_DECLARE_FEATURE(kContextualZeroSuggestLensFulfillment);
BASE_DECLARE_FEATURE(kContextualSearchProviderAsyncSuggestInputs);
// On Device Suggest.
BASE_DECLARE_FEATURE(kOnDeviceHeadProviderIncognito);
BASE_DECLARE_FEATURE(kOnDeviceHeadProviderNonIncognito);

@ -69,6 +69,8 @@ class AutocompleteProviderClientImpl : public AutocompleteProviderClient {
const override;
OnDeviceTailModelService* GetOnDeviceTailModelService() const override;
ProviderStateService* GetProviderStateService() const override;
base::CallbackListSubscription GetLensSuggestInputsWhenReady(
LensOverlaySuggestInputsCallback callback) const override;
std::string GetAcceptLanguages() const override;
std::string GetEmbedderRepresentationOfAboutScheme() const override;
std::vector<std::u16string> GetBuiltinURLs() override;

@ -187,6 +187,13 @@ ProviderStateService* AutocompleteProviderClientImpl::GetProviderStateService()
return ios::ProviderStateServiceFactory::GetForProfile(profile_);
}
base::CallbackListSubscription
AutocompleteProviderClientImpl::GetLensSuggestInputsWhenReady(
LensOverlaySuggestInputsCallback callback) const {
NOTREACHED()
<< "GetLensSuggestInputsWhenReady is not implemented by default.";
}
std::string AutocompleteProviderClientImpl::GetAcceptLanguages() const {
return profile_->GetPrefs()->GetString(language::prefs::kAcceptLanguages);
}