// Copyright 2012 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/browser_commands.h"

#include <memory>
#include <numeric>
#include <optional>
#include <utility>
#include <variant>
#include <vector>

#include "base/check.h"
#include "base/check_deref.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/i18n/rtl.h"
#include "base/memory/scoped_refptr.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/strings/escape.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
#include "chrome/browser/chained_back_navigation_tracker.h"
#include "chrome/browser/commerce/browser_utils.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/contextual_tasks/contextual_tasks_side_panel_coordinator.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/favicon/favicon_utils.h"
#include "chrome/browser/feedback/show_feedback_page.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/reading_list/reading_list_model_factory.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h"
#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/sessions/session_service_base.h"
#include "chrome/browser/sessions/session_service_factory.h"
#include "chrome/browser/sessions/session_service_lookup.h"
#include "chrome/browser/sessions/tab_restore_service_factory.h"
#include "chrome/browser/sharing_hub/sharing_hub_features.h"
#include "chrome/browser/tab_group_sync/tab_group_sync_service_factory.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/browser/ui/accelerator_utils.h"
#include "chrome/browser/ui/autofill/address_bubbles_controller.h"
#include "chrome/browser/ui/autofill/payments/filled_card_information_bubble_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/iban_bubble_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.h"
#include "chrome/browser/ui/bookmarks/bookmark_bar_controller.h"
#include "chrome/browser/ui/bookmarks/bookmark_stats.h"
#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/bookmarks/bookmark_utils_desktop.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_live_tab_context.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/find_bar/find_bar.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/intent_picker_tab_helper.h"
#include "chrome/browser/ui/lens/lens_search_controller.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
#include "chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble.h"
#include "chrome/browser/ui/sharing_hub/screenshot/screenshot_captured_bubble_controller.h"
#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h"
#include "chrome/browser/ui/startup/startup_tab.h"
#include "chrome/browser/ui/status_bubble.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/tab_dialogs.h"
#include "chrome/browser/ui/tabs/features.h"
#include "chrome/browser/ui/tabs/new_tab_grouping_user_data.h"
#include "chrome/browser/ui/tabs/organization/tab_organization_service.h"
#include "chrome/browser/ui/tabs/organization/tab_organization_service_factory.h"
#include "chrome/browser/ui/tabs/organization/tab_organization_session.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h"
#include "chrome/browser/ui/tabs/split_tab_metrics.h"
#include "chrome/browser/ui/tabs/split_tab_util.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_group_model.h"
#include "chrome/browser/ui/tabs/tab_strip_user_gesture_details.h"
#include "chrome/browser/ui/tabs/vertical_tab_strip_state_controller.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/user_education/browser_user_education_interface.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry_key.h"
#include "chrome/browser/ui/views/side_panel/side_panel_ui.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h"
#include "chrome/browser/ui/webui/commerce/product_specifications_disclosure_dialog.h"
#include "chrome/browser/ui/webui/tab_search/tab_search.mojom.h"
#include "chrome/browser/upgrade_detector/upgrade_detector.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/content_restriction.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/bookmarks/common/bookmark_pref_names.h"
#include "components/browsing_data/content/browsing_data_helper.h"
#include "components/commerce/core/commerce_utils.h"
#include "components/commerce/core/mojom/product_specifications.mojom.h"
#include "components/commerce/core/pref_names.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/cookie_settings_base.h"
#include "components/embedder_support/user_agent_utils.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "components/feature_engagement/public/feature_constants.h"
#include "components/find_in_page/find_tab_helper.h"
#include "components/find_in_page/find_types.h"
#include "components/google/core/common/google_util.h"
#include "components/language_detection/core/constants.h"
#include "components/lens/buildflags.h"
#include "components/lens/lens_features.h"
#include "components/lens/lens_overlay_invocation_source.h"
#include "components/media_router/browser/media_router_dialog_controller.h"  // nogncheck
#include "components/media_router/browser/media_router_metrics.h"
#include "components/omnibox/browser/omnibox_prefs.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/reading_list/core/reading_list_entry.h"
#include "components/reading_list/core/reading_list_model.h"
#include "components/reading_list/core/reading_list_pref_names.h"
#include "components/saved_tab_groups/public/tab_group_sync_service.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/sessions/core/live_tab_context.h"
#include "components/sessions/core/tab_restore_service.h"
#include "components/tab_groups/tab_group_id.h"
#include "components/tab_groups/tab_group_visual_data.h"
#include "components/tabs/public/split_tab_data.h"
#include "components/tabs/public/split_tab_visual_data.h"
#include "components/tabs/public/tab_collection.h"
#include "components/tabs/public/tab_group.h"
#include "components/tabs/public/tab_group_tab_collection.h"
#include "components/tabs/public/tab_interface.h"
#include "components/translate/core/browser/language_state.h"
#include "components/translate/core/browser/translate_manager.h"
#include "components/user_education/common/feature_promo/feature_promo_controller.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "components/webapps/common/web_app_id.h"
#include "components/zoom/page_zoom.h"
#include "components/zoom/zoom_controller.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "pdf/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "rlz/buildflags/buildflags.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 "ui/base/clipboard/clipboard_buffer.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/models/list_selection_model.h"
#include "ui/base/window_open_disposition.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "url/gurl.h"
#include "url/url_constants.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/ui/extensions/app_launch_params.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h"
#include "chrome/common/extensions/extension_metrics.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#endif

#if BUILDFLAG(ENABLE_PDF)
#include "chrome/browser/pdf/pdf_extension_util.h"
#include "pdf/pdf_features.h"
#endif

#if BUILDFLAG(ENABLE_PRINTING)
#include "chrome/browser/printing/print_view_manager_common.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
#endif  // BUILDFLAG(ENABLE_PRINTING)

#if BUILDFLAG(ENABLE_RLZ)
#include "components/rlz/rlz_tracker.h"  // nogncheck
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/chromeos/printing/print_preview/print_view_manager_common.h"
#endif

#if !BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/apps/link_capturing/enable_link_capturing_infobar_delegate.h"
#endif

#if BUILDFLAG(IS_MAC)
#include "chrome/browser/web_applications/extensions/launch.h"
#endif

#if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
#include "chrome/browser/lens/region_search/lens_region_search_controller.h"
#include "chrome/browser/lens/region_search/lens_region_search_helper.h"
#include "components/lens/lens_features.h"
#endif

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ui/toasts/api/toast_id.h"
#include "chrome/browser/ui/toasts/toast_controller.h"
#include "chrome/browser/ui/toasts/toast_features.h"
#endif

namespace {

const char kOsOverrideForTabletSite[] = "Linux; Android 9; Chrome tablet";
const char kChPlatformOverrideForTabletSite[] = "Android";

// Creates a new tabbed browser window, with the same size, type and profile as
// |original_browser|'s window, inserts |contents| into it, and shows it.
void CreateAndShowNewWindowWithContents(
    std::unique_ptr<content::WebContents> contents,
    const Browser* original_browser) {
  Browser* new_browser = nullptr;
  DCHECK(!original_browser->is_type_app_popup());
  if (original_browser->is_type_app()) {
    new_browser = Browser::Create(Browser::CreateParams::CreateForApp(
        original_browser->app_name(), original_browser->is_trusted_source(),
        gfx::Rect(), original_browser->profile(), true));
  } else {
    new_browser = Browser::Create(Browser::CreateParams(
        original_browser->type(), original_browser->profile(), true));
  }
  // Preserve the size of the original window. The new window has already
  // been given an offset by the OS, so we shouldn't copy the old bounds.
  BrowserWindow* new_window = new_browser->window();
  new_window->SetBounds(
      gfx::Rect(new_window->GetRestoredBounds().origin(),
                original_browser->window()->GetRestoredBounds().size()));

  // We need to show the browser now.  Otherwise ContainerWin assumes the
  // WebContents is invisible and won't size it.
  new_browser->window()->Show();

  // The page transition below is only for the purpose of inserting the tab.
  new_browser->tab_strip_model()->AddWebContents(std::move(contents), -1,
                                                 ui::PAGE_TRANSITION_LINK,
                                                 AddTabTypes::ADD_ACTIVE);
}

bool GetTabURLAndTitleToSave(content::WebContents* web_contents,
                             GURL* url,
                             std::u16string* title) {
  // |web_contents| can be nullptr if the last tab in the browser was closed
  // but the browser wasn't closed yet. https://crbug.com/799668
  if (!web_contents) {
    return false;
  }
  return chrome::GetURLAndTitleToBookmark(web_contents, url, title);
}

ReadingListModel* GetReadingListModel(Browser* browser) {
  ReadingListModel* model =
      ReadingListModelFactory::GetForBrowserContext(browser->profile());
  if (!model || !model->loaded()) {
    return nullptr;  // Ignore requests until model has loaded.
  }
  return model;
}

bool CanMoveWebContentsToReadLater(Browser* browser,
                                   content::WebContents* web_contents,
                                   ReadingListModel* model,
                                   GURL* url,
                                   std::u16string* title) {
  return model && GetTabURLAndTitleToSave(web_contents, url, title) &&
         model->IsUrlSupported(*url) && !browser->profile()->IsGuestSession();
}

bool BookmarkCurrentTabHelper(Browser* browser,
                              bookmarks::BookmarkModel* model,
                              GURL* url,
                              std::u16string* title) {
  if (!model || !model->loaded()) {
    return false;  // Ignore requests until bookmarks are loaded.
  }

  content::WebContents* const web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  // |web_contents| can be nullptr if the last tab in the browser was closed
  // but the browser wasn't closed yet. https://crbug.com/799668
  if (!web_contents) {
    return false;
  }
  if (!chrome::GetURLAndTitleToBookmark(web_contents, url, title)) {
    return false;
  }
  bool is_bookmarked_by_any = model->IsBookmarked(*url);
  if (!is_bookmarked_by_any &&
      web_contents->GetBrowserContext()->IsOffTheRecord()) {
    // If we're incognito the favicon may not have been saved. Save it now
    // so that bookmarks have an icon for the page.
    favicon::SaveFaviconEvenIfInIncognito(web_contents);
  }
  return true;
}

content::WebContents* DuplicateTabAt(Browser* browser,
                                     int index,
                                     int dst_index) {
  content::WebContents* contents =
      browser->tab_strip_model()->GetWebContentsAt(index);
  CHECK(contents);
  std::unique_ptr<content::WebContents> contents_dupe = contents->Clone();
  content::WebContents* raw_contents_dupe = contents_dupe.get();

  bool pinned = false;
  if (browser->CanSupportWindowFeature(
          Browser::WindowFeature::kFeatureTabStrip)) {
    // If this is a tabbed browser, just create a duplicate tab inside the same
    // window next to the tab being duplicated.
    TabStripModel* tab_strip_model = browser->tab_strip_model();
    pinned = tab_strip_model->IsTabPinned(index);
    int add_types = AddTabTypes::ADD_ACTIVE | AddTabTypes::ADD_INHERIT_OPENER |
                    (pinned ? AddTabTypes::ADD_PINNED : 0);
    const auto old_group = tab_strip_model->GetTabGroupForTab(index);
    tab_strip_model->InsertWebContentsAt(dst_index, std::move(contents_dupe),
                                         add_types, old_group);
  } else {
    CreateAndShowNewWindowWithContents(std::move(contents_dupe), browser);
  }

  SessionServiceBase* session_service =
      GetAppropriateSessionServiceIfExisting(browser);
  if (session_service) {
    session_service->TabRestored(raw_contents_dupe, pinned);
  }
  return raw_contents_dupe;
}

void RecordTabCloseCount(int count) {
  base::UmaHistogramCounts100("TabStrip.Tab.HotkeyClosedCount", count);
}

void CloseSelectedTabAndRecordTabCountMetric(BrowserWindowInterface* browser) {
  const int selected_tabs_count =
      browser->GetTabStripModel()->selection_model().size();
  RecordTabCloseCount(selected_tabs_count);

  browser->GetTabStripModel()->CloseSelectedTabs();
}

void MoveGroupToWindowImpl(Browser* source,
                           Browser* target,
                           tab_groups::TabGroupId group) {
  CHECK(source->tab_strip_model()->group_model()->ContainsTabGroup(group));

  tab_groups::TabGroupSyncService* tab_group_service =
      tab_groups::TabGroupSyncServiceFactory::GetForProfile(source->profile());

  std::unique_ptr<tab_groups::ScopedLocalObservationPauser> observation_pauser;
  if (tab_group_service && tab_group_service->GetGroup(group)) {
    observation_pauser = tab_group_service->CreateScopedLocalObserverPauser();
  }

  std::unique_ptr<DetachedTabCollection> detached_group =
      source->tab_strip_model()->DetachTabGroupForInsertion(group);
  target->tab_strip_model()->InsertDetachedTabGroupAt(std::move(detached_group),
                                                      0);

  target->window()->Show();
}

void MoveTabsToWindowImpl(Browser* source,
                          Browser* target,
                          const std::vector<int>& tab_indices) {
  if (tab_indices.empty()) {
    return;
  }

  TabStripModel* source_model = source->tab_strip_model();
  TabStripModel* target_model = target->tab_strip_model();

  // Store the active tab from the source tab strip since this will change as
  // tabs are detached. If the active tab from `source_model` isn't moving,
  // default to activating the first tab being moved.
  const tabs::TabInterface* active_tab =
      std::find(tab_indices.begin(), tab_indices.end(),
                source_model->active_index()) != tab_indices.end()
          ? source_model->GetActiveTab()
          : source_model->GetTabAtIndex(tab_indices[0]);

  for (auto& tab_or_collection :
       source_model->DetachTabsAndCollectionsForInsertion(tab_indices)) {
    if (auto tab =
            std::get_if<std::unique_ptr<DetachedTab>>(&tab_or_collection)) {
      bool active = active_tab == tab->get()->tab.get();
      bool pinned = tab->get()->was_pinned_at_time_of_removal;
      int add_types = (active ? AddTabTypes::ADD_ACTIVE : 0) |
                      (pinned ? AddTabTypes::ADD_PINNED : 0);
      target_model->InsertDetachedTabAt(target_model->count(),
                                        std::move(tab->get()->tab), add_types);
    } else if (auto collection =
                   std::get_if<std::unique_ptr<DetachedTabCollection>>(
                       &tab_or_collection)) {
      if (std::holds_alternative<std::unique_ptr<tabs::TabGroupTabCollection>>(
              collection->get()->collection_)) {
        target_model->InsertDetachedTabGroupAt(std::move(*collection),
                                               target_model->count());
      } else {
        bool pinned = collection->get()->pinned_;
        target_model->InsertDetachedSplitTabAt(
            std::move(*collection),
            pinned ? target_model->IndexOfFirstNonPinnedTab()
                   : target_model->count(),
            pinned);
      }
    }
  }
  target->window()->Show();
}

}  // namespace

