// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/omnibox/chrome_omnibox_client.h"

#include <stddef.h>

#include <algorithm>
#include <memory>
#include <utility>

#include "base/functional/bind.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "base/rand_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/trace_event/typed_macros.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
#include "chrome/browser/autocomplete/shortcuts_backend_factory.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service_factory.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/feedback/public/feedback_source.h"
#include "chrome/browser/feedback/show_feedback_page.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history_embeddings/history_embeddings_utils.h"
#include "chrome/browser/omnibox/autocomplete_controller_emitter_factory.h"
#include "chrome/browser/predictors/autocomplete_action_predictor.h"
#include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
#include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/loading_predictor_factory.h"
#include "chrome/browser/preloading/autocomplete_dictionary_preload_service.h"
#include "chrome/browser/preloading/autocomplete_dictionary_preload_service_factory.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_factory.h"
#include "chrome/browser/preloading/preloading_features.h"
#include "chrome/browser/preloading/prerender/prerender_manager.h"
#include "chrome/browser/preloading/prerender/prerender_utils.h"
#include "chrome/browser/preloading/search_preload/search_preload_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ssl/typed_navigation_upgrade_throttle.h"
#include "chrome/browser/ui/bookmarks/bookmark_stats.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/hats/hats_service.h"
#include "chrome/browser/ui/hats/hats_service_factory.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/lens/lens_search_controller.h"
#include "chrome/browser/ui/lens/lens_searchbox_controller.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.h"
#include "chrome/browser/ui/omnibox/omnibox_next_features.h"
#include "chrome/browser/ui/omnibox/omnibox_tab_helper.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/search_engines/dse_reset_dialog.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/pref_names.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "components/favicon/core/favicon_service.h"
#include "components/omnibox/browser/autocomplete_controller_emitter.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_result.h"
#include "components/omnibox/browser/base_search_provider.h"
#include "components/omnibox/browser/location_bar_model.h"
#include "components/omnibox/browser/most_visited_sites_provider.h"
#include "components/omnibox/browser/omnibox_prefs.h"
#include "components/omnibox/browser/page_classification_functions.h"
#include "components/omnibox/browser/search_provider.h"
#include "components/omnibox/browser/shortcuts_backend.h"
#include "components/omnibox/browser/zero_suggest_provider.h"
#include "components/omnibox/common/omnibox_feature_configs.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/profile_metrics/browser_profile_type.h"
#include "components/search_engines/template_url_service.h"
#include "components/search_engines/template_url_starter_pack_data.h"
#include "components/sessions/content/session_tab_helper.h"
#include "components/strings/grit/components_strings.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/constants.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "skia/ext/image_operations.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/vector_icon_types.h"
#include "url/gurl.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h"
#include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h"
#endif

namespace {

using predictors::AutocompleteActionPredictor;

LensSearchController* GetLensSearchController(
    content::WebContents* web_contents) {
  return web_contents ? LensSearchController::FromTabWebContents(web_contents)
                      : nullptr;
}

}  // namespace

ChromeOmniboxClient::ChromeOmniboxClient(LocationBar* location_bar,
                                         Browser* browser,
                                         Profile* profile)
    : location_bar_(location_bar),
      browser_(browser),
      profile_(profile),
      scheme_classifier_(
          std::make_unique<ChromeAutocompleteSchemeClassifier>(profile)),
      favicon_cache_(FaviconServiceFactory::GetForProfile(
                         profile,
                         ServiceAccessType::EXPLICIT_ACCESS),
                     HistoryServiceFactory::GetForProfile(
                         profile,
                         ServiceAccessType::EXPLICIT_ACCESS)) {}

ChromeOmniboxClient::~ChromeOmniboxClient() {
  BitmapFetcherService* bitmap_fetcher_service =
      BitmapFetcherServiceFactory::GetForBrowserContext(profile_);
  for (auto request_id : request_ids_) {
    bitmap_fetcher_service->CancelRequest(request_id);
  }
}

std::unique_ptr<AutocompleteProviderClient>
ChromeOmniboxClient::CreateAutocompleteProviderClient() {
  // base::Unretained(location_bar_) is safe because `location_bar_` outlives
  // `ChromeOmniboxClient` which outlives `AutocompleteController` which owns
  // `ChromeAutocompleteProviderClient`.
  return std::make_unique<ChromeAutocompleteProviderClient>(
      profile_, base::BindRepeating(&LocationBar::GetWebContents,
                                    base::Unretained(location_bar_)));
}