using base::UserMetricsAction;
using bookmarks::BookmarkModel;
using content::NavigationController;
using content::NavigationEntry;
using content::OpenURLParams;
using content::Referrer;
using content::WebContents;

namespace chrome {
namespace {

#if BUILDFLAG(ENABLE_EXTENSIONS)
const extensions::Extension* GetExtensionForBrowser(
    BrowserWindowInterface* browser) {
  return extensions::ExtensionRegistry::Get(browser->GetProfile())
      ->GetExtensionById(web_app::GetAppIdFromApplicationName(
                             browser->GetBrowserForMigrationOnly()->app_name()),
                         extensions::ExtensionRegistry::EVERYTHING);
}
#endif

// Based on |disposition|, creates a new tab as necessary, and returns the
// appropriate tab to navigate.  If that tab is the |current_tab|, reverts the
// location bar contents, since all browser-UI-triggered navigations should
// revert any omnibox edits in the |current_tab|.
WebContents* GetTabAndRevertIfNecessaryHelper(Browser* browser,
                                              WindowOpenDisposition disposition,
                                              WebContents* current_tab) {
  switch (disposition) {
    case WindowOpenDisposition::NEW_FOREGROUND_TAB:
    case WindowOpenDisposition::NEW_BACKGROUND_TAB: {
      std::unique_ptr<WebContents> new_tab = current_tab->Clone();
      WebContents* raw_new_tab = new_tab.get();
      if (disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB) {
        new_tab->WasHidden();
      }
      const int index =
          browser->tab_strip_model()->GetIndexOfWebContents(current_tab);
      const auto group = browser->tab_strip_model()->GetTabGroupForTab(index);
      browser->tab_strip_model()->AddWebContents(
          std::move(new_tab), -1, ui::PAGE_TRANSITION_LINK,
          (disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB)
              ? AddTabTypes::ADD_ACTIVE
              : AddTabTypes::ADD_NONE,
          group);
      return raw_new_tab;
    }
    case WindowOpenDisposition::NEW_WINDOW: {
      std::unique_ptr<WebContents> new_tab = current_tab->Clone();
      WebContents* raw_new_tab = new_tab.get();
      Browser* new_browser =
          Browser::Create(Browser::CreateParams(browser->profile(), true));
      new_browser->tab_strip_model()->AddWebContents(std::move(new_tab), -1,
                                                     ui::PAGE_TRANSITION_LINK,
                                                     AddTabTypes::ADD_ACTIVE);
      new_browser->window()->Show();
      return raw_new_tab;
    }
    default:
      browser->window()->GetLocationBar()->Revert();
      return current_tab;
  }
}

// Like the above, but auto-computes the current tab
WebContents* GetTabAndRevertIfNecessary(Browser* browser,
                                        WindowOpenDisposition disposition) {
  WebContents* activate_tab =
      browser->tab_strip_model()->GetActiveWebContents();
  return GetTabAndRevertIfNecessaryHelper(browser, disposition, activate_tab);
}

void RecordReloadWithCookieBlocking(BrowserWindowInterface* browser,
                                    WebContents* web_contents) {
  // Figure out if 3P cookies are blocked for this page.
  scoped_refptr<const content_settings::CookieSettings> cookie_settings =
      CookieSettingsFactory::GetForProfile(browser->GetProfile());

  // For this metric, we define "cookies blocked in settings" based on the
  // global opt-in to third-party cookie blocking as well as no overriding
  // content setting on the top-level site.
  bool cookies_blocked_in_settings =
      cookie_settings->ShouldBlockThirdPartyCookies() &&
      !cookie_settings->IsThirdPartyAccessAllowed(
          web_contents->GetLastCommittedURL(), nullptr);

  // Also measure if 3P cookies were actually blocked on the site.
  content_settings::PageSpecificContentSettings* pscs =
      content_settings::PageSpecificContentSettings::GetForFrame(
          web_contents->GetPrimaryMainFrame());
  bool cookies_blocked =
      pscs && pscs->blocked_browsing_data_model()->size() > 0U;

  ukm::SourceId source_id =
      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();

  ukm::builders::ThirdPartyCookies_BreakageIndicator_UserReload(source_id)
      .SetTPCBlocked(cookies_blocked)
      .SetTPCBlockedInSettings(cookies_blocked_in_settings)
      .Record(ukm::UkmRecorder::Get());
}

void ReloadInternal(BrowserWindowInterface* browser,
                    WindowOpenDisposition disposition,
                    bool bypass_cache) {
  TabStripModel* const tab_strip_model = browser->GetTabStripModel();
  tabs::TabInterface* const active_tab = tab_strip_model->GetActiveTab();
  WebContents* const active_contents = tab_strip_model->GetActiveWebContents();

  std::vector<WebContents*> tabs_to_reload;

  // When using split view, both tabs composing the split view are considered
  // selected by the `selection_model` and `selection_model().size()` returns 2;
  // even though visually, both tabs are represented by a single UI tab in the
  // tab strip. To detect whether the user has selected multiple UI tabs,
  // compare the number of model selected tabs wither either 2 or 1 depending on
  // whether the active tab is split.
  bool multiple_ui_tabs_selected =
      active_tab && tab_strip_model->selection_model().size() >
                        (active_tab->IsSplit() ? 2 : 1);

  if (base::FeatureList::IsEnabled(features::kReloadSelectionModel) &&
      !multiple_ui_tabs_selected) {
    tabs_to_reload.push_back(active_contents);
  } else {
    // Reloading a tab may change the selection (see crbug.com/339061099), so
    // take
    // a defensive copy into a more stable form before we begin. We take
    // WebContents* so we can follow the tabs as they shift within the same
    // tabstrip (e.g. if `disposition` is NEW_BACKGROUND_TAB).
    for (const int selected_index :
         tab_strip_model->selection_model().selected_indices()) {
      tabs_to_reload.push_back(
          tab_strip_model->GetWebContentsAt(selected_index));
    }
  }

  base::UmaHistogramCounts100("TabStrip.Tab.ReloadCount",
                              tabs_to_reload.size());

  for (WebContents* const tab : tabs_to_reload) {
    // Skip this tab if it is no longer part of this tabstrip. N.B. we do this
    // instead of using WeakPtr<WebContents> because we do not want to reload
    // tabs that move to another browser.
    if (tab_strip_model->GetIndexOfWebContents(tab) == TabStripModel::kNoTab) {
      continue;
    }

    WebContents* const new_tab = GetTabAndRevertIfNecessaryHelper(
        browser->GetBrowserForMigrationOnly(), disposition, tab);

    // If the `tab` is the activated page, give the focus to it, as this is
    // caused by a user action
    if (tab == active_contents && !new_tab->FocusLocationBarByDefault()) {
      new_tab->Focus();
    }

    // User reloads is a possible breakage indicator from blocking 3P cookies.
    RecordReloadWithCookieBlocking(browser, tab);

    DevToolsWindow* const devtools =
        DevToolsWindow::GetInstanceForInspectedWebContents(new_tab);
    constexpr content::ReloadType kBypassingType =
        content::ReloadType::BYPASSING_CACHE;
    constexpr content::ReloadType kNormalType = content::ReloadType::NORMAL;
    if (!devtools || !devtools->ReloadInspectedWebContents(bypass_cache)) {
      new_tab->GetController().Reload(
          bypass_cache ? kBypassingType : kNormalType, true);
    }
  }
}

bool IsShowingWebContentsModalDialog(BrowserWindowInterface* bwi) {
  WebContents* const web_contents =
      bwi->GetTabStripModel()->GetActiveWebContents();
  if (!web_contents) {
    return false;
  }

  // TODO(gbillock): This is currently called in production by the CanPrint
  // method, and may be too restrictive if we allow print preview to overlap.
  // Re-assess how to queue print preview after we know more about popup
  // management policy.
  const web_modal::WebContentsModalDialogManager* manager =
      web_modal::WebContentsModalDialogManager::FromWebContents(web_contents);
  return manager && manager->IsDialogActive();
}

#if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
bool PrintPreviewShowing(const Browser* browser) {
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
  WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
  auto* controller = printing::PrintPreviewDialogController::GetInstance();
  CHECK(controller);
  return controller->GetPrintPreviewForContents(contents) ||
         controller->is_creating_print_preview_dialog();
#else
  return false;
#endif
}
#endif  // BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)

}  // namespace

bool IsCommandEnabled(Browser* browser, int command) {
  return browser->command_controller()->IsCommandEnabled(command);
}

bool SupportsCommand(Browser* browser, int command) {
  return browser->command_controller()->SupportsCommand(command);
}

bool ExecuteCommand(BrowserWindowInterface* bwi,
                    int command,
                    base::TimeTicks time_stamp) {
  return bwi->GetFeatures().browser_command_controller()->ExecuteCommand(
      command, time_stamp);
}

bool ExecuteCommandWithDisposition(Browser* browser,
                                   int command,
                                   WindowOpenDisposition disposition) {
  return browser->command_controller()->ExecuteCommandWithDisposition(
      command, disposition);
}

void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
  browser->command_controller()->UpdateCommandEnabled(command, enabled);
}

void AddCommandObserver(Browser* browser,
                        int command,
                        CommandObserver* observer) {
  browser->command_controller()->AddCommandObserver(command, observer);
}

void RemoveCommandObserver(Browser* browser,
                           int command,
                           CommandObserver* observer) {
  browser->command_controller()->RemoveCommandObserver(command, observer);
}

int GetContentRestrictions(const BrowserWindowInterface* bwi) {
  int content_restrictions = 0;
  WebContents* const current_tab =
      bwi->GetTabStripModel()->GetActiveWebContents();
  if (current_tab) {
    CoreTabHelper* core_tab_helper =
        CoreTabHelper::FromWebContents(current_tab);
    content_restrictions = core_tab_helper->content_restrictions();
    NavigationEntry* last_committed_entry =
        current_tab->GetController().GetLastCommittedEntry();
    if (!content::IsSavableURL(last_committed_entry->GetURL())) {
      content_restrictions |= CONTENT_RESTRICTION_SAVE;
    }
  }
  return content_restrictions;
}

void NewEmptyWindow(Profile* profile, bool should_trigger_session_restore) {
  bool off_the_record = profile->IsOffTheRecord();
  PrefService* prefs = profile->GetPrefs();
  if (off_the_record) {
    if (IncognitoModePrefs::GetAvailability(prefs) ==
        policy::IncognitoModeAvailability::kDisabled) {
      off_the_record = false;
    }
  } else if (profile->IsGuestSession() ||
             IncognitoModePrefs::ShouldOpenSubsequentBrowsersInIncognito(
                 *base::CommandLine::ForCurrentProcess(), prefs)) {
    off_the_record = true;
  }

  if (off_the_record) {
    // This metric counts the Incognito and Off-The-Record Guest profiles
    // together.
    base::RecordAction(UserMetricsAction("NewIncognitoWindow"));
    if (profile->IsGuestSession()) {
      base::RecordAction(UserMetricsAction("NewGuestWindow"));
    } else {
      base::RecordAction(UserMetricsAction("NewIncognitoWindow2"));
    }
    OpenEmptyWindow(profile->GetPrimaryOTRProfile(/*create_if_needed=*/true),
                    should_trigger_session_restore);
  } else if (!should_trigger_session_restore) {
    base::RecordAction(UserMetricsAction("NewWindow"));
    OpenEmptyWindow(profile->GetOriginalProfile(),
                    /*should_trigger_session_restore=*/false);
  } else {
    base::RecordAction(UserMetricsAction("NewWindow"));
    SessionService* session_service =
        SessionServiceFactory::GetForProfileForSessionRestore(
            profile->GetOriginalProfile());
    if (!session_service ||
        !session_service->RestoreIfNecessary(StartupTabs(),
                                             /* restore_apps */ false)) {
      OpenEmptyWindow(profile->GetOriginalProfile());
    }
  }
}

Browser* OpenEmptyWindow(Profile* profile,
                         bool should_trigger_session_restore) {
  if (Browser::GetCreationStatusForProfile(profile) !=
      Browser::CreationStatus::kOk) {
    return nullptr;
  }

  // Don't create a new window when the profile is shutting down.
  if (profile->ShutdownStarted()) {
    return nullptr;
  }

  Browser::CreateParams params =
      Browser::CreateParams(Browser::TYPE_NORMAL, profile, true);
  params.should_trigger_session_restore = should_trigger_session_restore;
  Browser* browser = Browser::Create(params);

  // Startup tabs could be created during browser creation. Add an empty tab
  // only if no tabs are created.
  if (browser->tab_strip_model()->empty()) {
    AddTabAt(browser, GURL(), -1, true);
  }

  browser->window()->Show();
  return browser;
}

void OpenWindowWithRestoredTabs(Profile* profile) {
  sessions::TabRestoreService* service =
      TabRestoreServiceFactory::GetForProfile(profile);
  if (service) {
    service->RestoreMostRecentEntry(nullptr);
  }
}

void OpenURLOffTheRecord(Profile* profile, const GURL& url) {
  ScopedTabbedBrowserDisplayer displayer(
      profile->GetPrimaryOTRProfile(/*create_if_needed=*/true));
  AddSelectedTabWithURL(displayer.browser(), url, ui::PAGE_TRANSITION_LINK);
}

bool CanGoBack(const Browser* browser) {
  return browser->tab_strip_model()
      ->GetActiveWebContents()
      ->GetController()
      .CanGoBack();
}

bool CanGoBack(content::WebContents* web_contents) {
  return web_contents->GetController().CanGoBack();
}

bool ShouldEnableBackButton(const Browser* browser) {
  return browser->tab_strip_model()
      ->GetActiveWebContents()
      ->GetController()
      .ShouldEnableBackButton();
}

enum class BackNavigationMenuIPHTrigger : int {
  kUserPerformsManyBackNavigation = 0,
  kUserPerformsChainedBackNavigation,
  kUserPerformsChainedBackNavigationWithBackButton
};

const char kBackNavigationMenuIPHExperimentParamName[] = "x_experiment";

void MaybeShowFeatureBackNavigationMenuPromo(Browser* browser,
                                             WebContents* web_contents) {
  if (!base::FeatureList::IsEnabled(
          feature_engagement::kIPHBackNavigationMenuFeature)) {
    return;
  }

  bool should_show_feature_promo;
  const ChainedBackNavigationTracker* tracker =
      ChainedBackNavigationTracker::FromWebContents(web_contents);
  CHECK(tracker);
  switch (static_cast<BackNavigationMenuIPHTrigger>(
      base::GetFieldTrialParamByFeatureAsInt(
          feature_engagement::kIPHBackNavigationMenuFeature,
          kBackNavigationMenuIPHExperimentParamName, 0))) {
    case BackNavigationMenuIPHTrigger::kUserPerformsChainedBackNavigation:
      should_show_feature_promo =
          tracker->IsChainedBackNavigationRecentlyPerformed();
      break;

    case BackNavigationMenuIPHTrigger::
        kUserPerformsChainedBackNavigationWithBackButton:
      should_show_feature_promo =
          tracker->IsBackButtonChainedBackNavigationRecentlyPerformed();
      break;
    default:
      should_show_feature_promo = true;
      break;
  }

  if (should_show_feature_promo) {
    BrowserUserEducationInterface::From(browser)->MaybeShowFeaturePromo(
        feature_engagement::kIPHBackNavigationMenuFeature);
  }
}

void GoBack(Browser* browser, WindowOpenDisposition disposition) {
  base::RecordAction(UserMetricsAction("Back"));

  if (CanGoBack(browser)) {
    WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
    new_tab->GetController().GoBack();
    MaybeShowFeatureBackNavigationMenuPromo(browser, new_tab);
  }
}

void GoBack(content::WebContents* web_contents) {
  base::RecordAction(UserMetricsAction("Back"));

  if (CanGoBack(web_contents)) {
    web_contents->GetController().GoBack();
    Browser* browser = chrome::FindBrowserWithTab(web_contents);
    if (browser) {
      MaybeShowFeatureBackNavigationMenuPromo(browser, web_contents);
    }
  }
}

bool CanGoForward(const Browser* browser) {
  return browser->tab_strip_model()
      ->GetActiveWebContents()
      ->GetController()
      .CanGoForward();
}

bool CanGoForward(content::WebContents* web_contents) {
  return web_contents->GetController().CanGoForward();
}

bool ShouldEnableForwardButton(const Browser* browser) {
  return browser->tab_strip_model()
      ->GetActiveWebContents()
      ->GetController()
      .ShouldEnableForwardButton();
}

void GoForward(Browser* browser, WindowOpenDisposition disposition) {
  base::RecordAction(UserMetricsAction("Forward"));
  if (CanGoForward(browser)) {
    GetTabAndRevertIfNecessary(browser, disposition)
        ->GetController()
        .GoForward();
  }
}

void GoForward(content::WebContents* web_contents) {
  base::RecordAction(UserMetricsAction("Forward"));
  if (CanGoForward(web_contents)) {
    web_contents->GetController().GoForward();
  }
}

void NavigateToIndexWithDisposition(Browser* browser,
                                    int index,
                                    WindowOpenDisposition disposition) {
  NavigationController* controller =
      &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
  DCHECK_GE(index, 0);
  DCHECK_LT(index, controller->GetEntryCount());
  controller->GoToIndex(index);
}

void Reload(BrowserWindowInterface* browser,
            WindowOpenDisposition disposition) {
  base::RecordAction(UserMetricsAction("Reload"));
  ReloadInternal(browser, disposition, false);
}

void ReloadBypassingCache(Browser* browser, WindowOpenDisposition disposition) {
  base::RecordAction(UserMetricsAction("ReloadBypassingCache"));
  ReloadInternal(browser, disposition, true);
}

bool CanReload(const Browser* browser) {
  return browser && !browser->is_type_devtools() &&
         !browser->is_type_picture_in_picture();
}

void Home(Browser* browser, WindowOpenDisposition disposition) {
  base::RecordAction(UserMetricsAction("Home"));

  std::string extra_headers;
#if BUILDFLAG(ENABLE_RLZ)
  // If the home page is a Google home page, add the RLZ header to the request.
  PrefService* pref_service = browser->profile()->GetPrefs();
  if (pref_service) {
    if (google_util::IsGoogleHomePageUrl(
            GURL(pref_service->GetString(prefs::kHomePage)))) {
      extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader(
          rlz::RLZTracker::ChromeHomePage());
    }
  }
#endif  // BUILDFLAG(ENABLE_RLZ)

  GURL url = browser->profile()->GetHomePage();

#if BUILDFLAG(ENABLE_EXTENSIONS)
  // With bookmark apps enabled, hosted apps should return to their launch page
  // when the home button is pressed.
  if (browser->is_type_app() || browser->is_type_app_popup()) {
    const extensions::Extension* extension = GetExtensionForBrowser(browser);
    if (!extension) {
      return;
    }
    url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
  }

  if (disposition == WindowOpenDisposition::CURRENT_TAB ||
      disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB) {
    extensions::MaybeShowExtensionControlledHomeNotification(
        browser, browser->tab_strip_model()->GetActiveWebContents());
  }
#endif

  bool is_chrome_internal = url.SchemeIs(url::kAboutScheme) ||
                            url.SchemeIs(content::kChromeUIScheme) ||
                            url.SchemeIs(chrome::kChromeNativeScheme);
  base::UmaHistogramBoolean("Navigation.Home.IsChromeInternal",
                            is_chrome_internal);
  // Log a user action for the !is_chrome_internal case. This value is used as
  // part of a high-level guiding metric, which is being migrated to user
  // actions.
  if (!is_chrome_internal) {
    base::RecordAction(
        base::UserMetricsAction("Navigation.Home.NotChromeInternal"));
  }
  OpenURLParams params(
      url, Referrer(), disposition,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_BOOKMARK |
                                ui::PAGE_TRANSITION_HOME_PAGE),
      false);
  params.extra_headers = extra_headers;
  browser->OpenURL(params, /*navigation_handle_callback=*/{});
}