bool ChromeOmniboxClient::CurrentPageExists() const {
  return (location_bar_->GetWebContents() != nullptr);
}

const GURL& ChromeOmniboxClient::GetURL() const {
  return CurrentPageExists() ? location_bar_->GetWebContents()->GetVisibleURL()
                             : GURL::EmptyGURL();
}

const std::u16string& ChromeOmniboxClient::GetTitle() const {
  return CurrentPageExists() ? location_bar_->GetWebContents()->GetTitle()
                             : base::EmptyString16();
}

gfx::Image ChromeOmniboxClient::GetFavicon() const {
  return favicon::ContentFaviconDriver::FromWebContents(
             location_bar_->GetWebContents())
      ->GetFavicon();
}

ukm::SourceId ChromeOmniboxClient::GetUKMSourceId() const {
  return CurrentPageExists() ? location_bar_->GetWebContents()
                                   ->GetPrimaryMainFrame()
                                   ->GetPageUkmSourceId()
                             : ukm::kInvalidSourceId;
}

bool ChromeOmniboxClient::IsLoading() const {
  return location_bar_->GetWebContents()->IsLoading();
}

bool ChromeOmniboxClient::IsPasteAndGoEnabled() const {
  return location_bar_->command_updater()->IsCommandEnabled(
      IDC_OPEN_CURRENT_URL);
}

bool ChromeOmniboxClient::IsDefaultSearchProviderEnabled() const {
  const base::Value::Dict& url_dict = profile_->GetPrefs()->GetDict(
      DefaultSearchManager::kDefaultSearchProviderDataPrefName);
  return !url_dict.FindBool(DefaultSearchManager::kDisabledByPolicy)
              .value_or(false);
}

SessionID ChromeOmniboxClient::GetSessionID() const {
  return sessions::SessionTabHelper::IdForTab(location_bar_->GetWebContents());
}

PrefService* ChromeOmniboxClient::GetPrefs() {
  return profile_->GetPrefs();
}

const PrefService* ChromeOmniboxClient::GetPrefs() const {
  return profile_->GetPrefs();
}

bookmarks::BookmarkModel* ChromeOmniboxClient::GetBookmarkModel() {
  return BookmarkModelFactory::GetForBrowserContext(profile_);
}

AutocompleteControllerEmitter*
ChromeOmniboxClient::GetAutocompleteControllerEmitter() {
  return AutocompleteControllerEmitterFactory::GetForBrowserContext(profile_);
}

TemplateURLService* ChromeOmniboxClient::GetTemplateURLService() {
  return TemplateURLServiceFactory::GetForProfile(profile_);
}

const AutocompleteSchemeClassifier& ChromeOmniboxClient::GetSchemeClassifier()
    const {
  return *scheme_classifier_;
}

AutocompleteClassifier* ChromeOmniboxClient::GetAutocompleteClassifier() {
  return AutocompleteClassifierFactory::GetForProfile(profile_);
}

bool ChromeOmniboxClient::ShouldDefaultTypedNavigationsToHttps() const {
  return base::FeatureList::IsEnabled(omnibox::kDefaultTypedNavigationsToHttps);
}

int ChromeOmniboxClient::GetHttpsPortForTesting() const {
  return TypedNavigationUpgradeThrottle::GetHttpsPortForTesting();
}

bool ChromeOmniboxClient::IsUsingFakeHttpsForHttpsUpgradeTesting() const {
  // Tests on desktop/Android always use a real HTTPS server.
  return false;
}

gfx::Image ChromeOmniboxClient::GetExtensionIcon(
    const TemplateURL* template_url) const {
  CHECK_EQ(template_url->type(), TemplateURL::OMNIBOX_API_EXTENSION);
  return extensions::OmniboxAPI::Get(profile_)->GetOmniboxIcon(
      template_url->GetExtensionId());
}

gfx::Image ChromeOmniboxClient::GetSizedIcon(
    const gfx::VectorIcon& vector_icon_type,
    SkColor vector_icon_color) const {
  return gfx::Image(gfx::CreateVectorIcon(
      vector_icon_type, GetLayoutConstant(LOCATION_BAR_ICON_SIZE),
      vector_icon_color));
}