base::WeakPtr<content::NavigationHandle> OpenCurrentURL(Browser* browser) {
  base::RecordAction(UserMetricsAction("LoadURL"));
  // TODO(crbug.com/40820294): Eliminate extra checks once source of
  //  bad pointer dereference is identified. See also TODO comment below.
  CHECK(browser);
  BrowserWindow* window = browser->window();
  CHECK(window);
  LocationBar* location_bar = window->GetLocationBar();
  if (!location_bar) {
    return nullptr;
  }

  GURL url(location_bar->navigation_params().destination_url);
  TRACE_EVENT1("navigation", "chrome::OpenCurrentURL", "url", url);

  if (ShouldInterceptChromeURLNavigationInIncognito(browser, url)) {
    ProcessInterceptedChromeURLNavigationInIncognito(browser, url);
    return nullptr;
  }

  NavigateParams params(browser, url,
                        location_bar->navigation_params().transition);
  params.disposition = location_bar->navigation_params().disposition;
  // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
  // inherit the opener. In some cases the tabstrip will determine the group
  // should be inherited, in which case the group is inherited instead of the
  // opener.
  params.tabstrip_add_types =
      AddTabTypes::ADD_FORCE_INDEX | AddTabTypes::ADD_INHERIT_OPENER;
  params.input_start =
      location_bar->navigation_params().match_selection_timestamp;
  params.is_using_https_as_default_scheme =
      location_bar->navigation_params().url_typed_without_scheme;
  params.url_typed_with_http_scheme =
      location_bar->navigation_params().url_typed_with_http_scheme;
  params.extra_headers = location_bar->navigation_params().extra_headers;
  auto result = Navigate(&params);

#if BUILDFLAG(ENABLE_EXTENSIONS)
  DCHECK(extensions::ExtensionSystem::Get(browser->profile())
             ->extension_service());
  // TODO(crbug.com/40820294): Eliminate extra checks once source of
  //  bad pointer dereference is identified. See also TODO comment above.
  extensions::ExtensionRegistry* extension_registry =
      extensions::ExtensionRegistry::Get(browser->profile());
  CHECK(extension_registry);
  const extensions::Extension* extension =
      extension_registry->enabled_extensions().GetAppByURL(url);
  if (extension) {
    extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
                                    extension->GetType());
  }
#endif
  return result;
}

void Stop(Browser* browser) {
  base::RecordAction(UserMetricsAction("Stop"));
  browser->tab_strip_model()->GetActiveWebContents()->Stop();
}

void NewWindow(BrowserWindowInterface* browser) {
  Profile* const profile = browser->GetProfile();
#if BUILDFLAG(IS_MAC)
  // Web apps should open a window to their launch page.
  if (auto* const app_browser_controller =
          web_app::AppBrowserController::From(browser)) {
    const webapps::AppId app_id = app_browser_controller->app_id();

    auto launch_container = apps::LaunchContainer::kLaunchContainerWindow;

    auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
    if (provider && provider->registrar_unsafe().GetAppEffectiveDisplayMode(
                        app_id) == blink::mojom::DisplayMode::kBrowser) {
      launch_container = apps::LaunchContainer::kLaunchContainerTab;
    }
    apps::AppLaunchParams params = apps::AppLaunchParams(
        app_id, launch_container, WindowOpenDisposition::NEW_WINDOW,
        apps::LaunchSource::kFromKeyboard);
    web_app::LaunchExtensionOrWebApp(profile, std::move(params),
                                     base::DoNothing());
    return;
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  // Hosted apps should open a window to their launch page.
  const extensions::Extension* extension = GetExtensionForBrowser(browser);
  if (extension && extension->is_hosted_app()) {
    const auto app_launch_params = CreateAppLaunchParamsUserContainer(
        profile, extension, WindowOpenDisposition::NEW_WINDOW,
        apps::LaunchSource::kFromKeyboard);
    OpenApplicationWindow(
        profile, app_launch_params,
        extensions::AppLaunchInfo::GetLaunchWebURL(extension));
    return;
  }
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)
#endif  // BUILDFLAG(IS_MAC)
  NewEmptyWindow(profile->GetOriginalProfile());
}

void NewIncognitoWindow(Profile* profile) {
  NewEmptyWindow(profile->GetPrimaryOTRProfile(/*create_if_needed=*/true));
}

void CloseWindow(BrowserWindowInterface* browser) {
  base::RecordAction(UserMetricsAction("CloseWindow"));
  browser->GetWindow()->Close();
}

content::WebContents& NewTab(Browser* browser, NewTabTypes context) {
  if (context != NewTabTypes::kNoUserAction) {
    base::RecordAction(base::UserMetricsAction("NewTab"));
  }

  UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", context,
                            NewTabTypes::kNewTabEnumCount);

  browser->profile()->SetUserData(
      NewTabGroupingUserData::kNewTabGroupingUserDataKey,
      std::make_unique<NewTabGroupingUserData>(
          browser->tab_strip_model()->GetActiveTabGroupId()));

  if (browser->SupportsWindowFeature(
          Browser::WindowFeature::kFeatureTabStrip)) {
    std::optional<tab_groups::TabGroupId> group_id = std::nullopt;

    if (features::IsNewTabAddsToActiveGroupEnabled()) {
      const int index = browser->tab_strip_model()->active_index();
      group_id = browser->tab_strip_model()->GetTabGroupForTab(index);
    }

    return *AddAndReturnTabAt(browser, GURL(), -1, true, group_id);
  }

  ScopedTabbedBrowserDisplayer displayer(browser->profile());
  Browser* b = displayer.browser();
  auto* contents = AddAndReturnTabAt(b, GURL(), -1, true);
  b->window()->Show();
  // The call to AddBlankTabAt above did not set the focus to the tab as its
  // window was not active, so we have to do it explicitly.
  // See http://crbug.com/6380.
  b->tab_strip_model()->GetActiveWebContents()->RestoreFocus();

  return *contents;
}

void NewTabToRight(Browser* browser) {
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      browser->tab_strip_model()->active_index(),
      TabStripModel::CommandNewTabToRight);
}

void CloseTab(BrowserWindowInterface* browser) {
  base::RecordAction(UserMetricsAction("CloseTab_Accelerator"));

  // If the selection model consists of only the indices of a single split tab,
  // decide if just the active tab in the split is closed instead of all tabs in
  // the split.
  const bool only_active_split_tab_selected =
      browser->GetTabStripModel()->IsActiveTabSplit() &&
      browser->GetTabStripModel()->selection_model().size() == 2;
  if (only_active_split_tab_selected &&
      base::FeatureList::IsEnabled(
          features::kCloseActiveTabInSplitViewViaHotkey)) {
    RecordTabCloseCount(1);

    content::WebContents* active_web_contents =
        browser->GetTabStripModel()->GetActiveWebContents();
    active_web_contents->Close();

    return;
  }

  ToastController* toast_controller = browser->GetFeatures().toast_controller();
  if (!toast_controller) {
    CloseSelectedTabAndRecordTabCountMetric(browser);
    return;
  }

  tabs::TabInterface* tab = browser->GetTabStripModel()->GetActiveTab();
  const bool single_pinned_tab_selected =
      tab->IsPinned() &&
      browser->GetTabStripModel()->selection_model().size() == 1;
  if (single_pinned_tab_selected &&
      toast_controller->GetCurrentToastId() != ToastId::kClosePinnedTab) {
    BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
    CHECK(browser_view);
    ui::Accelerator accelerator;
    CHECK(
        browser_view->GetAcceleratorForCommandId(IDC_CLOSE_TAB, &accelerator));

    ToastParams params(ToastId::kClosePinnedTab);
    params.body_string_replacement_params.emplace_back(
        accelerator.GetShortcutText());
    toast_controller->MaybeShowToast(std::move(params));
  } else {
    CloseSelectedTabAndRecordTabCountMetric(browser);
    if (single_pinned_tab_selected) {
      base::RecordAction(
          UserMetricsAction("Tab.PinnedTabToastClosedAfterConfirmation"));
    }
  }
}

bool CanZoomIn(content::WebContents* contents) {
  return contents && !contents->IsCrashed() &&
         zoom::ZoomController::FromWebContents(contents)->GetZoomPercent() !=
             contents->GetMaximumZoomPercent();
}

bool CanZoomOut(content::WebContents* contents) {
  return contents && !contents->IsCrashed() &&
         zoom::ZoomController::FromWebContents(contents)->GetZoomPercent() !=
             contents->GetMinimumZoomPercent();
}

bool CanResetZoom(content::WebContents* contents) {
  zoom::ZoomController* zoom_controller =
      zoom::ZoomController::FromWebContents(contents);
  return !zoom_controller->IsAtDefaultZoom() ||
         !zoom_controller->PageScaleFactorIsOne();
}

void SelectNextTab(Browser* browser,
                   TabStripUserGestureDetails gesture_detail) {
  base::RecordAction(UserMetricsAction("SelectNextTab"));
  browser->tab_strip_model()->SelectNextTab(gesture_detail);
}

void SelectPreviousTab(Browser* browser,
                       TabStripUserGestureDetails gesture_detail) {
  base::RecordAction(UserMetricsAction("SelectPrevTab"));
  browser->tab_strip_model()->SelectPreviousTab(gesture_detail);
}

void MoveTabNext(Browser* browser) {
  base::RecordAction(UserMetricsAction("MoveTabNext"));
  browser->tab_strip_model()->MoveTabNext();
}

void MoveTabPrevious(Browser* browser) {
  base::RecordAction(UserMetricsAction("MoveTabPrevious"));
  browser->tab_strip_model()->MoveTabPrevious();
}

void SelectNumberedTab(Browser* browser,
                       int index,
                       TabStripUserGestureDetails gesture_detail) {
  int visible_count = 0;
  for (int i = 0; i < browser->tab_strip_model()->count(); i++) {
    if (browser->tab_strip_model()->IsTabCollapsed(i)) {
      continue;
    }
    if (visible_count == index) {
      base::RecordAction(UserMetricsAction("SelectNumberedTab"));
      browser->tab_strip_model()->ActivateTabAt(i, gesture_detail);
      break;
    }
    visible_count += 1;
  }
}

void SelectLastTab(Browser* browser,
                   TabStripUserGestureDetails gesture_detail) {
  for (int i = browser->tab_strip_model()->count() - 1; i >= 0; i--) {
    if (!browser->tab_strip_model()->IsTabCollapsed(i)) {
      base::RecordAction(UserMetricsAction("SelectLastTab"));
      browser->tab_strip_model()->ActivateTabAt(i, gesture_detail);
      break;
    }
  }
}

void DuplicateTab(Browser* browser) {
  base::RecordAction(UserMetricsAction("Duplicate"));
  DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
}

bool CanDuplicateTab(const Browser* browser) {
  return CanDuplicateTabAt(browser, browser->tab_strip_model()->active_index());
}

bool CanDuplicateKeyboardFocusedTab(const Browser* browser) {
  if (!HasKeyboardFocusedTab(browser)) {
    return false;
  }
  return CanDuplicateTabAt(browser, *GetKeyboardFocusedTabIndex(browser));
}

bool CanMoveActiveTabToNewWindow(Browser* browser) {
  const ui::ListSelectionModel::SelectedIndices selection =
      browser->tab_strip_model()->selection_model().selected_indices();
  return CanMoveTabsToNewWindow(
      browser, std::vector<int>(selection.begin(), selection.end()));
}

void MoveActiveTabToNewWindow(Browser* browser) {
  const ui::ListSelectionModel::SelectedIndices selection =
      browser->tab_strip_model()->selection_model().selected_indices();
  MoveTabsToNewWindow(browser,
                      std::vector<int>(selection.begin(), selection.end()));
}

bool CanMoveTabsToNewWindow(Browser* browser,
                            const std::vector<int>& tab_indices) {
  if (browser->is_type_app()) {
    for (int index : tab_indices) {
      if (web_app::IsPinnedHomeTab(browser->tab_strip_model(), index)) {
        return false;
      }
    }
  }
  return browser->tab_strip_model()->count() >
         static_cast<int>(tab_indices.size());
}

void MoveGroupToNewWindow(Browser* browser, tab_groups::TabGroupId group) {
  Browser* new_browser;
  if (browser->is_type_app() && browser->app_controller()->has_tab_strip()) {
    new_browser = Browser::Create(Browser::CreateParams::CreateForApp(
        browser->app_name(), browser->is_trusted_source(), gfx::Rect(),
        browser->profile(), true));
    web_app::MaybeAddPinnedHomeTab(new_browser,
                                   new_browser->app_controller()->app_id());
  } else {
    new_browser =
        Browser::Create(Browser::CreateParams(browser->profile(), true));
  }

  MoveGroupToWindowImpl(browser, new_browser, group);
}

void MoveTabsToNewWindow(Browser* browser,
                         const std::vector<int>& tab_indices) {
  if (tab_indices.empty()) {
    return;
  }

  Browser* new_browser;
  if (browser->is_type_app() && browser->app_controller()->has_tab_strip()) {
    new_browser = Browser::Create(Browser::CreateParams::CreateForApp(
        browser->app_name(), browser->is_trusted_source(), gfx::Rect(),
        browser->profile(), true));
    web_app::MaybeAddPinnedHomeTab(new_browser,
                                   new_browser->app_controller()->app_id());
  } else {
    new_browser =
        Browser::Create(Browser::CreateParams(browser->profile(), true));
  }

  MoveTabsToWindowImpl(browser, new_browser, tab_indices);
}

bool CanCloseTabsToRight(const Browser* browser) {
  return browser->tab_strip_model()->IsContextMenuCommandEnabled(
      browser->tab_strip_model()->active_index(),
      TabStripModel::CommandCloseTabsToRight);
}

bool CanCloseOtherTabs(const Browser* browser) {
  return browser->tab_strip_model()->IsContextMenuCommandEnabled(
      browser->tab_strip_model()->active_index(),
      TabStripModel::CommandCloseOtherTabs);
}

WebContents* DuplicateTabAt(Browser* browser, int index) {
  return ::DuplicateTabAt(browser, index, index + 1);
}

void DuplicateSplit(Browser* browser, split_tabs::SplitTabId split) {
  CHECK(browser->CanSupportWindowFeature(
      Browser::WindowFeature::kFeatureTabStrip));

  TabStripModel* model = browser->tab_strip_model();
  split_tabs::SplitTabData* split_data = model->GetSplitData(split);
  gfx::Range split_indices_range = split_data->GetIndexRange();

  std::vector<int> duplicated_tab_indices;
  for (size_t split_index = split_indices_range.GetMin();
       split_index < split_indices_range.GetMax(); split_index++) {
    size_t dst_index = split_index + split_indices_range.length();
    ::DuplicateTabAt(browser, split_index, dst_index);
    duplicated_tab_indices.push_back(dst_index);
  }

  // Activate the tab that was last active in the old split, and then
  // create the new split with the same visual data.
  // TODO(418015278): Revisit if we should store last active tab in the visual
  // data, to make copying it easier.
  int active_index = split_tabs::GetIndexOfLastActiveTab(model, split) +
                     split_indices_range.length();
  model->ActivateTabAt(active_index);
  // AddToNewSplit always creates a split with the active index so remove it
  // from the passed in indices.
  duplicated_tab_indices.erase(std::find(duplicated_tab_indices.begin(),
                                         duplicated_tab_indices.end(),
                                         active_index));
  model->AddToNewSplit(duplicated_tab_indices,
                       split_tabs::SplitTabVisualData(
                           *(model->GetSplitData(split)->visual_data())),
                       split_tabs::SplitTabCreatedSource::kDuplicateSplit);
}

bool CanDuplicateTabAt(const Browser* browser, int index) {
  if (browser->is_type_picture_in_picture()) {
    return false;
  }
  WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
  return contents;
}

void MoveTabsToExistingWindow(Browser* source,
                              Browser* target,
                              const std::vector<int>& tab_indices) {
  MoveTabsToWindowImpl(source, target, tab_indices);
}

void MoveGroupToExistingWindow(Browser* source,
                               Browser* target,
                               tab_groups::TabGroupId group) {
  MoveGroupToWindowImpl(source, target, group);
}

void PinTab(Browser* browser) {
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      browser->tab_strip_model()->active_index(),
      TabStripModel::ContextMenuCommand::CommandTogglePinned);
}

void GroupTab(Browser* browser) {
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      browser->tab_strip_model()->active_index(),
      TabStripModel::ContextMenuCommand::CommandToggleGrouped);
}

void NewSplitTab(BrowserWindowInterface* browser,
                 split_tabs::SplitTabCreatedSource source) {
  TabStripModel* const tab_strip_model = browser->GetTabStripModel();
  const int active_index = tab_strip_model->active_index();
  // In Incognito mode, we can't show the regular Split View NTP so default to
  // the regular NTP which renders special content when in Incognito.
  const char* new_tab_url = browser->GetProfile()->IsIncognitoProfile()
                                ? chrome::kChromeUINewTabURL
                                : chrome::kChromeUISplitViewNewTabPageURL;
  tab_strip_model->delegate()->AddTabAt(
      GURL(new_tab_url), active_index + 1, true,
      tab_strip_model->GetTabGroupForTab(active_index),
      tab_strip_model->IsTabPinned(active_index));
  tab_strip_model->AddToNewSplit({active_index},
                                 split_tabs::SplitTabVisualData(), source);
}

void AddNewTabToGroup(Browser* browser) {
  if (!browser->tab_strip_model()->SupportsTabGroups()) {
    return;
  }

  int index = browser->tab_strip_model()->active_index();
  std::optional<tab_groups::TabGroupId> group_id =
      browser->tab_strip_model()->GetTabGroupForTab(index);
  if (!group_id) {
    return;
  }

  AddTabAt(browser, GURL(), -1, true, group_id);
}

void CreateNewTabGroup(Browser* browser) {
  NewTab(browser);
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      browser->tab_strip_model()->active_index(),
      TabStripModel::ContextMenuCommand::CommandAddToNewGroupFromMenuItem);
}

void CloseTabGroup(Browser* browser) {
  const int index = browser->tab_strip_model()->active_index();
  std::optional<tab_groups::TabGroupId> group_id =
      browser->tab_strip_model()->GetTabGroupForTab(index);
  if (!group_id) {
    return;
  }

  const int num_tabs_in_group = browser->tab_strip_model()
                                    ->group_model()
                                    ->GetTabGroup(group_id.value())
                                    ->tab_count();
  if (num_tabs_in_group == browser->tab_strip_model()->count()) {
    // If the group about to be closed has all of the tabs in the browser, add a
    // new tab outside the group to prevent the browser from closing.
    browser->tab_strip_model()->delegate()->AddTabAt(GURL(), -1, true);
  }

  browser->tab_strip_model()->CloseAllTabsInGroup(group_id.value());
}

void FocusNextTabGroup(Browser* browser) {
  TabStripModel* tab_strip_model = browser->tab_strip_model();
  if (!tab_strip_model->SupportsTabGroups()) {
    return;
  }

  int current_index = tab_strip_model->active_index();
  std::optional<tab_groups::TabGroupId> current_group_id =
      tab_strip_model->GetTabGroupForTab(current_index);

  // Find the next tab group and focus its first tab.
  int count = tab_strip_model->count();
  for (int i = 1; i < count; ++i) {
    int new_index = (current_index + i) % count;
    std::optional<tab_groups::TabGroupId> new_group_id =
        tab_strip_model->GetTabGroupForTab(new_index);
    if (new_group_id && new_group_id != current_group_id) {
      tab_strip_model->ActivateTabAt(
          new_index, TabStripUserGestureDetails(
                         TabStripUserGestureDetails::GestureType::kKeyboard));
      return;
    }
  }
}

void FocusPreviousTabGroup(Browser* browser) {
  TabStripModel* tab_strip_model = browser->tab_strip_model();
  if (!tab_strip_model->SupportsTabGroups()) {
    return;
  }

  int current_index = tab_strip_model->active_index();
  std::optional<tab_groups::TabGroupId> current_group_id =
      tab_strip_model->GetTabGroupForTab(current_index);

  // Find the next tab group and focus its first tab.
  int count = tab_strip_model->count();
  for (int i = 1; i < count; ++i) {
    int offset = count - i;
    int new_index = (current_index + offset) % count;
    std::optional<tab_groups::TabGroupId> new_group_id =
        tab_strip_model->GetTabGroupForTab(new_index);
    if (new_group_id && new_group_id != current_group_id) {
      tabs::TabInterface* first_tab_of_group =
          tab_strip_model->group_model()
              ->GetTabGroup(new_group_id.value())
              ->GetFirstTab();
      CHECK(first_tab_of_group);
      tab_strip_model->ActivateTabAt(
          tab_strip_model->GetIndexOfTab(first_tab_of_group),
          TabStripUserGestureDetails(
              TabStripUserGestureDetails::GestureType::kKeyboard));
      return;
    }
  }
}

bool GroupAllUngroupedTabs(Browser* browser) {
  TabStripModel* tab_strip_model = browser->tab_strip_model();
  if (!tab_strip_model->SupportsTabGroups()) {
    return false;
  }

  int i = 0;
  std::vector<int> indices;
  for (const tabs::TabInterface* t : *tab_strip_model) {
    if (!t->GetGroup() && !t->IsPinned()) {
      indices.push_back(i);
    }
    ++i;
  }
  if (indices.size() == 0) {
    return false;
  }

  tab_groups::TabGroupId group = tab_strip_model->AddToNewGroup(indices);
  tab_strip_model->OpenTabGroupEditor(group);
  return true;
}

void AddNewTabToRecentGroup(Browser* browser) {
  if (!features::IsTabGroupMenuMoreEntryPointsEnabled()) {
    return;
  }

  TabStripModel* tab_strip_model = browser->tab_strip_model();

  if (!tab_strip_model->SupportsTabGroups()) {
    return;
  }

  std::optional<tab_groups::TabGroupId> group_id = std::nullopt;

  // Add the new tab to the most recently active group.
  TabGroupModel* tab_group_model = tab_strip_model->group_model();
  CHECK(tab_group_model);
  group_id = tab_group_model->GetMostRecentTabGroupId();

  if (!group_id) {
    return;
  }

  AddTabAt(browser, GURL(), -1, true, group_id);
}

void MuteSite(Browser* browser) {
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      browser->tab_strip_model()->active_index(),
      TabStripModel::ContextMenuCommand::CommandToggleSiteMuted);
}

void MuteSiteForKeyboardFocusedTab(Browser* browser) {
  if (!HasKeyboardFocusedTab(browser)) {
    return;
  }
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      *GetKeyboardFocusedTabIndex(browser),
      TabStripModel::ContextMenuCommand::CommandToggleSiteMuted);
}

void PinKeyboardFocusedTab(Browser* browser) {
  if (!HasKeyboardFocusedTab(browser)) {
    return;
  }
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      *GetKeyboardFocusedTabIndex(browser),
      TabStripModel::ContextMenuCommand::CommandTogglePinned);
}

void GroupKeyboardFocusedTab(Browser* browser) {
  if (!HasKeyboardFocusedTab(browser)) {
    return;
  }
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      *GetKeyboardFocusedTabIndex(browser),
      TabStripModel::ContextMenuCommand::CommandToggleGrouped);
}

void DuplicateKeyboardFocusedTab(Browser* browser) {
  if (HasKeyboardFocusedTab(browser)) {
    DuplicateTabAt(browser, *GetKeyboardFocusedTabIndex(browser));
  }
}

bool HasKeyboardFocusedTab(const Browser* browser) {
  return GetKeyboardFocusedTabIndex(browser).has_value();
}

void ConvertPopupToTabbedBrowser(Browser* browser) {
  base::RecordAction(UserMetricsAction("ShowAsTab"));
  TabStripModel* tab_strip = browser->tab_strip_model();
  // If this popup is the last browser object, removing it from the browser-list
  // will trigger OnShutdownStarting for Window close. Create the new browser
  // object first, before removing the existing object from the browser-list in
  // order to avoid incorrectly triggering a shutdown.
  Browser* b = Browser::Create(Browser::CreateParams(browser->profile(), true));
  // This method moves a WebContents from a non-normal browser window to a
  // normal browser window. We cannot move the Tab over directly since TabModel
  // enforces the requirement that it cannot move between window types.
  // https://crbug.com/334281979): Non-normal browser windows should not have a
  // tab to begin with.
  std::unique_ptr<content::WebContents> contents_move =
      tab_strip->DetachWebContentsAtForInsertion(tab_strip->active_index());

  // This method moves a WebContents from a non-normal browser window to a
  // normal browser window. We cannot move the Tab over directly since TabModel
  // enforces the requirement that it cannot move between window types.
  // https://crbug.com/334281979): Non-normal browser windows should not have a
  // tab to begin with.
  b->tab_strip_model()->AppendWebContents(std::move(contents_move), true);
  b->window()->Show();
}