gfx::Image ChromeOmniboxClient::GetSizedIcon(const SkBitmap* bitmap) const {
  CHECK(bitmap);

  // First, resize the bitmap to `LOCATION_BAR_ICON_SIZE`.
  const int icon_size = GetLayoutConstant(LOCATION_BAR_ICON_SIZE);
  return gfx::Image(gfx::ImageSkiaOperations::CreateResizedImage(
      gfx::ImageSkia::CreateFrom1xBitmap(*bitmap),
      skia::ImageOperations::ResizeMethod::RESIZE_LANCZOS3,
      gfx::Size(icon_size, icon_size)));
}

gfx::Image ChromeOmniboxClient::GetSizedIcon(const gfx::Image& icon) const {
  if (icon.IsEmpty()) {
    return icon;
  }

  const int icon_size = GetLayoutConstant(LOCATION_BAR_ICON_SIZE);
  // In touch mode, icons are 20x20. FaviconCache and ExtensionIconManager both
  // guarantee favicons and extension icons will be 16x16, so add extra padding
  // around them to align them vertically with the other vector icons.
  DCHECK_GE(icon_size, icon.Height());
  DCHECK_GE(icon_size, icon.Width());
  auto padding_border = gfx::Insets::VH((icon_size - icon.Height()) / 2,
                                        (icon_size - icon.Width()) / 2);
  if (!padding_border.IsEmpty()) {
    return gfx::Image(gfx::CanvasImageSource::CreatePadded(*icon.ToImageSkia(),
                                                           padding_border));
  }
  return icon;
}

std::u16string ChromeOmniboxClient::GetFormattedFullURL() const {
  return location_bar_->GetLocationBarModel()->GetFormattedFullURL();
}

std::u16string ChromeOmniboxClient::GetURLForDisplay() const {
  return location_bar_->GetLocationBarModel()->GetURLForDisplay();
}

GURL ChromeOmniboxClient::GetNavigationEntryURL() const {
  return location_bar_->GetLocationBarModel()->GetURL();
}

metrics::OmniboxEventProto::PageClassification
ChromeOmniboxClient::GetPageClassification(bool is_prefetch) const {
  return location_bar_->GetLocationBarModel()->GetPageClassification(
      is_prefetch);
}

metrics::OmniboxEventProto::PageClassification
ChromeOmniboxClient::GetOmniboxComposeboxPageClassification() const {
  return location_bar_->GetLocationBarModel()
      ->GetOmniboxComposeboxPageClassification();
}

security_state::SecurityLevel ChromeOmniboxClient::GetSecurityLevel() const {
  return location_bar_->GetLocationBarModel()->GetSecurityLevel();
}

net::CertStatus ChromeOmniboxClient::GetCertStatus() const {
  return location_bar_->GetLocationBarModel()->GetCertStatus();
}

const gfx::VectorIcon& ChromeOmniboxClient::GetVectorIcon() const {
  return location_bar_->GetLocationBarModel()->GetVectorIcon();
}

void ChromeOmniboxClient::ProcessExtensionMatch(
    const std::u16string& text,
    const TemplateURL* template_url,
    const AutocompleteMatch& match,
    WindowOpenDisposition disposition) {
  // Strip the keyword + leading space (if present) off the input.
  std::u16string remaining_input;
  AutocompleteInput::SplitKeywordFromInput(match.fill_into_edit, true,
                                           &remaining_input);

  // In unscoped mode, the input is sent verbatim. In scoped (keyword) mode, the
  // keyword and input are split, and only the input after the keyword is sent.
  std::string input =
      match.provider->type() == AutocompleteProvider::TYPE_UNSCOPED_EXTENSION
          ? base::UTF16ToUTF8(match.fill_into_edit)
          : base::UTF16ToUTF8(remaining_input);
  extensions::ExtensionOmniboxEventRouter::OnInputEntered(
      location_bar_->GetWebContents(), template_url->GetExtensionId(), input,
      disposition);
}

void ChromeOmniboxClient::OnInputStateChanged() {
  if (!location_bar_->GetWebContents()) {
    return;
  }
  if (auto* helper =
          OmniboxTabHelper::FromWebContents(location_bar_->GetWebContents())) {
    helper->OnInputStateChanged();
  }
}

void ChromeOmniboxClient::OnFocusChanged(OmniboxFocusState state,
                                         OmniboxFocusChangeReason reason) {
  if (!location_bar_->GetWebContents()) {
    return;
  }
  if (auto* helper =
          OmniboxTabHelper::FromWebContents(location_bar_->GetWebContents())) {
    helper->OnFocusChanged(state, reason);
  }
}