void CloseTabsToRight(Browser* browser) {
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      browser->tab_strip_model()->active_index(),
      TabStripModel::CommandCloseTabsToRight);
}

void CloseOtherTabs(Browser* browser) {
  browser->tab_strip_model()->ExecuteContextMenuCommand(
      browser->tab_strip_model()->active_index(),
      TabStripModel::CommandCloseOtherTabs);
}

void Exit() {
  base::RecordAction(UserMetricsAction("Exit"));
  chrome::AttemptUserExit();
}

void BookmarkCurrentTab(Browser* browser) {
  base::RecordAction(base::UserMetricsAction("Star"));
  BookmarkModel* model =
      BookmarkModelFactory::GetForBrowserContext(browser->profile());
  GURL url;
  std::u16string title;
  if (!BookmarkCurrentTabHelper(browser, model, &url, &title)) {
    return;
  }
  bool was_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
  bookmarks::AddIfNotBookmarked(model, url, title);
  bool is_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
  // Make sure the model actually added a bookmark before showing the star. A
  // bookmark isn't created if the url is invalid.
  if (browser->window()->IsActive() && is_bookmarked_by_user) {
    // Only show the bubble if the window is active, otherwise we may get into
    // weird situations where the bubble is deleted as soon as it is shown.
    browser->window()->ShowBookmarkBubble(url, was_bookmarked_by_user);
  }

  if (!was_bookmarked_by_user && is_bookmarked_by_user) {
    RecordBookmarksAdded(browser->profile());
  }
}

void BookmarkCurrentTabInFolder(Browser* browser,
                                BookmarkModel* model,
                                int64_t folder_id) {
  GURL url;
  std::u16string title;
  if (!BookmarkCurrentTabHelper(browser, model, &url, &title)) {
    return;
  }
  const bookmarks::BookmarkNode* parent =
      bookmarks::GetBookmarkNodeByID(model, folder_id);
  if (parent) {
    bool was_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
    model->AddNewURL(parent, 0, title, url);
    bool is_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
    if (!was_bookmarked_by_user && is_bookmarked_by_user) {
      RecordBookmarksAdded(browser->profile());
    }
  }
}

bool CanBookmarkCurrentTab(const Browser* browser) {
  BookmarkModel* model =
      BookmarkModelFactory::GetForBrowserContext(browser->profile());
  return browser_defaults::bookmarks_enabled &&
         browser->profile()->GetPrefs()->GetBoolean(
             bookmarks::prefs::kEditBookmarksEnabled) &&
         model && model->loaded() && browser->is_type_normal();
}

void BookmarkAllTabs(Browser* browser) {
  base::RecordAction(UserMetricsAction("BookmarkAllTabs"));
  RecordBookmarkAllTabsWithTabsCount(browser->profile(),
                                     browser->tab_strip_model()->count());

  bookmarks::ShowBookmarkAllTabsDialog(browser);
}

bool CanBookmarkAllTabs(const Browser* browser) {
  return browser->tab_strip_model()->count() > 1 &&
         CanBookmarkCurrentTab(browser);
}

bool CanMoveActiveTabToReadLater(Browser* browser) {
  GURL url;
  std::u16string title;
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  ReadingListModel* model = GetReadingListModel(browser);
  return CanMoveWebContentsToReadLater(browser, web_contents, model, &url,
                                       &title);
}

void MoveCurrentTabToReadLater(Browser* browser) {
  MoveTabsToReadLater(browser,
                      {browser->tab_strip_model()->GetActiveWebContents()});
}

void MoveTabsToReadLater(Browser* browser,
                         std::vector<content::WebContents*> web_contentses) {
  int added_to_read_later = 0;
  for (WebContents* const web_contents : web_contentses) {
    GURL url;
    std::u16string title;
    ReadingListModel* model = GetReadingListModel(browser);
    if (!CanMoveWebContentsToReadLater(browser, web_contents, model, &url,
                                       &title)) {
      continue;
    }
    model->AddOrReplaceEntry(url, base::UTF16ToUTF8(title),
                             reading_list::EntrySource::ADDED_VIA_CURRENT_APP,
                             /*estimated_read_time=*/std::nullopt,
                             /*creation_time=*/std::nullopt);
    BrowserUserEducationInterface::From(browser)->MaybeShowFeaturePromo(
        feature_engagement::kIPHReadingListDiscoveryFeature);
    base::UmaHistogramEnumeration(
        "ReadingList.BookmarkBarState.OnEveryAddToReadingList",
        BookmarkBarController::From(browser)->bookmark_bar_state());
    added_to_read_later += 1;
  }

  if (added_to_read_later == 0) {
    return;
  }

#if !BUILDFLAG(IS_ANDROID)
  if (toast_features::IsEnabled(toast_features::kReadingListToast)) {
    // Don't show the reading list toast if the side panel is visible.
    if (browser->GetFeatures().side_panel_ui()->IsSidePanelEntryShowing(
            SidePanelEntryKey(SidePanelEntryId::kReadingList))) {
      return;
    }

    ToastController* const toast_controller =
        browser->GetFeatures().toast_controller();
    if (toast_controller) {
      ToastParams params = ToastParams(ToastId::kAddedToReadingList);
      params.body_string_cardinality_param = added_to_read_later;
      toast_controller->MaybeShowToast(std::move(params));
    }
  }
#endif
}

bool MarkCurrentTabAsReadInReadLater(Browser* browser) {
  GURL url;
  std::u16string title;
  ReadingListModel* model = GetReadingListModel(browser);
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  if (!model || !GetTabURLAndTitleToSave(web_contents, &url, &title)) {
    return false;
  }
  scoped_refptr<const ReadingListEntry> entry = model->GetEntryByURL(url);
  // Mark current tab as read.
  if (entry && !entry->IsRead()) {
    model->SetReadStatusIfExists(url, true);
  }
  return entry != nullptr;
}

bool IsCurrentTabUnreadInReadLater(Browser* browser) {
  GURL url;
  std::u16string title;
  ReadingListModel* model = GetReadingListModel(browser);
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  if (!model || !GetTabURLAndTitleToSave(web_contents, &url, &title)) {
    return false;
  }
  scoped_refptr<const ReadingListEntry> entry = model->GetEntryByURL(url);
  return entry && !entry->IsRead();
}

void ShowOffersAndRewardsForPage(BrowserWindowInterface* bwi) {
  WebContents* const web_contents =
      bwi->GetTabStripModel()->GetActiveWebContents();
  autofill::OfferNotificationBubbleControllerImpl* controller =
      autofill::OfferNotificationBubbleControllerImpl::FromWebContents(
          web_contents);
  DCHECK(controller);
  controller->ReshowBubble();
}

void SaveCreditCard(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  autofill::SaveCardBubbleControllerImpl* controller =
      autofill::SaveCardBubbleControllerImpl::FromWebContents(web_contents);
  controller->ReshowBubble(/*is_user_gesture=*/true);
}

void SaveIban(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  autofill::IbanBubbleControllerImpl* controller =
      autofill::IbanBubbleControllerImpl::FromWebContents(web_contents);
  controller->ReshowBubble();
}

void ShowMandatoryReauthOptInPrompt(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  autofill::MandatoryReauthBubbleControllerImpl* controller =
      autofill::MandatoryReauthBubbleControllerImpl::FromWebContents(
          web_contents);
  controller->ReshowBubble();
}

void SaveAutofillAddress(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  autofill::AddressBubblesController* controller =
      autofill::AddressBubblesController::FromWebContents(web_contents);
  controller->OnIconClicked();
}

void ShowFilledCardInformationBubble(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  auto* controller =
      autofill::FilledCardInformationBubbleControllerImpl::FromWebContents(
          web_contents);
  if (controller) {
    controller->ReshowBubble();
  }
}

void ShowVirtualCardEnrollBubble(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  autofill::VirtualCardEnrollBubbleControllerImpl* controller =
      autofill::VirtualCardEnrollBubbleControllerImpl::FromWebContents(
          web_contents);
  if (controller) {
    controller->ReshowBubble();
  }
}

void StartTabOrganizationRequest(Browser* browser) {
  TabOrganizationService* service =
      TabOrganizationServiceFactory::GetForProfile(browser->profile());
  UMA_HISTOGRAM_BOOLEAN("Tab.Organization.AllEntrypoints.Clicked", true);
  UMA_HISTOGRAM_BOOLEAN("Tab.Organization.ThreeDotMenu.Clicked", true);

  service->RestartSessionAndShowUI(browser,
                                   TabOrganizationEntryPoint::kThreeDotMenu);
}

void ShowTranslateBubble(BrowserWindowInterface* bwi) {
  if (!bwi->GetWindow()->IsActive()) {
    return;
  }

  WebContents* const web_contents =
      bwi->GetTabStripModel()->GetActiveWebContents();
  ChromeTranslateClient* chrome_translate_client =
      ChromeTranslateClient::FromWebContents(web_contents);

  if (!chrome_translate_client) {
    return;
  }

  // The Translate bubble will not show if a text field is focused, so we clear
  // focus here as the user has intentionally opened the bubble.
  web_contents->ClearFocusedElement();

  std::string source_language;
  std::string target_language;
  chrome_translate_client->GetTranslateLanguages(web_contents, &source_language,
                                                 &target_language);

  // If the source language matches the target language, we change the source
  // language to unknown, so that we display "Detected Language".
  if (source_language == target_language) {
    source_language = language_detection::kUnknownLanguageCode;
  }

  translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE;
  auto* language_state =
      chrome_translate_client->GetTranslateManager()->GetLanguageState();

  if (language_state->translation_pending()) {
    step = translate::TRANSLATE_STEP_TRANSLATING;
  } else if (language_state->translation_error()) {
    step = translate::TRANSLATE_STEP_TRANSLATE_ERROR;
  } else if (language_state->IsPageTranslated()) {
    step = translate::TRANSLATE_STEP_AFTER_TRANSLATE;
  }
  bwi->GetBrowserForMigrationOnly()->window()->ShowTranslateBubble(
      web_contents, step, source_language, target_language,
      translate::TranslateErrors::NONE, true);
}

void ManagePasswordsForPage(BrowserWindowInterface* bwi) {
  auto* const user_education = BrowserUserEducationInterface::From(bwi);
  user_education->NotifyFeaturePromoFeatureUsed(
      feature_engagement::kIPHPasswordsManagementBubbleAfterSaveFeature,
      FeaturePromoFeatureUsedAction::kClosePromoIfPresent);
  user_education->NotifyFeaturePromoFeatureUsed(
      feature_engagement::kIPHPasswordsManagementBubbleDuringSigninFeature,
      FeaturePromoFeatureUsedAction::kClosePromoIfPresent);
  user_education->NotifyFeaturePromoFeatureUsed(
      feature_engagement::kIPHPasswordManagerShortcutFeature,
      FeaturePromoFeatureUsedAction::kClosePromoIfPresent);
  WebContents* const web_contents =
      bwi->GetTabStripModel()->GetActiveWebContents();
  ManagePasswordsUIController* controller =
      ManagePasswordsUIController::FromWebContents(web_contents);
  controller->QueueOrShowBubble(
      /*user_action=*/!controller->IsAutomaticallyOpeningBubble());
}

bool CanSendTabToSelf(BrowserWindowInterface* bwi) {
  return send_tab_to_self::ShouldDisplayEntryPoint(
      bwi->GetTabStripModel()->GetActiveWebContents());
}

void SendTabToSelf(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  send_tab_to_self::ShowBubble(web_contents);
}

bool CanGenerateQrCode(const Browser* browser) {
  return !sharing_hub::SharingIsDisabledByPolicy(browser->profile()) &&
         qrcode_generator::QRCodeGeneratorBubbleController::
             IsGeneratorAvailable(browser->tab_strip_model()
                                      ->GetActiveWebContents()
                                      ->GetController()
                                      .GetLastCommittedEntry()
                                      ->GetURL());
}