void ChromeOmniboxClient::OnKeywordModeChanged(bool entered,
                                               const std::u16string& keyword) {
  if (entered) {
    // Note, entry into keyword mode is not sufficient signal to start lens and
    // that is handled by separate explicit actions; but whenever the '@page'
    // keyword mode is exited, lens should be closed.
    return;
  }

  TemplateURL* template_url =
      GetTemplateURLService()->GetTemplateURLForKeyword(keyword);
  if (!template_url || template_url->starter_pack_id() !=
                           template_url_starter_pack_data::kPage) {
    return;
  }

  if (LensSearchController* lens_search_controller =
          GetLensSearchController(location_bar_->GetWebContents())) {
    // TODO(crbug.com/408073216): Create and use new dismissal source.
    lens_search_controller->CloseLensAsync(
        lens::LensOverlayDismissalSource::kEscapeKeyPress);
  }
}

void ChromeOmniboxClient::MaybeShowOnFocusHatsSurvey(
    AutocompleteProviderClient* client) {
  if (!g_browser_process ||
      !base::StartsWith(g_browser_process->GetApplicationLocale(), "en")) {
    return;
  }

  // Check zero-suggest eligibility criteria.
  auto classification = GetPageClassification(/*is_prefetch=*/false);
  AutocompleteInput input(
      GetNavigationEntryURL().IsAboutBlank()
          ? u""
          : base::UTF8ToUTF16(GetNavigationEntryURL().spec()),
      classification, GetSchemeClassifier());
  input.set_focus_type(metrics::OmniboxFocusType::INTERACTION_FOCUS);
  input.set_current_url(GetNavigationEntryURL());
  if (!ZeroSuggestProvider::GetResultTypeAndEligibility(client, input).second ||
      !MostVisitedSitesProvider::AllowMostVisitedSitesSuggestions(client,
                                                                  input)) {
    return;
  }

  // If the content is for an SRP or Web Page.
  if (!omnibox::IsSearchResultsPage(classification) &&
      !omnibox::IsOtherWebPage(classification)) {
    return;
  }

  auto focus_count = GetPrefs()->GetInteger(omnibox::kFocusedSrpWebCount);
  focus_count += 1;

  if (focus_count <
      static_cast<int>(omnibox_feature_configs::
                           HappinessTrackingSurveyForOmniboxOnFocusZps::Get()
                               .focus_threshold)) {
    GetPrefs()->SetInteger(omnibox::kFocusedSrpWebCount, focus_count);
    return;
  }

  const auto survey_delay_time_ms =
      omnibox_feature_configs::HappinessTrackingSurveyForOmniboxOnFocusZps::
          Get()
              .survey_delay;
  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&ChromeOmniboxClient::CheckConditionsAndLaunchSurvey,
                     weak_factory_.GetWeakPtr()),
      base::Milliseconds(survey_delay_time_ms));
}

void ChromeOmniboxClient::CheckConditionsAndLaunchSurvey() {
  // Roll the dice as we want to show one of two surveys to the treatment
  // group but only one survey to the control group.
  bool show_happiness_survey = base::RandInt(0, 1) == 0;

  // Don't show the suggestions utility survey to control group.
  if (!omnibox_feature_configs::OmniboxUrlSuggestionsOnFocus::Get().enabled &&
      !show_happiness_survey) {
    return;
  }

  // Get channel string to return as PSD.
  std::string channel;
  switch (chrome::GetChannel()) {
    case version_info::Channel::STABLE:
      channel = "stable";
      break;
    case version_info::Channel::BETA:
      channel = "beta";
      break;
    case version_info::Channel::DEV:
      channel = "dev";
      break;
    case version_info::Channel::CANARY:
      channel = "canary";
      break;
    default:
      channel = "unknown";
  }

  const std::string& survey_trigger =
      show_happiness_survey ? kHatsSurveyTriggerOnFocusZpsSuggestionsHappiness
                            : kHatsSurveyTriggerOnFocusZpsSuggestionsUtility;

  const std::string& trigger_id =
      show_happiness_survey
          ? omnibox_feature_configs::
                HappinessTrackingSurveyForOmniboxOnFocusZps::Get()
                    .happiness_trigger_id
          : omnibox_feature_configs::
                HappinessTrackingSurveyForOmniboxOnFocusZps::Get()
                    .utility_trigger_id;

  HatsService* hats_service =
      HatsServiceFactory::GetForProfile(profile_, /*create_if_necessary=*/true);

  if (!browser_) {
    return;
  }

  auto* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);

  if (!browser_view) {
    return;
  }

  auto* location_bar_view = browser_view->GetLocationBarView();

  // Don't show the HaTS survey if the location bar has focus.
  if (location_bar_view &&
      !location_bar_view->Contains(
          location_bar_view->GetFocusManager()->GetFocusedView())) {
    hats_service->LaunchSurvey(
        survey_trigger, base::DoNothing(), base::DoNothing(), {},
        {{"page classification",
          metrics::OmniboxEventProto::PageClassification_Name(
              GetPageClassification(/*is_prefetch=*/false))},
         {"channel", channel}},
        trigger_id, HatsService::SurveyOptions());
  }
}

void ChromeOmniboxClient::OnResultChanged(
    const AutocompleteResult& result,
    bool default_match_changed,
    bool should_preload,
    const BitmapFetchedCallback& on_bitmap_fetched) {
  if (should_preload) {
    if (auto* dictionary_preload_service =
            AutocompleteDictionaryPreloadServiceFactory::GetForProfile(
                profile_)) {
      dictionary_preload_service->MaybePreload(result);
    }
    if (SearchPrefetchService* search_prefetch_service =
            SearchPrefetchServiceFactory::GetForProfile(profile_)) {
      search_prefetch_service->OnResultChanged(location_bar_->GetWebContents(),
                                               result);
    }
    if (auto* search_preload_service =
            SearchPreloadService::GetForProfile(profile_)) {
      search_preload_service->OnAutocompleteResultChanged(
          location_bar_->GetWebContents(), result);
    }
  }

  BitmapFetcherService* bitmap_fetcher_service =
      BitmapFetcherServiceFactory::GetForBrowserContext(profile_);

  // Clear out the old requests.
  for (auto request_id : request_ids_) {
    bitmap_fetcher_service->CancelRequest(request_id);
  }
  request_ids_.clear();
  // Create new requests.
  int result_index = -1;
  for (const AutocompleteMatch& match : result) {
    ++result_index;
    if (!match.icon_url.is_empty()) {
      request_ids_.push_back(bitmap_fetcher_service->RequestImage(
          match.icon_url,
          base::BindOnce(on_bitmap_fetched, result_index, match.icon_url)));
    } else {
      const TemplateURL* turl = nullptr;
      if (!match.associated_keyword.empty()) {
        turl = AutocompleteMatch::GetTemplateURLWithKeyword(
            GetTemplateURLService(), match.associated_keyword, "");
      } else if (!match.keyword.empty()) {
        turl = match.GetTemplateURL(GetTemplateURLService());
      }
      // Fetch the favicon if the `TemplateURL` is from the enterprise search
      // aggregator policy. This covers both cases:
      // 1. Non-featured matches with an associated keyword hint (e.g.,
      //    verbatim match when typing 'aggregator').
      // 2. Matches originating from the aggregator keyword mode itself (e.g.
      //    shortcut suggestions in default mode).
      if (turl && turl->CreatedByEnterpriseSearchAggregatorPolicy()) {
        request_ids_.push_back(bitmap_fetcher_service->RequestImage(
            turl->favicon_url(), base::BindOnce(on_bitmap_fetched, result_index,
                                                turl->favicon_url())));
      }
    }
    if (match.HasTakeoverAction(OmniboxActionId::CONTEXTUAL_SEARCH_OPEN_LENS) &&
        omnibox_feature_configs::ContextualSearch::Get()
            .open_lens_action_uses_thumbnail) {
      if (const content::WebContents* web_contents =
              location_bar_->GetWebContents()) {
        content::RenderWidgetHostView* view =
            web_contents->GetPrimaryMainFrame()
                ->GetRenderViewHost()
                ->GetWidget()
                ->GetView();
        if (view && view->IsSurfaceAvailableForCopy()) {
          view->CopyFromSurface(
              /*src_rect=*/gfx::Rect(),
              /*output_size=*/gfx::Size(),
              base::BindPostTask(
                  base::SequencedTaskRunner::GetCurrentDefault(),
                  base::BindOnce(
                      [](const viz::CopyOutputBitmapWithMetadata& result) {
                        return result.bitmap;
                      })
                      .Then(base::BindOnce(on_bitmap_fetched, result_index,
                                           GURL()))));
        }
      }
    }
    if (!match.ImageUrl().is_empty()) {
      request_ids_.push_back(bitmap_fetcher_service->RequestImage(
          match.ImageUrl(),
          base::BindOnce(on_bitmap_fetched, result_index, GURL())));
    }
  }
}