void GenerateQRCode(BrowserWindowInterface* bwi) {
  WebContents* web_contents = bwi->GetTabStripModel()->GetActiveWebContents();
  qrcode_generator::QRCodeGeneratorBubbleController* controller =
      qrcode_generator::QRCodeGeneratorBubbleController::Get(web_contents);
  content::NavigationEntry* entry =
      web_contents->GetController().GetLastCommittedEntry();
  controller->ShowBubble(entry->GetURL());
}

void SharingHub(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  sharing_hub::SharingHubBubbleController* controller =
      sharing_hub::SharingHubBubbleController::CreateOrGetFromWebContents(
          web_contents);
  controller->ShowBubble(share::ShareAttempt(web_contents));
}

void ScreenshotCapture(Browser* browser) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  sharing_hub::ScreenshotCapturedBubbleController* controller =
      sharing_hub::ScreenshotCapturedBubbleController::Get(web_contents);
  controller->Capture(browser);
}

void SavePage(Browser* browser) {
  base::RecordAction(UserMetricsAction("SavePage"));
  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
  DCHECK(current_tab);
  if (current_tab->GetContentsMimeType() == "application/pdf") {
    base::RecordAction(UserMetricsAction("PDF.SavePage"));
#if BUILDFLAG(ENABLE_PDF)
    // The PDF viewer may handle the event by itself.
    if (chrome_pdf::features::IsOopifPdfEnabled() &&
        pdf_extension_util::MaybeDispatchSaveEvent(
            current_tab->GetPrimaryMainFrame())) {
      return;
    }
#endif  // BUILDFLAG(ENABLE_PDF)
  }
  current_tab->OnSavePage();
}

bool CanSavePage(const Browser* browser) {
  // LocalState can be NULL in tests.
  if (g_browser_process->local_state() &&
      !g_browser_process->local_state()->GetBoolean(
          prefs::kAllowFileSelectionDialogs)) {
    return false;
  }
  if (static_cast<policy::DownloadRestriction>(
          browser->profile()->GetPrefs()->GetInteger(
              policy::policy_prefs::kDownloadRestrictions)) ==
      policy::DownloadRestriction::ALL_FILES) {
    return false;
  }
  return !browser->is_type_devtools() &&
         !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
}

void Print(BrowserWindowInterface* bwi) {
#if BUILDFLAG(ENABLE_PRINTING)
  auto* const web_contents = bwi->GetTabStripModel()->GetActiveWebContents();

  // Launch ChromeOS print preview only if in a ChromeOS build and
  // `kPrintPreviewCrosPrimary` enabled. Otherwise use browser print preview.
#if BUILDFLAG(IS_CHROMEOS)
  if (base::FeatureList::IsEnabled(::features::kPrintPreviewCrosPrimary)) {
    chromeos::printing::StartPrint(
        web_contents,
        /*print_renderer=*/mojo::NullAssociatedRemote(),
        bwi->GetProfile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled),
        /*has_selection=*/false);
    return;
  }
#endif

  printing::StartPrint(
      web_contents,
#if BUILDFLAG(IS_CHROMEOS)
      /*print_renderer=*/mojo::NullAssociatedRemote(),
#endif
      bwi->GetProfile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled),
      /*has_selection=*/false);
#endif  // BUILDFLAG(ENABLE_PRINTING)
}

bool CanPrint(BrowserWindowInterface* bwi) {
#if BUILDFLAG(ENABLE_PRINTING)
  // Do not print when printing is disabled via pref or policy.
  // Do not print when a page has crashed.
  // Do not print when a constrained window is showing. It's confusing.
  // TODO(gbillock): Need to re-assess the call to
  // IsShowingWebContentsModalDialog after a popup management policy is
  // refined -- we will probably want to just queue the print request, not
  // block it.
  WebContents* const current_tab =
      bwi->GetTabStripModel()->GetActiveWebContents();
  return bwi->GetProfile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
         (current_tab && !current_tab->IsCrashed()) &&
         !(IsShowingWebContentsModalDialog(bwi) ||
           GetContentRestrictions(bwi) & CONTENT_RESTRICTION_PRINT);
#else   // BUILDFLAG(ENABLE_PRINTING)
  return false;
#endif  // BUILDFLAG(ENABLE_PRINTING)
}

#if BUILDFLAG(ENABLE_PRINTING)
void BasicPrint(Browser* browser) {
  printing::StartBasicPrint(browser->tab_strip_model()->GetActiveWebContents());
}

bool CanBasicPrint(Browser* browser) {
#if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
  // If printing is not disabled via pref or policy, it is always possible to
  // advanced print when the print preview is visible.
  return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
         (PrintPreviewShowing(browser) || CanPrint(browser));
#else
  return false;  // The print dialog is disabled.
#endif  // BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
}
#endif  // BUILDFLAG(ENABLE_PRINTING)

bool CanRouteMedia(BrowserWindowInterface* bwi) {
  // Do not allow user to open Media Router dialog when there is already an
  // active modal dialog. This avoids overlapping dialogs.
  return media_router::MediaRouterEnabled(bwi->GetProfile()) &&
         !IsShowingWebContentsModalDialog(bwi);
}

void RouteMediaInvokedFromAppMenu(Browser* browser) {
  DCHECK(CanRouteMedia(browser));

  media_router::MediaRouterDialogController* dialog_controller =
      media_router::MediaRouterDialogController::GetOrCreateForWebContents(
          browser->tab_strip_model()->GetActiveWebContents());
  if (!dialog_controller) {
    return;
  }

  dialog_controller->ShowMediaRouterDialog(
      media_router::MediaRouterDialogActivationLocation::APP_MENU);
}

void Find(Browser* browser) {
  base::RecordAction(UserMetricsAction("Find"));
  FindInPage(browser, false, true);
}

void FindNext(Browser* browser) {
  base::RecordAction(UserMetricsAction("FindNext"));
  FindInPage(browser, true, true);
}

void FindPrevious(Browser* browser) {
  base::RecordAction(UserMetricsAction("FindPrevious"));
  FindInPage(browser, true, false);
}

void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
  browser->GetFeatures().GetFindBarController()->Show(find_next,
                                                      forward_direction);
}

void ShowTabSearch(BrowserWindowInterface* bwi) {
  bwi->GetBrowserForMigrationOnly()->window()->CreateTabSearchBubble(
      tab_search::mojom::TabSearchSection::kSearch,
      tab_search::mojom::TabOrganizationFeature::kNone);
}

void CloseTabSearch(Browser* browser) {
  browser->window()->CloseTabSearchBubble();
}

void ToggleContextualTasksSidePanel(BrowserWindowInterface* browser) {
  auto* coordinator =
      contextual_tasks::ContextualTasksSidePanelCoordinator::From(browser);
  CHECK(coordinator);
  if (coordinator->IsSidePanelOpenForContextualTask()) {
    coordinator->Close();
  } else {
    coordinator->Show();
  }
}

void ToggleVerticalTabs(Browser* browser) {
  tabs::VerticalTabStripStateController* controller =
      browser->GetFeatures().vertical_tab_strip_state_controller();
  if (!controller) {
    return;
  }

  bool initial_tab_orientation = controller->ShouldDisplayVerticalTabs();

  controller->SetVerticalTabsEnabled(!initial_tab_orientation);
}

void ShowTabDeclutter(Browser* browser) {
  browser->window()->CreateTabSearchBubble(
      tab_search::mojom::TabSearchSection::kOrganize,
      tab_search::mojom::TabOrganizationFeature::kDeclutter);
}

bool CanCloseFind(Browser* browser) {
  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
  if (!current_tab) {
    return false;
  }

  find_in_page::FindTabHelper* find_helper =
      find_in_page::FindTabHelper::FromWebContents(current_tab);
  return find_helper ? find_helper->find_ui_active() : false;
}

void CloseFind(Browser* browser) {
  browser->GetFeatures().GetFindBarController()->EndFindSession(
      find_in_page::SelectionAction::kKeep, find_in_page::ResultAction::kKeep);
}

void Zoom(Browser* browser, content::PageZoom zoom) {
  zoom::PageZoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
                       zoom);
}

void FocusToolbar(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusToolbar"));
  browser->window()->FocusToolbar();
}

void FocusLocationBar(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusLocation"));
  browser->window()->SetFocusToLocationBar(true);
}

void FocusSearch(Browser* browser) {
  // TODO(beng): replace this with FocusLocationBar
  base::RecordAction(UserMetricsAction("FocusSearch"));
  browser->window()->GetLocationBar()->FocusSearch();
}

void FocusAppMenu(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusAppMenu"));
  browser->window()->FocusAppMenu();
}

void FocusBookmarksToolbar(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
  browser->window()->FocusBookmarksToolbar();
}

void FocusInactivePopupForAccessibility(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusInactivePopupForAccessibility"));
  browser->window()->FocusInactivePopupForAccessibility();
}

void FocusNextPane(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusNextPane"));
  browser->window()->RotatePaneFocus(true);
}

void FocusPreviousPane(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusPreviousPane"));
  browser->window()->RotatePaneFocus(false);
}

void FocusWebContentsPane(Browser* browser) {
  base::RecordAction(UserMetricsAction("FocusWebContentsPane"));
  browser->window()->FocusWebContentsPane();
}

void ToggleDevToolsWindow(BrowserWindowInterface* bwi,
                          DevToolsToggleAction action,
                          DevToolsOpenedByAction opened_by) {
  if (action.type() == DevToolsToggleAction::kShowConsolePanel) {
    base::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
  } else {
    base::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
  }
  DevToolsWindow::ToggleDevToolsWindow(bwi->GetBrowserForMigrationOnly(),
                                       action, opened_by);
}

bool CanOpenTaskManager() {
#if !BUILDFLAG(IS_ANDROID)
  return true;
#else
  return false;
#endif
}

void OpenTaskManager(BrowserWindowInterface* bwi,
                     task_manager::StartAction start_action) {
#if !BUILDFLAG(IS_ANDROID)
  base::RecordAction(UserMetricsAction("TaskManager"));
  chrome::ShowTaskManager(bwi ? bwi->GetBrowserForMigrationOnly() : nullptr,
                          start_action);
#else
  NOTREACHED();
#endif
}

void OpenFeedbackDialog(BrowserWindowInterface* bwi,
                        feedback::FeedbackSource source,
                        const std::string& description_template,
                        const std::string& category_tag) {
  base::RecordAction(UserMetricsAction("Feedback"));
  chrome::ShowFeedbackPage(bwi, source, description_template,
                           std::string() /* description_placeholder_text */,
                           category_tag, std::string() /* extra_diagnostics */);
}

void ToggleBookmarkBar(Browser* browser) {
  base::RecordAction(UserMetricsAction("ShowBookmarksBar"));
  ToggleBookmarkBarWhenVisible(browser->profile());
}

void ToggleShowFullURLs(Browser* browser) {
  bool pref_enabled = browser->profile()->GetPrefs()->GetBoolean(
      omnibox::kPreventUrlElisionsInOmnibox);
  browser->profile()->GetPrefs()->SetBoolean(
      omnibox::kPreventUrlElisionsInOmnibox, !pref_enabled);
}

void ToggleShowGoogleLensShortcut(Browser* browser) {
  bool pref_enabled = browser->profile()->GetPrefs()->GetBoolean(
      omnibox::kShowGoogleLensShortcut);
  browser->profile()->GetPrefs()->SetBoolean(omnibox::kShowGoogleLensShortcut,
                                             !pref_enabled);
}

void ToggleShowAiModeOmniboxButton(Browser* browser) {
  bool pref_enabled = browser->profile()->GetPrefs()->GetBoolean(
      omnibox::kShowAiModeOmniboxButton);
  browser->profile()->GetPrefs()->SetBoolean(omnibox::kShowAiModeOmniboxButton,
                                             !pref_enabled);
}