gfx::Image ChromeOmniboxClient::GetFaviconForPageUrl(
    const GURL& page_url,
    FaviconFetchedCallback on_favicon_fetched) {
  return favicon_cache_.GetFaviconForPageUrl(page_url,
                                             std::move(on_favicon_fetched));
}

gfx::Image ChromeOmniboxClient::GetFaviconForDefaultSearchProvider(
    FaviconFetchedCallback on_favicon_fetched) {
  const TemplateURL* const default_provider =
      GetTemplateURLService()->GetDefaultSearchProvider();
  if (!default_provider) {
    return gfx::Image();
  }

  return favicon_cache_.GetFaviconForIconUrl(default_provider->favicon_url(),
                                             std::move(on_favicon_fetched));
}

gfx::Image ChromeOmniboxClient::GetFaviconForKeywordSearchProvider(
    const TemplateURL* template_url,
    FaviconFetchedCallback on_favicon_fetched) {
  if (!template_url) {
    return gfx::Image();
  }

  return favicon_cache_.GetFaviconForIconUrl(template_url->favicon_url(),
                                             std::move(on_favicon_fetched));
}

void ChromeOmniboxClient::OnTextChanged(const AutocompleteMatch& current_match,
                                        bool user_input_in_progress,
                                        const std::u16string& user_text,
                                        const AutocompleteResult& result,
                                        bool has_focus) {
  AutocompleteActionPredictor::Action recommended_action =
      AutocompleteActionPredictor::ACTION_NONE;
  if (user_input_in_progress) {
    content::WebContents* web_contents = location_bar_->GetWebContents();
    AutocompleteActionPredictor* action_predictor =
        predictors::AutocompleteActionPredictorFactory::GetForProfile(profile_);
    action_predictor->RegisterTransitionalMatches(user_text, result);
    // Confer with the AutocompleteActionPredictor to determine what action,
    // if any, we should take. Get the recommended action here even if we
    // don't need it so we can get stats for anyone who is opted in to UMA,
    // but only get it if the user has actually typed something to avoid
    // constructing it before it's needed. Note: This event is triggered as
    // part of startup when the initial tab transitions to the start page.
    recommended_action = action_predictor->RecommendAction(
        user_text, current_match, web_contents);
  }

  switch (recommended_action) {
    case AutocompleteActionPredictor::ACTION_PRERENDER:
      // It's possible that there is no current page, for instance if the tab
      // has been closed or on return from a sleep state.
      // (http://crbug.com/105689)
      if (!CurrentPageExists()) {
        break;
      }
      // Ask for prerendering if the destination URL is different than the
      // current URL.
      if (current_match.destination_url != GetURL()) {
        DoPrerender(current_match);
      }
      break;
    case AutocompleteActionPredictor::ACTION_PRECONNECT:
      DoPreconnect(current_match);
      break;
    case AutocompleteActionPredictor::ACTION_NONE:
      break;
  }

  location_bar_->OnChanged();
}

void ChromeOmniboxClient::OnRevert() {
  AutocompleteActionPredictor* action_predictor =
      predictors::AutocompleteActionPredictorFactory::GetForProfile(profile_);
  action_predictor->UpdateDatabaseFromTransitionalMatches(GURL());
}

void ChromeOmniboxClient::OnURLOpenedFromOmnibox(OmniboxLog* log) {
  // Record the value if prerender for search suggestion was not started. Other
  // values (kHitFinished, kUnused, kCancelled) are recorded in
  // PrerenderManager.
  content::WebContents* web_contents = location_bar_->GetWebContents();
  if (web_contents) {
    if (SearchPrefetchService* search_prefetch_service =
            SearchPrefetchServiceFactory::GetForProfile(profile_)) {
      search_prefetch_service->OnURLOpenedFromOmnibox(log);
    }

    auto* prerender_manager = PrerenderManager::FromWebContents(web_contents);
    if (!prerender_manager ||
        !prerender_manager->HasSearchResultPagePrerendered()) {
      base::UmaHistogramEnumeration(
          internal::kHistogramPrerenderPredictionStatusDefaultSearchEngine,
          PrerenderPredictionStatus::kNotStarted);
    }
  }

  predictors::AutocompleteActionPredictorFactory::GetForProfile(profile_)
      ->OnOmniboxOpenedUrl(*log);
}

void ChromeOmniboxClient::OnBookmarkLaunched() {
  RecordBookmarkLaunch(BookmarkLaunchLocation::kOmnibox,
                       profile_metrics::GetBrowserProfileType(profile_));
}

void ChromeOmniboxClient::DiscardNonCommittedNavigations() {
  location_bar_->GetWebContents()->GetController().DiscardNonCommittedEntries();
}

void ChromeOmniboxClient::FocusWebContents() {
  if (location_bar_->GetWebContents()) {
    location_bar_->GetWebContents()->Focus();
  }
}

void ChromeOmniboxClient::OnNavigationLikely(
    size_t index,
    const AutocompleteMatch& match,
    omnibox::mojom::NavigationPredictor navigation_predictor) {
  if (SearchPrefetchService* search_prefetch_service =
          SearchPrefetchServiceFactory::GetForProfile(profile_)) {
    search_prefetch_service->OnNavigationLikely(
        index, match, navigation_predictor, location_bar_->GetWebContents());
  }
  if (auto* search_preload_service =
          SearchPreloadService::GetForProfile(profile_)) {
    search_preload_service->OnNavigationLikely(
        index, match, navigation_predictor, location_bar_->GetWebContents());
  }
}

void ChromeOmniboxClient::ShowFeedbackPage(const std::u16string& input_text,
                                           const GURL& destination_url) {
  base::Value::Dict ai_metadata;
  ai_metadata.Set("input", base::UTF16ToUTF8(input_text));
  ai_metadata.Set("destination_url", destination_url.spec());
  chrome::ShowFeedbackPage(
      browser_, feedback::kFeedbackSourceAI,
      /*description_template=*/std::string(),
      /*description_placeholder_text=*/
      l10n_util::GetStringUTF8(IDS_HISTORY_EMBEDDINGS_FEEDBACK_PLACEHOLDER),
      /*category_tag=*/"genai_history",
      /*extra_diagnostics=*/std::string(),
      /*autofill_metadata=*/base::Value::Dict(), std::move(ai_metadata));
}