void ToggleShowSearchTools(Browser* browser) {
  bool pref_enabled =
      browser->profile()->GetPrefs()->GetBoolean(omnibox::kShowSearchTools);
  browser->profile()->GetPrefs()->SetBoolean(omnibox::kShowSearchTools,
                                             !pref_enabled);
}

void ShowAppMenu(Browser* browser) {
  // We record the user metric for this event in AppMenu::RunMenu.
  browser->window()->ShowAppMenu();
}

void ShowAvatarMenu(Browser* browser) {
  browser->window()->ShowAvatarBubbleFromAvatarButton(
      /*is_source_accelerator=*/true);
}

// TODO(crbug.com/345770406): Rename the function name.
// We removed the extra confirmation step in the Chrome update flow. After the
// full rollout of the code, this name will be misleading. We will clean up the
// code and its related source enums.
void OpenUpdateChromeDialog(Browser* browser) {
  if (UpgradeDetector::GetInstance()->is_outdated_install()) {
    UpgradeDetector::GetInstance()->NotifyOutdatedInstall();
  } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
    UpgradeDetector::GetInstance()->NotifyOutdatedInstallNoAutoUpdate();
  } else {
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
    if (base::FeatureList::IsEnabled(features::kFewerUpdateConfirmations)) {
      chrome::AttemptRelaunch();
      return;
    }
#endif
    base::RecordAction(UserMetricsAction("UpdateChrome"));
    browser->window()->ShowUpdateChromeDialog();
  }
}

bool CanRequestTabletSite(WebContents* current_tab) {
  return current_tab &&
         current_tab->GetController().GetLastCommittedEntry() != nullptr;
}

bool IsRequestingTabletSite(Browser* browser) {
  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
  if (!current_tab) {
    return false;
  }
  content::NavigationEntry* entry =
      current_tab->GetController().GetLastCommittedEntry();
  if (!entry) {
    return false;
  }
  return entry->GetIsOverridingUserAgent();
}

void ToggleRequestTabletSite(Browser* browser) {
  WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
  if (!current_tab) {
    return;
  }
  NavigationController& controller = current_tab->GetController();
  NavigationEntry* entry = controller.GetLastCommittedEntry();
  if (!entry) {
    return;
  }
  if (entry->GetIsOverridingUserAgent()) {
    entry->SetIsOverridingUserAgent(false);
  } else {
    SetAndroidOsForTabletSite(current_tab);
  }
  controller.LoadOriginalRequestURL();
}

void SetAndroidOsForTabletSite(content::WebContents* current_tab) {
  DCHECK(current_tab);
  NavigationEntry* entry = current_tab->GetController().GetLastCommittedEntry();
  if (entry) {
    entry->SetIsOverridingUserAgent(true);
    std::string product = embedder_support::GetProductAndVersion() + " Mobile";
    blink::UserAgentOverride ua_override;
    ua_override.ua_string_override =
        embedder_support::BuildUserAgentFromOSAndProduct(
            kOsOverrideForTabletSite, product);
    ua_override.ua_metadata_override = embedder_support::GetUserAgentMetadata();
    ua_override.ua_metadata_override->mobile = true;
    ua_override.ua_metadata_override->form_factors = {blink::kTabletFormFactor};
    ua_override.ua_metadata_override->platform =
        kChPlatformOverrideForTabletSite;
    ua_override.ua_metadata_override->platform_version = std::string();
    current_tab->SetUserAgentOverride(ua_override, false);
  }
}

void ToggleFullscreenMode(BrowserWindowInterface* browser,
                          bool user_initiated) {
  DCHECK(browser);
  browser->GetFeatures()
      .exclusive_access_manager()
      ->fullscreen_controller()
      ->ToggleBrowserFullscreenMode(user_initiated);
}

void ClearCache(Browser* browser) {
  content::BrowsingDataRemover* remover =
      browser->profile()->GetBrowsingDataRemover();
  remover->Remove(base::Time(), base::Time::Max(),
                  content::BrowsingDataRemover::DATA_TYPE_CACHE,
                  content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB);
  // BrowsingDataRemover takes care of deleting itself when done.
}

bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
  WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
  return contents ? content::DevToolsAgentHost::IsDebuggerAttached(contents)
                  : false;
}

void CopyURL(BrowserWindowInterface* bwi, content::WebContents* web_contents) {
  ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
  scw.WriteText(base::UTF8ToUTF16(web_contents->GetVisibleURL().spec()));

#if !BUILDFLAG(IS_ANDROID)
  if (toast_features::IsEnabled(toast_features::kLinkCopiedToast)) {
    ToastController* const toast_controller =
        bwi->GetFeatures().toast_controller();
    if (toast_controller) {
      toast_controller->MaybeShowToast(ToastParams(ToastId::kLinkCopied));
    }
  }
#endif
}

bool CanCopyUrl(BrowserWindowInterface* bwi) {
  return IsWebAppOrCustomTab(bwi) ||
         !sharing_hub::SharingIsDisabledByPolicy(bwi->GetProfile());
}

bool IsWebAppOrCustomTab(const BrowserWindowInterface* bwi) {
  return
#if BUILDFLAG(IS_CHROMEOS)
      bwi->GetType() == BrowserWindowInterface::TYPE_CUSTOM_TAB ||
#endif
      web_app::AppBrowserController::IsWebApp(bwi);
}

Browser* OpenInChrome(Browser* hosted_app_browser) {
  // Find a non-incognito browser.
  Browser* target_browser =
      chrome::FindTabbedBrowser(hosted_app_browser->profile(), false);

  if (!target_browser) {
    target_browser = Browser::Create(
        Browser::CreateParams(hosted_app_browser->profile(), true));
  }

  web_app::ReparentWebContentsIntoBrowserImpl(
      hosted_app_browser,
      hosted_app_browser->tab_strip_model()->GetActiveWebContents(),
      target_browser);
  return target_browser;
}

bool CanViewSource(const Browser* browser) {
  if (browser->is_type_devtools()) {
    return false;
  }

  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();

  // Disallow ViewSource if DevTools are disabled.
  if (!DevToolsWindow::AllowDevToolsFor(browser->profile(), web_contents)) {
    return false;
  }
  return web_contents->GetController().CanViewSource();
}

bool CanToggleCaretBrowsing(Browser* browser) {
#if BUILDFLAG(IS_MAC)
  // On Mac, ignore the keyboard shortcut unless web contents is focused,
  // because the keyboard shortcut interferes with a Japenese IME when the
  // omnibox is focused.  See https://crbug.com/1138475
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  if (!web_contents) {
    return false;
  }

  content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
  return rwhv && rwhv->HasFocus();
#else
  return true;
#endif  // BUILDFLAG(IS_MAC)
}

void ToggleCaretBrowsing(Browser* browser) {
  if (!CanToggleCaretBrowsing(browser)) {
    return;
  }

  PrefService* prefService = browser->profile()->GetPrefs();
  bool enabled = prefService->GetBoolean(prefs::kCaretBrowsingEnabled);

  if (enabled) {
    base::RecordAction(base::UserMetricsAction(
        "Accessibility.CaretBrowsing.DisableWithKeyboard"));
    prefService->SetBoolean(prefs::kCaretBrowsingEnabled, false);
    return;
  }

  // Show a confirmation dialog, unless either (1) the command-line
  // flag was used, or (2) the user previously checked the box
  // indicating not to ask them next time.
  if (prefService->GetBoolean(prefs::kShowCaretBrowsingDialog) &&
      !base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableCaretBrowsing)) {
    browser->window()->ShowCaretBrowsingDialog();
  } else {
    base::RecordAction(base::UserMetricsAction(
        "Accessibility.CaretBrowsing.EnableWithKeyboard"));
    prefService->SetBoolean(prefs::kCaretBrowsingEnabled, true);
  }
}

void PromptToNameWindow(Browser* browser) {
  chrome::ShowWindowNamePrompt(browser);
}

#if BUILDFLAG(IS_CHROMEOS)
void ToggleMultitaskMenu(Browser* browser) {
  browser->window()->ToggleMultitaskMenu();
}
#endif

#if !defined(TOOLKIT_VIEWS)
std::optional<int> GetKeyboardFocusedTabIndex(const Browser* browser) {
  return std::nullopt;
}
#endif

void ShowIncognitoClearBrowsingDataDialog(BrowserWindowInterface* bwi) {
  bwi->GetBrowserForMigrationOnly()
      ->window()
      ->ShowIncognitoClearBrowsingDataDialog();
}

void ShowIncognitoHistoryDisclaimerDialog(Browser* browser) {
  browser->window()->ShowIncognitoHistoryDisclaimerDialog();
}

bool ShouldInterceptChromeURLNavigationInIncognito(Browser* browser,
                                                   const GURL& url) {
  if (!browser || !browser->profile()->IsIncognitoProfile()) {
    return false;
  }

  bool show_clear_browsing_data_dialog =
      url == GURL(chrome::kChromeUISettingsURL)
                 .Resolve(chrome::kClearBrowserDataSubPage);

  bool show_history_disclaimer_dialog =
      url == GURL(chrome::kChromeUIHistoryURL);

  return show_clear_browsing_data_dialog || show_history_disclaimer_dialog;
}

void ProcessInterceptedChromeURLNavigationInIncognito(Browser* browser,
                                                      const GURL& url) {
  if (url == GURL(chrome::kChromeUISettingsURL)
                 .Resolve(chrome::kClearBrowserDataSubPage)) {
    ShowIncognitoClearBrowsingDataDialog(browser);
  } else if (url == GURL(chrome::kChromeUIHistoryURL)) {
    ShowIncognitoHistoryDisclaimerDialog(browser);
  } else {
    NOTREACHED();
  }
}

void ExecLensOverlay(Browser* browser) {
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  CHECK(web_contents);

  LensSearchController* const controller =
      LensSearchController::FromTabWebContents(web_contents);
  CHECK(controller);
  controller->OpenLensOverlay(lens::LensOverlayInvocationSource::kAppMenu);
  BrowserUserEducationInterface::From(browser)->NotifyNewBadgeFeatureUsed(
      lens::features::kLensOverlay);
}

void ExecLensRegionSearch(Browser* browser) {
#if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
  Profile* profile = browser->profile();
  TemplateURLService* service =
      TemplateURLServiceFactory::GetForProfile(profile);
  WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
  GURL url = contents->GetController().GetLastCommittedEntry()->GetURL();

  if (lens::IsRegionSearchEnabled(browser, profile, service, url)) {
    const bool is_google_dsp = search::DefaultSearchProviderIsGoogle(profile);
    const lens::AmbientSearchEntryPoint entry_point =
        is_google_dsp ? lens::AmbientSearchEntryPoint::
                            CONTEXT_MENU_SEARCH_REGION_WITH_GOOGLE_LENS
                      : lens::AmbientSearchEntryPoint::
                            CONTEXT_MENU_SEARCH_REGION_WITH_WEB;
    browser->GetFeatures().lens_region_search_controller()->Start(
        contents,
        /*use_fullscreen_capture=*/false, is_google_dsp, entry_point);
  }
#endif  // BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
}

void OpenCommerceProductSpecificationsTab(Browser* browser,
                                          const std::vector<GURL>& urls,
                                          const int position) {
  auto* prefs = browser->profile()->GetPrefs();
  // If user has not accepted the latest disclosure, show the disclosure dialog
  // first.
  if (prefs && prefs->GetInteger(
                   commerce::kProductSpecificationsAcceptedDisclosureVersion) !=
                   static_cast<int>(commerce::product_specifications::mojom::
                                        DisclosureVersion::kV1)) {
    commerce::DialogArgs dialog_args(urls, std::string(), /*set_id=*/"",
                                     /*in_new_tab=*/true);
    commerce::ProductSpecificationsDisclosureDialog::ShowDialog(
        browser->profile(), browser->tab_strip_model()->GetActiveWebContents(),
        std::move(dialog_args));
    return;
  }

  chrome::AddTabAt(browser, commerce::GetProductSpecsTabUrl(urls), position + 1,
                   true, std::nullopt);
}

}  // namespace chrome