void ChromeOmniboxClient::OnAutocompleteAccept(
    const GURL& destination_url,
    TemplateURLRef::PostContent* post_content,
    WindowOpenDisposition disposition,
    ui::PageTransition transition,
    AutocompleteMatchType::Type match_type,
    base::TimeTicks match_selection_timestamp,
    bool destination_url_entered_without_scheme,
    bool destination_url_entered_with_http_scheme,
    const std::u16string& text,
    const AutocompleteMatch& match,
    const AutocompleteMatch& alternative_nav_match) {
  TRACE_EVENT("omnibox", "ChromeOmniboxClient::OnAutocompleteAccept", "text",
              text, "match", match, "alternative_nav_match",
              alternative_nav_match);

  std::string extra_headers;
  for (const auto& header : match.extra_headers) {
    base::StrAppend(&extra_headers,
                    {header.first, ": ", header.second, "\r\n"});
  }

  // Store the details necessary to open the omnibox match via browser commands.
  location_bar_->set_navigation_params(LocationBar::NavigationParams(
      destination_url, disposition, transition, match_selection_timestamp,
      destination_url_entered_without_scheme,
      destination_url_entered_with_http_scheme, extra_headers));

  if (browser_) {
    auto navigation = chrome::OpenCurrentURL(browser_);
    ChromeOmniboxNavigationObserver::Create(navigation.get(), profile_, text,
                                            match, alternative_nav_match);
    search_engines::MaybeShowSearchEngineResetNotification(browser_,
                                                           match_type);
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  extensions::MaybeShowExtensionControlledSearchNotification(
      location_bar_->GetWebContents(), match_type);

  if (AutocompleteMatch::IsSearchType(match_type)) {
    if (auto* telemetry_service =
            safe_browsing::ExtensionTelemetryService::Get(profile_)) {
      telemetry_service->OnOmniboxSearch(match);
    }
  }
#endif
}

void ChromeOmniboxClient::OnInputInProgress(bool in_progress) {
  location_bar_->UpdateWithoutTabRestore();
  content::WebContents* const web_contents = location_bar_->GetWebContents();
  if (web_contents) {
    auto* const helper =
        OmniboxTabHelper::FromWebContents(location_bar_->GetWebContents());
    CHECK(helper);
    helper->OnInputInProgress(in_progress);
  }
}

void ChromeOmniboxClient::OnPopupVisibilityChanged(bool popup_is_open) {
  content::WebContents* const web_contents = location_bar_->GetWebContents();
  if (web_contents) {
    auto* const helper =
        OmniboxTabHelper::FromWebContents(location_bar_->GetWebContents());
    CHECK(helper);
    helper->OnPopupVisibilityChanged(
        popup_is_open, GetPageClassification(/*is_prefetch=*/false));
  }
}

void ChromeOmniboxClient::OpenUrl(GURL gurl) {
  CHECK(browser_);
  NavigateParams params(browser_, gurl, ui::PAGE_TRANSITION_GENERATED);
  params.disposition = WindowOpenDisposition::CURRENT_TAB;
  Navigate(&params);
}

void ChromeOmniboxClient::OpenIphLink(GURL gurl) {
  ui::PageTransition transition = ui::PageTransitionFromInt(
      ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
  NavigateParams params(profile_, gurl, transition);
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  Navigate(&params);
}

bool ChromeOmniboxClient::IsHistoryEmbeddingsEnabled() const {
  return history_embeddings::IsHistoryEmbeddingsEnabledForProfile(profile_);
}

bool ChromeOmniboxClient::IsAimPopupEnabled() const {
  return omnibox::IsAimPopupEnabled(profile_);
}

std::optional<lens::proto::LensOverlaySuggestInputs>
ChromeOmniboxClient::GetLensOverlaySuggestInputs() const {
  if (LensSearchController* lens_search_controller =
          GetLensSearchController(location_bar_->GetWebContents())) {
    return lens_search_controller->lens_searchbox_controller()
        ->GetLensSuggestInputs();
  }
  return std::nullopt;
}

void ChromeOmniboxClient::MaybePrewarmForDefaultSearchEngine() {
  if (!features::kPrewarmZeroSuggestTrigger.Get()) {
    // TODO(https://crbug.com/423465927): Consider to add a TriggerPlace enum
    // argument for this method on adding another triggers, and gate triggers
    // per the enum.
    return;
  }

  auto* prerender_manager = PrerenderManager::GetOrCreateForWebContents(
      location_bar_->GetWebContents());
  CHECK(prerender_manager);
  prerender_manager->MaybeStartPrewarmSearchResult();
}

base::WeakPtr<OmniboxClient> ChromeOmniboxClient::AsWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

void ChromeOmniboxClient::DoPrerender(const AutocompleteMatch& match) {
  content::WebContents* web_contents = location_bar_->GetWebContents();

  // Don't prerender when DevTools is open in this tab.
  if (content::DevToolsAgentHost::IsDebuggerAttached(web_contents)) {
    return;
  }

  // TODO(crbug.com/40208255): Refactor relevant code to reuse common
  // code, and ensure metrics are correctly recorded.
  DCHECK(!AutocompleteMatch::IsSearchType(match.type));

  predictors::AutocompleteActionPredictorFactory::GetForProfile(profile_)
      ->StartPrerendering(match.destination_url, *web_contents);
}

void ChromeOmniboxClient::DoPreconnect(const AutocompleteMatch& match) {
  if (match.destination_url.SchemeIs(extensions::kExtensionScheme)) {
    return;
  }

  auto* loading_predictor =
      predictors::LoadingPredictorFactory::GetForProfile(profile_);
  if (loading_predictor) {
    bool is_preconnectable =
        predictors::AutocompleteActionPredictor::IsPreconnectable(match);
    loading_predictor->PrepareForPageLoad(
        /*initiator_origin=*/std::nullopt, match.destination_url,
        predictors::HintOrigin::OMNIBOX, is_preconnectable);
    base::UmaHistogramExactLinear(
        base::StrCat(
            {"Omnibox.LoadingPredictor.MatchType.",
             is_preconnectable ? "Preconnectable" : "NonPreconnectable"}),
        match.GetOmniboxEventResultType(),
        metrics::OmniboxEventProto::Suggestion::ResultType_MAX + 1);
  }
  // We could prefetch the alternate nav URL, if any, but because there
  // can be many of these as a user types an initial series of characters,
  // the OS DNS cache could suffer eviction problems for minimal gain.
}

// static
void ChromeOmniboxClient::OnSuccessfulNavigation(
    Profile* profile,
    const std::u16string& text,
    const AutocompleteMatch& match) {
  auto shortcuts_backend = ShortcutsBackendFactory::GetForProfile(profile);
  // Can be null in incognito.
  if (!shortcuts_backend) {
    return;
  }

  shortcuts_backend->AddOrUpdateShortcut(text, match);
}
