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

#include <stddef.h>

#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "base/base_paths.h"
#include "base/check_deref.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/notimplemented.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/actor/actor_keyed_service.h"
#include "chrome/browser/actor/execution_engine.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/background/background_contents.h"
#include "chrome/browser/background/background_contents_service.h"
#include "chrome/browser/background/background_contents_service_factory.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/buildflags.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/content_settings/mixed_content_settings_tab_helper.h"
#include "chrome/browser/content_settings/page_specific_content_settings_delegate.h"
#include "chrome/browser/content_settings/sound_content_setting_observer.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/devtools/devtools_toggle_action.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/extensions/extension_ui_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/file_select_helper.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/headless/headless_mode_util.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/lifetime/browser_shutdown.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
#include "chrome/browser/policy/developer_tools_policy_handler.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/preloading/preloading_prefs.h"
#include "chrome/browser/printing/background_printing_manager.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_destroyer.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/repost_form_warning_controller.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/sessions/app_session_service.h"
#include "chrome/browser/sessions/app_session_service_factory.h"
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/sessions/session_service_factory.h"
#include "chrome/browser/sessions/session_service_lookup.h"
#include "chrome/browser/sessions/session_tab_helper_factory.h"
#include "chrome/browser/sessions/tab_restore_service_factory.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h"
#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h"
#include "chrome/browser/ui/bookmarks/bookmark_bar_controller.h"
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_live_tab_context.h"
#include "chrome/browser/ui/browser_manager_service.h"
#include "chrome/browser/ui/browser_manager_service_factory.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_select_file_dialog_controller.h"
#include "chrome/browser/ui/browser_tab_strip_model_delegate.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_ui_prefs.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_iterator.h"
#include "chrome/browser/ui/browser_window/public/create_browser_window.h"
#include "chrome/browser/ui/browser_window/public/desktop_browser_window_capabilities.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/exclusive_access/pointer_lock_controller.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/global_error/global_error.h"
#include "chrome/browser/ui/global_error/global_error_service.h"
#include "chrome/browser/ui/global_error/global_error_service_factory.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/page_action/page_action_icon_type.h"
#include "chrome/browser/ui/sad_tab.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/ui/signin/cookie_clear_on_exit_migration_notice.h"
#include "chrome/browser/ui/singleton_tabs.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/tab_helpers.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_group_model.h"
#include "chrome/browser/ui/tabs/tab_menu_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_utils.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/unload_controller.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/contents_web_view.h"
#include "chrome/browser/ui/views/frame/multi_contents_view.h"
#include "chrome/browser/ui/views/status_bubble_views.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/browser/ui/window_sizer/window_sizer.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_tab_helper.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/branded_strings.h"
#include "chrome/grit/generated_resources.h"
#include "components/blocked_content/list_item_position.h"
#include "components/blocked_content/popup_blocker.h"
#include "components/blocked_content/popup_blocker_tab_helper.h"
#include "components/blocked_content/popup_tracker.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/bookmarks/common/bookmark_pref_names.h"
#include "components/captive_portal/core/buildflags.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/custom_handlers/protocol_handler.h"
#include "components/custom_handlers/protocol_handler_registry.h"
#include "components/custom_handlers/register_protocol_handler_permission_request.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "components/find_in_page/find_tab_helper.h"
#include "components/headless/console_message_logger/headless_console_message_logger.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/javascript_dialogs/tab_modal_dialog_manager.h"
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
#include "components/page_load_metrics/common/page_load_metrics.mojom.h"
#include "components/paint_preview/buildflags/buildflags.h"
#include "components/permissions/permission_request_manager.h"
#include "components/prefs/pref_service.h"
#include "components/saved_tab_groups/public/tab_group_sync_service.h"
#include "components/sessions/content/session_tab_helper.h"
#include "components/sessions/core/session_types.h"
#include "components/sessions/core/tab_restore_service.h"
#include "components/startup_metric_utils/browser/startup_metric_utils.h"
#include "components/tabs/public/split_tab_data.h"
#include "components/tabs/public/split_tab_id.h"
#include "components/tabs/public/split_tab_visual_data.h"
#include "components/tabs/public/tab_group.h"
#include "components/tabs/public/tab_interface.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "components/zoom/zoom_controller.h"
#include "content/public/browser/color_chooser.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_exposed_isolation_level.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/profiling.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/common/window_container_type.mojom-shared.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_map.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "net/base/filename_util.h"
#include "third_party/blink/public/common/security/protocol_handler_security_level.h"
#include "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "third_party/blink/public/mojom/page/draggable_region.mojom.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h"
#include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/mojom/window_show_state.mojom.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/text_elider.h"
#include "ui/gfx/text_utils.h"
#include "url/origin.h"
#include "url/scheme_host_port.h"

#if BUILDFLAG(IS_WIN)
// windows.h must be included before shellapi.h
#include <windows.h>

#include <shellapi.h>

#include "chrome/browser/ui/view_ids.h"
#include "ui/base/win/shell.h"
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(IS_CHROMEOS)
#include "ash/constants/ash_features.h"
#include "chrome/browser/ash/guest_os/guest_os_terminal.h"
#include "chrome/browser/ui/settings_window_manager_chromeos.h"
#endif

#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
#include "components/captive_portal/content/captive_portal_tab_helper.h"
#endif

#if BUILDFLAG(ENABLE_PRINTING)
#include "components/printing/browser/print_composite_client.h"
#endif

#if BUILDFLAG(ENABLE_PAINT_PREVIEW)
#include "components/paint_preview/browser/paint_preview_client.h"  // nogncheck
#endif

#if BUILDFLAG(IS_MAC)
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/display/types/display_constants.h"
#endif  // BUILDFLAG(IS_MAC)

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/preloading/preview/preview_manager.h"
#endif

#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/platform_session_manager.h"
#endif

#if BUILDFLAG(ENABLE_GLIC)
#include "chrome/browser/ai/ai_data_keyed_service.h"          // nogncheck
#include "chrome/browser/ai/ai_data_keyed_service_factory.h"  // nogncheck
#include "chrome/browser/glic/public/glic_enabling.h"
#include "chrome/browser/glic/public/glic_keyed_service.h"
#endif

#if defined(USE_AURA)
#include "chrome/browser/ui/overscroll_pref_manager.h"
#endif  // defined(USE_AURA)

using base::UserMetricsAction;
using content::NavigationController;
using content::NavigationEntry;
using content::OpenURLParams;
using content::Referrer;
using content::RenderWidgetHostView;
using content::SiteInstance;
using content::WebContents;
using custom_handlers::ProtocolHandler;
using extensions::Extension;
using input::NativeWebKeyboardEvent;
using ui::WebDialogDelegate;
using web_modal::WebContentsModalDialogManager;

///////////////////////////////////////////////////////////////////////////////

namespace {

// How long we wait before updating the browser chrome while loading a page.
constexpr base::TimeDelta kUIUpdateCoalescingTime = base::Milliseconds(200);

const extensions::Extension* GetExtensionForOrigin(
    Profile* profile,
    const GURL& security_origin) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
  if (!security_origin.SchemeIs(extensions::kExtensionScheme)) {
    return nullptr;
  }

  const extensions::Extension* extension =
      extensions::ExtensionRegistry::Get(profile)->enabled_extensions().GetByID(
          security_origin.GetHost());
  DCHECK(extension);
  return extension;
#else
  return nullptr;
#endif
}

// Returns a pair [last_window, last_window_for_profile] indicating if `browser`
// is the only browser in total and for this profile.
// Ignores browsers that are in the process of closing.
std::pair<bool, bool> IsLastWindow(const Browser& browser) {
  bool last_window = true;
  bool last_window_for_profile = true;
  ForEachCurrentBrowserWindowInterfaceOrderedByActivation(
      [&](BrowserWindowInterface* other_browser) {
        // Don't count this browser window or any other in the process of
        // closing. Window closing may be delayed, and windows that are in the
        // process of closing don't count against our totals.
        if (other_browser == &browser ||
            other_browser->capabilities()->IsAttemptingToCloseBrowser()) {
          return true;
        }

        last_window = false;

        if (other_browser->GetProfile() == browser.profile()) {
          last_window_for_profile = false;
        }
        return last_window_for_profile;
      });

  return {last_window, last_window_for_profile};
}

// Returns whether the cookie migration notice should be shown: the migration
// is not complete, and this is the last browser window open for this profile.
bool ShouldShowCookieMigrationNoticeForBrowser(const Browser& browser) {
  if (!CanShowCookieClearOnExitMigrationNotice(browser)) {
    return false;
  }

  auto [last_window, last_window_for_profile] = IsLastWindow(browser);
  return last_window_for_profile;
}

void UpdateTabGroupSessionMetadata(Browser* browser,
                                   const tab_groups::TabGroupId& group_id) {
  SessionService* const session_service =
      SessionServiceFactory::GetForProfile(browser->profile());
  if (!session_service) {
    return;
  }

  const tab_groups::TabGroupVisualData* visual_data =
      browser->tab_strip_model()
          ->group_model()
          ->GetTabGroup(group_id)
          ->visual_data();

  session_service->SetTabGroupMetadata(browser->session_id(), group_id,
                                       visual_data);
}

bool ShouldHideUIForFullscreenWrapper(const Browser* browser) {
  return browser->ShouldHideUIForFullscreen();
}

bool AlwaysReturnTrue(const Browser* browser) {
  return true;
}

bool AlwaysReturnFalse(const Browser* browser) {
  return false;
}

base::FunctionRef<bool(const Browser*)> MaybeLazyIsFullscreen(
    const Browser* browser) {
  // Returns a base::FunctionRef instead of a Base::RepeatingCallback to reduce
  // allocation overhead, since this is a performance experiment.
  if (base::FeatureList::IsEnabled(features::kInlineFullscreenPerfExperiment)) {
    // In the experiment branch, lazy-eval ShouldHideUIForFullscreen.
    return &ShouldHideUIForFullscreenWrapper;
  }

  // In the control branch, eagerly evaluate ShouldHideUIForFullscreen.
  return browser->ShouldHideUIForFullscreen() ? &AlwaysReturnTrue
                                              : &AlwaysReturnFalse;
}

bool HasActorTask(Profile* profile, content::RenderFrameHost* rfh) {
  auto* actor_service = actor::ActorKeyedService::Get(profile);
  if (!actor_service) {
    return false;
  }

  auto* wc = content::WebContents::FromRenderFrameHost(rfh);
  if (!wc) {
    return false;
  }

  const auto* tab_interface = tabs::TabInterface::MaybeGetFromContents(wc);
  if (!tab_interface) {
    return false;
  }

  return !actor_service->GetTaskFromTab(*tab_interface).is_null();
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// Browser, CreateParams:

BrowserWindowInterface* BrowserWindowInterface::FromSessionID(
    const SessionID& session_id) {
  BrowserWindowInterface* found = nullptr;
  ForEachCurrentBrowserWindowInterfaceOrderedByActivation(
      [&](BrowserWindowInterface* browser) {
        if (browser->GetSessionID() == session_id) {
          found = browser;
        }
        return !found;
      });
  return found;
}

Browser::CreateParams::CreateParams(Profile* profile, bool user_gesture)
    : CreateParams(TYPE_NORMAL, profile, user_gesture) {}

Browser::CreateParams::CreateParams(Type type,
                                    Profile* profile,
                                    bool user_gesture)
    : type(type), profile(profile), user_gesture(user_gesture) {}

Browser::CreateParams::CreateParams(const CreateParams& other) = default;

Browser::CreateParams& Browser::CreateParams::operator=(
    const CreateParams& other) = default;

Browser::CreateParams::~CreateParams() = default;

// static
Browser::CreateParams Browser::CreateParams::CreateForAppBase(
    bool is_popup,
    const std::string& app_name,
    bool trusted_source,
    const gfx::Rect& window_bounds,
    Profile* profile,
    bool user_gesture) {
  DCHECK(!app_name.empty());

  CreateParams params(is_popup ? Type::TYPE_APP_POPUP : Type::TYPE_APP, profile,
                      user_gesture);
  params.app_name = app_name;
  params.trusted_source = trusted_source;
  params.initial_bounds = window_bounds;

  return params;
}

// static
Browser::CreateParams Browser::CreateParams::CreateForApp(
    const std::string& app_name,
    bool trusted_source,
    const gfx::Rect& window_bounds,
    Profile* profile,
    bool user_gesture) {
  return CreateForAppBase(false, app_name, trusted_source, window_bounds,
                          profile, user_gesture);
}

// static
Browser::CreateParams Browser::CreateParams::CreateForAppPopup(
    const std::string& app_name,
    bool trusted_source,
    const gfx::Rect& window_bounds,
    Profile* profile,
    bool user_gesture) {
  return CreateForAppBase(true, app_name, trusted_source, window_bounds,
                          profile, user_gesture);
}

// static
Browser::CreateParams Browser::CreateParams::CreateForPictureInPicture(
    const std::string& app_name,
    bool trusted_source,
    Profile* profile,
    bool user_gesture) {
  Browser::CreateParams browser_params(Browser::TYPE_PICTURE_IN_PICTURE,
                                       profile, user_gesture);
  browser_params.app_name = app_name;
  browser_params.trusted_source = trusted_source;
  return browser_params;
}

// static
Browser::CreateParams Browser::CreateParams::CreateForDevTools(
    Profile* profile) {
  CreateParams params(TYPE_DEVTOOLS, profile, true);
  params.app_name = DevToolsWindow::kDevToolsApp;
  params.trusted_source = true;
  return params;
}

///////////////////////////////////////////////////////////////////////////////
// Browser, Constructors, Creation, Showing:

// static
BrowserWindowInterface::CreationStatus Browser::GetCreationStatusForProfile(
    Profile* profile) {
  return GetBrowserWindowCreationStatusForProfile(*profile);
}

// static
Browser* Browser::Create(const CreateParams& params) {
  // If this is failing, a caller is trying to create a browser when creation is
  // not possible, e.g. using the wrong profile or during shutdown. The caller
  // should handle this; see e.g. crbug.com/1141608 and crbug.com/1261628.
  CHECK_EQ(CreationStatus::kOk, GetCreationStatusForProfile(params.profile));

  std::unique_ptr<Browser> browser = base::WrapUnique(new Browser(params));
  Browser* const browser_ptr = browser.get();
  BrowserManagerServiceFactory::GetForProfile(params.profile)
      ->AddBrowser(std::move(browser));
  return browser_ptr;
}

// static
std::unique_ptr<Browser> Browser::DeprecatedCreateOwnedForTesting(
    const CreateParams& params) {
  CHECK_IS_TEST();
  // If this is failing, a caller is trying to create a browser when creation is
  // not possible, e.g. using the wrong profile or during shutdown. The caller
  // should handle this; see e.g. crbug.com/1141608 and crbug.com/1261628.
  CHECK_EQ(CreationStatus::kOk, GetCreationStatusForProfile(params.profile));
  return base::WrapUnique(new Browser(params));
}

Browser::Browser(const CreateParams& params)
    : create_params_(params),
      type_(params.type),
      profile_(params.profile),
      window_(nullptr),
      tab_strip_model_delegate_(
          std::make_unique<chrome::BrowserTabStripModelDelegate>(this)),
      tab_strip_model_(std::make_unique<TabStripModel>(
          tab_strip_model_delegate_.get(),
          params.profile,
          // Tab groups are disabled for app browsers.
          (type_ == TYPE_APP || type_ == TYPE_APP_POPUP)
              ? nullptr
              : TabGroupModelFactory::GetInstance())),
      app_name_(params.app_name),
      is_trusted_source_(params.trusted_source),
      session_id_(SessionID::NewUnique()),
      omit_from_session_restore_(params.omit_from_session_restore),
      should_trigger_session_restore_(params.should_trigger_session_restore),
      cancel_download_confirmation_state_(
          CancelDownloadConfirmationState::kNotPrompted),
      override_bounds_(params.initial_bounds),
      initial_show_state_(params.initial_show_state),
      initial_workspace_(params.initial_workspace),
      initial_visible_on_all_workspaces_state_(
          params.initial_visible_on_all_workspaces_state),
      creation_source_(params.creation_source),
      unload_controller_(this),
      window_has_shown_(false),
      user_title_(params.user_title),
      initial_vertical_tab_strip_collapsed_(
          params.vertical_tab_strip_collapsed),
      initial_vertical_tab_strip_uncollapsed_width_(
          params.vertical_tab_strip_uncollapsed_width) {
  if (!profile_->IsOffTheRecord()) {
    profile_keep_alive_ = std::make_unique<ScopedProfileKeepAlive>(
        params.profile->GetOriginalProfile(),
        ProfileKeepAliveOrigin::kBrowserWindow);
  }

  tab_strip_model_->AddObserver(this);

  ThemeServiceFactory::GetForProfile(profile_)->AddObserver(this);

  profile_pref_registrar_.Init(profile_->GetPrefs());
  profile_pref_registrar_.Add(
      prefs::kDevToolsAvailability,
      base::BindRepeating(&Browser::OnDevToolsAvailabilityChanged,
                          base::Unretained(this)));

  ProfileMetrics::LogProfileLaunch(profile_);

  if (params.skip_window_init_for_testing) {
    // This is as initialized as the window will ever get.
    is_initialized_ = true;
    return;
  }

  // BrowserWindowFeatures need to be initialized before browser window
  // creation, so that the features can be used in creating components
  // in browser window.
  features_ = std::make_unique<BrowserWindowFeatures>();
  features_->Init(this);

  SessionServiceBase* session_service =
      GetAppropriateSessionServiceForSessionRestore(this);
#if BUILDFLAG(IS_OZONE)
  if (session_service && session_service->GetPlatformSessionId()) {
    platform_session_data_ = ui::PlatformSessionWindowData{
        .session_id = session_service->GetPlatformSessionId().value(),
        .window_id = session_id_.id(),
        .restore_id = params.restore_id > Browser::kDefaultRestoreId
                          ? std::optional<int32_t>(params.restore_id)
                          : std::nullopt};
  }
#endif  // BUILDFLAG(IS_OZONE)

  if (params.window) {
    CHECK_IS_TEST() << "Browser::CreateParams::window is a test-only param";
  }
  window_ =
      params.window
          ? std::unique_ptr<BrowserWindow, BrowserWindowDeleter>(params.window)
          : BrowserWindow::CreateBrowserWindow(this, params.user_gesture,
                                               params.in_tab_dragging);

  if (auto* const app_browser_controller = app_controller()) {
    app_browser_controller->UpdateCustomTabBarVisibility(false);
  }

  if (session_service) {
    session_service->WindowOpened(this);
  }

  // Initialize the browser features that rely on the browser window now that it
  // is initialized.
  features_->InitPostWindowConstruction(this);

  // All initialization is complete; after this point, the browser should be on
  // the browser list until it is marked for destruction.
  is_initialized_ = true;

  BrowserList::AddBrowser(this);
}

Browser::~Browser() {
  if (!is_delete_scheduled_) {
    // Guarantee the Browser has performed the necessary cleanup in the
    // `OnWindowClosing()` lifecycle hook. This may not be invoked during
    // Browser shutdown specifically in cases where clients directly reset
    // the Browser unique_ptr.
    force_skip_warning_user_on_close_ = true;
    OnWindowClosing();
  }

  BrowserList::RemoveBrowser(this);
  window_.reset();

  // Tear down `BrowserWindowFeatures` to avoid exposing it to Browser in a
  // partially-destroyed state.
  features_.reset();

  // Stop observing notifications and destroy the tab monitor before continuing
  // with destruction. Profile destruction will unload extensions and reentrant
  // calls to Browser:: should be avoided while it is being torn down.
  ThemeServiceFactory::GetForProfile(profile_)->RemoveObserver(this);

  // The tab strip should not have any tabs at this point.
  //
  // TODO(crbug.com/40887606): This DCHECK doesn't always pass.
  // TODO(crbug.com/40064092): convert this to CHECK.
  DCHECK(tab_strip_model_->empty());

  // If closing the window is going to trigger a shutdown, then we need to
  // schedule all active downloads to be cancelled. This needs to be after
  // removing |this| from BrowserList so that OkToClose...() can determine
  // whether there are any other windows open for the browser.
  int num_downloads;
  if (!browser_defaults::kBrowserAliveWithNoWindows &&
      OkToCloseWithInProgressDownloads(&num_downloads) ==
          DownloadCloseType::kBrowserShutdown) {
    DownloadCoreService::CancelAllDownloads(
        DownloadCoreService::CancelDownloadsTrigger::kShutdown);
  }

  SessionServiceBase* service = GetAppropriateSessionServiceForProfile(this);

  if (service) {
    service->WindowClosed(session_id_);
  }

  profile_pref_registrar_.Reset();

  // The system incognito profile should not try be destroyed using
  // ProfileDestroyer::DestroyProfileWhenAppropriate(). This profile can be
  // used, at least, by the user manager window. This window is not a browser,
  // therefore, BrowserList::IsOffTheRecordBrowserActiveForProfile(profile_)
  // returns false, while the user manager window is still opened.
  // This cannot be fixed in ProfileDestroyer::DestroyProfileWhenAppropriate(),
  // because the ProfileManager needs to be able to destroy all profiles when
  // it is destroyed. See crbug.com/527035
  //
  // Non-primary OffTheRecord profiles should not be destroyed directly by
  // Browser (e.g. for offscreen tabs, https://crbug.com/664351).
  //
  // TODO(crbug.com/40159237): Use ScopedProfileKeepAlive for Incognito too,
  // instead of separate logic for Incognito and regular profiles.
  if (profile_->IsIncognitoProfile() &&
      !BrowserList::IsOffTheRecordBrowserInUse(profile_) &&
      !profile_->IsSystemProfile()) {
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
    // The Printing Background Manager holds onto preview dialog WebContents
    // whose corresponding print jobs have not yet fully spooled. Make sure
    // these get destroyed before tearing down the incognito profile so that
    // their RenderFrameHosts can exit in time - see crbug.com/579155
    g_browser_process->background_printing_manager()
        ->DeletePreviewContentsForBrowserContext(profile_);
#endif
    // An incognito profile is no longer needed, this indirectly frees
    // its cache and cookies once it gets destroyed at the appropriate time.
    ProfileDestroyer::DestroyOTRProfileWhenAppropriate(profile_);
  }
}

///////////////////////////////////////////////////////////////////////////////
// Getters & Setters

BrowserView& Browser::GetBrowserView() {
  return CHECK_DEREF(window_->AsBrowserView());
}

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

base::WeakPtr<const Browser> Browser::AsWeakPtr() const {
  return weak_factory_.GetWeakPtr();
}

///////////////////////////////////////////////////////////////////////////////
// Browser, State Storage and Retrieval for UI:

GURL Browser::GetNewTabURL() const {
  if (auto* const app_browser_controller = app_controller()) {
    return app_browser_controller->GetAppNewTabUrl();
  }
  return GURL(chrome::kChromeUINewTabURL);
}

gfx::Image Browser::GetCurrentPageIcon() const {
  WebContents* web_contents = tab_strip_model_->GetActiveWebContents();
  // |web_contents| can be NULL since GetCurrentPageIcon() is called by the
  // window during the window's creation (before tabs have been added).
  favicon::FaviconDriver* favicon_driver =
      web_contents
          ? favicon::ContentFaviconDriver::FromWebContents(web_contents)
          : nullptr;
  return favicon_driver ? favicon_driver->GetFavicon() : gfx::Image();
}

std::u16string Browser::GetWindowTitleForCurrentTab(
    bool include_app_name) const {
  if (!user_title_.empty()) {
    return base::UTF8ToUTF16(user_title_);
  }

  // For document picture-in-picture windows, we use the title from the opener
  // WebContents instead of the picture-in-picture WebContents itself.
  content::WebContents* web_contents_for_title =
      is_type_picture_in_picture()
          ? PictureInPictureWindowManager::GetInstance()->GetWebContents()
          : tab_strip_model_->GetActiveWebContents();

  return GetWindowTitleFromWebContents(include_app_name,
                                       web_contents_for_title);
}

std::u16string Browser::GetWindowTitleForTab(int index) const {
  std::u16string title = base::UTF8ToUTF16(user_title_);

  if (title.empty()) {
    title = tab_strip_model_->GetWebContentsAt(index)->GetTitle();
    if (is_type_picture_in_picture()) {
      content::WebContents* pip_web_contents =
          PictureInPictureWindowManager::GetInstance()->GetWebContents();
      if (pip_web_contents) {
        title = pip_web_contents->GetTitle();
      }
    }
    title = FormatTitleForDisplay(title);
  }

  if (title.empty() && (is_type_normal() || is_type_popup())) {
    title = CoreTabHelper::GetDefaultTitle();
  }

  return title;
}

std::u16string Browser::GetTitleForTab(int index) const {
  std::u16string title = FormatTitleForDisplay(
      tab_strip_model_->GetWebContentsAt(index)->GetTitle());

  if (title.empty()) {
    title = CoreTabHelper::GetDefaultTitle();
  }

  return title;
}

std::u16string Browser::GetWindowTitleForMaxWidth(int max_width) const {
  static constexpr unsigned int kMinTitleCharacters = 4;
  const gfx::FontList font_list;

  if (!user_title_.empty()) {
    std::u16string title = base::UTF8ToUTF16(user_title_);
    std::u16string pixel_elided_title = gfx::ElideText(
        title, font_list, max_width, gfx::ElideBehavior::ELIDE_TAIL);
    std::u16string character_elided_title =
        gfx::TruncateString(title, kMinTitleCharacters, gfx::CHARACTER_BREAK);
    return pixel_elided_title.size() > character_elided_title.size()
               ? pixel_elided_title
               : character_elided_title;
  }

  const auto num_more_tabs = tab_strip_model_->count() - 1;
  const std::u16string format_string = l10n_util::GetPluralStringFUTF16(
      IDS_BROWSER_WINDOW_TITLE_MENU_ENTRY, num_more_tabs);

  // First, format with an empty string to see how much space we have available.
  std::u16string temp_window_title =
      base::ReplaceStringPlaceholders(format_string, std::u16string(), nullptr);
  int width = max_width - GetStringWidth(temp_window_title, font_list);

  std::u16string title;
  content::WebContents* contents = tab_strip_model_->GetActiveWebContents();
  // |contents| can be NULL if GetWindowTitleForMenu is called during the
  // window's creation (before tabs have been added).
  if (contents) {
    auto* const app_browser_controller = app_controller();
    title = FormatTitleForDisplay(app_browser_controller
                                      ? app_browser_controller->GetTitle()
                                      : contents->GetTitle());
  }

  // If there is no title, leave it empty for apps.
  if (title.empty() && (is_type_normal() || is_type_popup())) {
    title = CoreTabHelper::GetDefaultTitle();
  }

  // Try to elide the title to fit the pixel width. If that will make the title
  // shorter than the minimum character limit, use a character elided title
  // instead.
  std::u16string pixel_elided_title =
      gfx::ElideText(title, font_list, width, gfx::ElideBehavior::ELIDE_TAIL);
  std::u16string character_elided_title =
      gfx::TruncateString(title, kMinTitleCharacters, gfx::CHARACTER_BREAK);
  title = pixel_elided_title.size() > character_elided_title.size()
              ? pixel_elided_title
              : character_elided_title;

  // Finally, add the page title.
  return base::ReplaceStringPlaceholders(format_string, title, nullptr);
}

std::u16string Browser::GetWindowTitleFromWebContents(
    bool include_app_name,
    content::WebContents* contents) const {
  std::u16string title = base::UTF8ToUTF16(user_title_);

  // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
  // window during the window's creation (before tabs have been added).
  if (title.empty() && contents) {
    auto* const app_browser_controller = app_controller();
    title = FormatTitleForDisplay(app_browser_controller
                                      ? app_browser_controller->GetTitle()
                                      : contents->GetTitle());
#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
    // If the app name is requested and this is a captive portal window, the
    // title should indicate that this is a captive portal window. Captive
    // portal windows should always be pop-ups, and the is_captive_portal_window
    // condition should not change over the lifetime of a WebContents.
    if (include_app_name &&
        captive_portal::CaptivePortalTabHelper::FromWebContents(contents) &&
        captive_portal::CaptivePortalTabHelper::FromWebContents(contents)
            ->is_captive_portal_window()) {
      DCHECK(is_type_popup());
      return l10n_util::GetStringFUTF16(
          IDS_CAPTIVE_PORTAL_BROWSER_WINDOW_TITLE_FORMAT,
          title.empty() ? CoreTabHelper::GetDefaultTitle() : title);
    }
#endif
  }

  // If there is no title, leave it empty for apps.
  if (title.empty() && (is_type_normal() || is_type_popup())) {
    title = CoreTabHelper::GetDefaultTitle();
  }

#if BUILDFLAG(IS_MAC)
  // On Mac, we don't want to suffix the page title with the application name.
  return title;
#else
  // If there is no title and this is an app, fall back on the app name. This
  // ensures that the native window gets a title which is important for a11y,
  // for example the window selector uses the Aura window title.
  if (title.empty() &&
      (is_type_app() || is_type_app_popup() || is_type_devtools()) &&
      include_app_name) {
    auto* const app_browser_controller = app_controller();
    return app_browser_controller ? app_browser_controller->GetAppShortName()
                                  : base::UTF8ToUTF16(app_name());
  }
  // Include the app name in window titles for tabbed browser windows when
  // requested with |include_app_name|.
  return ((is_type_normal() || is_type_popup()) && include_app_name)
             ? l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT,
                                          title)
             : title;
#endif  // BUILDFLAG(IS_MAC)
}

// static
std::u16string Browser::FormatTitleForDisplay(std::u16string title) {
  size_t current_index = 0;
  size_t match_index;
  while ((match_index = title.find(L'\n', current_index)) !=
         std::u16string::npos) {
    title.replace(match_index, 1, std::u16string());
    current_index = match_index;
  }

  return title;
}

///////////////////////////////////////////////////////////////////////////////
// Browser, OnBeforeUnload handling:

Browser::WarnBeforeClosingResult Browser::MaybeWarnBeforeClosing(
    Browser::WarnBeforeClosingCallback warn_callback) {
  // If the browser can close right away (we've indicated that we want to skip
  // before-unload handlers by setting `force_skip_warning_user_on_close_` to
  // true or there are no pending downloads we need to prompt about) then
  // there's no need to warn.
  if (force_skip_warning_user_on_close_) {
    return WarnBeforeClosingResult::kOkToClose;
  }

  // `CanCloseWithInProgressDownloads()` may trigger a modal dialog.
  bool can_close_with_downloads = CanCloseWithInProgressDownloads();
  if (can_close_with_downloads &&
      !ShouldShowCookieMigrationNoticeForBrowser(*this)) {
    return WarnBeforeClosingResult::kOkToClose;
  }

  // If there is no download warning, show the cookie migration notice now.
  // Otherwise, the download warning is being shown. Cookie migration notice
  // will be shown after, if needed.
  if (can_close_with_downloads) {
    ShowCookieClearOnExitMigrationNotice(
        *this, base::BindOnce(&Browser::CookieMigrationNoticeResponse,
                              weak_factory_.GetWeakPtr()));
  }

  DCHECK(!warn_before_closing_callback_)
      << "Tried to close window during close warning; dialog should be modal.";
  warn_before_closing_callback_ = std::move(warn_callback);

  return WarnBeforeClosingResult::kDoNotClose;
}

bool Browser::HandleBeforeClose() {
  const auto get_closing_status =
      [this]() -> BrowserWindowInterface::ClosingStatus {
    // If `force_skip_warning_user_` is true, then we should immediately
    // return true.
    if (force_skip_warning_user_on_close_) {
      return BrowserWindowInterface::ClosingStatus::kPermitted;
    }

    // If the user needs to see one or more warnings, hold off closing the
    // browser.
    const WarnBeforeClosingResult result =
        MaybeWarnBeforeClosing(base::BindOnce(&Browser::FinishWarnBeforeClosing,
                                              weak_factory_.GetWeakPtr()));
    if (result == WarnBeforeClosingResult::kDoNotClose) {
      return BrowserWindowInterface::ClosingStatus::kDeniedByUser;
    }

    return unload_controller_.GetBrowserClosingStatus();
  };

  // Notify clients if close was cancelled.
  const BrowserWindowInterface::ClosingStatus close_status =
      get_closing_status();
  const bool close_permitted =
      close_status == BrowserWindowInterface::ClosingStatus::kPermitted;
  if (!close_permitted) {
    browser_close_cancelled_callback_list_.Notify(this, close_status);
  }
  return close_permitted;
}

bool Browser::TryToCloseWindow(
    bool skip_beforeunload,
    const base::RepeatingCallback<void(bool)>& on_close_confirmed) {
  cancel_download_confirmation_state_ =
      CancelDownloadConfirmationState::kResponseReceived;
  return unload_controller_.TryToCloseWindow(skip_beforeunload,
                                             on_close_confirmed);
}

void Browser::ResetTryToCloseWindow() {
  cancel_download_confirmation_state_ =
      CancelDownloadConfirmationState::kNotPrompted;
  unload_controller_.ResetTryToCloseWindow();
}

bool Browser::IsAttemptingToCloseBrowser() const {
  return unload_controller_.is_attempting_to_close_browser();
}

bool Browser::ShouldRunUnloadListenerBeforeClosing(
    content::WebContents* web_contents) {
  return !force_skip_warning_user_on_close_ &&
         unload_controller_.ShouldRunUnloadEventsHelper(web_contents);
}

bool Browser::RunUnloadListenerBeforeClosing(
    content::WebContents* web_contents) {
  return !force_skip_warning_user_on_close_ &&
         unload_controller_.RunUnloadEventsHelper(web_contents);
}

void Browser::SetWindowUserTitle(const std::string& user_title) {
  user_title_ = user_title;
  window_->UpdateTitleBar();
  // See comment in Browser::OnTabGroupChanged
  DCHECK(!IsRelevantToAppSessionService(type_));
  SessionService* const session_service =
      SessionServiceFactory::GetForProfile(profile_);
  if (session_service) {
    session_service->SetWindowUserTitle(session_id(), user_title);
  }
}

Browser* Browser::GetBrowserForOpeningWebUi() {
  if (!is_type_picture_in_picture()) {
    return this;
  }

  if (!opener_browser_) {
    auto* opener_web_contents =
        PictureInPictureWindowManager::GetInstance()->GetWebContents();
    // We should always have an opener web contents if the current browser is a
    // picture-in-picture type.
    DCHECK(opener_web_contents);
    opener_browser_ = chrome::FindBrowserWithTab(opener_web_contents);
  }

  return opener_browser_;
}

std::vector<StatusBubble*> Browser::GetStatusBubblesForTesting() {
  return GetStatusBubbles();
}

Profile* Browser::GetProfile() {
  return profile();
}

const Profile* Browser::GetProfile() const {
  return profile();
}

void Browser::OpenGURL(const GURL& gurl, WindowOpenDisposition disposition) {
  OpenURL(content::OpenURLParams(gurl, content::Referrer(), disposition,
                                 ui::PAGE_TRANSITION_LINK,
                                 /*is_renderer_initiated=*/false),
          /*navigation_handle_callback=*/{});
}

const SessionID& Browser::GetSessionID() const {
  return session_id_;
}

TabStripModel* Browser::GetTabStripModel() {
  return tab_strip_model_.get();
}

const TabStripModel* Browser::GetTabStripModel() const {
  return tab_strip_model_.get();
}

bool Browser::IsTabStripVisible() {
  return window_ && window_->IsToolbarShowing();
}

bool Browser::ShouldHideUIForFullscreen() const {
  // Windows and GTK remove the browser controls in fullscreen, but Mac and Ash
  // keep the controls in a slide-down panel.
  return window_ && window_->ShouldHideUIForFullscreen();
}

base::CallbackListSubscription Browser::RegisterBrowserDidClose(
    BrowserDidCloseCallback callback) {
  return browser_did_close_callback_list_.Add(std::move(callback));
}

base::CallbackListSubscription Browser::RegisterBrowserCloseCancelled(
    BrowserCloseCancelledCallback callback) {
  return browser_close_cancelled_callback_list_.Add(std::move(callback));
}

base::WeakPtr<BrowserWindowInterface> Browser::GetWeakPtr() {
  return AsWeakPtr();
}

base::CallbackListSubscription Browser::RegisterActiveTabDidChange(
    ActiveTabChangeCallback callback) {
  return did_active_tab_change_callback_list_.Add(std::move(callback));
}

tabs::TabInterface* Browser::GetActiveTabInterface() {
  return tab_strip_model_->GetActiveTab();
}

BrowserWindowFeatures& Browser::GetFeatures() {
  return *features_.get();
}

const BrowserWindowFeatures& Browser::GetFeatures() const {
  return *features_.get();
}

ui::UnownedUserDataHost& Browser::GetUnownedUserDataHost() {
  return unowned_user_data_host_;
}

const ui::UnownedUserDataHost& Browser::GetUnownedUserDataHost() const {
  return unowned_user_data_host_;
}

web_modal::WebContentsModalDialogHost*
Browser::GetWebContentsModalDialogHostForWindow() {
  return window_->GetWebContentsModalDialogHost();
}

web_modal::WebContentsModalDialogHost*
Browser::GetWebContentsModalDialogHostForTab(
    tabs::TabInterface* tab_interface) {
  return GetWebContentsModalDialogHost(tab_interface->GetContents());
}

bool Browser::IsActive() const {
// TODO(https://crbug.com/376306245): This is a temporary workaround for the
// fact that window_->IsActive() does not return the right result for macOS
// standalone PWA windows. This new behavior is still not technically correct,
// since it's checking that the last active window is `this`, as opposed to
// whether `this` is active.
#if BUILDFLAG(IS_MAC)
  // If this is a standalone PWA window, check BrowserList instead.
  if (app_controller()) {
    return GetLastActiveBrowserWindowInterfaceWithAnyProfile() == this;
  }
#endif
  return is_active_;
}

base::CallbackListSubscription Browser::RegisterDidBecomeActive(
    DidBecomeActiveCallback callback) {
  return did_become_active_callback_list_.Add(std::move(callback));
}

base::CallbackListSubscription Browser::RegisterDidBecomeInactive(
    DidBecomeInactiveCallback callback) {
  return did_become_inactive_callback_list_.Add(std::move(callback));
}

void Browser::SynchronouslyDestroyBrowser() {
  // TODO(crbug.com/413168662): Eliminate the need for BrowserCloseManager to
  // call this directly, instead allow Browsers to be destroyed by their owning
  // BrowserManagerService at shutdown.
  BrowserManagerServiceFactory::GetForProfile(profile())->DeleteBrowser(this);
  // `this` is no longer valid from this point forward.
}

ExclusiveAccessManager* Browser::GetExclusiveAccessManager() {
  return GetFeatures().exclusive_access_manager();
}

BrowserActions* Browser::GetActions() {
  return GetFeatures().browser_actions();
}

BrowserWindowInterface::Type Browser::GetType() const {
  return type_;
}

web_app::AppBrowserController* Browser::app_controller() {
  return web_app::AppBrowserController::From(this);
}

const web_app::AppBrowserController* Browser::app_controller() const {
  return web_app::AppBrowserController::From(this);
}

std::vector<tabs::TabInterface*> Browser::GetAllTabInterfaces() {
  std::vector<tabs::TabInterface*> results;
  results.reserve(tab_strip_model_->count());
  for (tabs::TabInterface* tab : *tab_strip_model_) {
    results.push_back(tab);
  }
  return results;
}

Browser* Browser::GetBrowserForMigrationOnly() {
  return this;
}

const Browser* Browser::GetBrowserForMigrationOnly() const {
  return this;
}

bool Browser::IsTabModalPopupDeprecated() const {
  return is_tab_modal_popup_deprecated_;
}

bool Browser::CanShowCallToAction() const {
  return !showing_call_to_action_;
}

std::unique_ptr<ScopedWindowCallToAction> Browser::ShowCallToAction() {
  return std::make_unique<ScopedWindowCallToActionImpl>(this);
}

ui::BaseWindow* Browser::GetWindow() {
  return window_.get();
}

const ui::BaseWindow* Browser::GetWindow() const {
  return window_.get();
}

DesktopBrowserWindowCapabilities* Browser::capabilities() {
  return DesktopBrowserWindowCapabilities::From(this);
}

const DesktopBrowserWindowCapabilities* Browser::capabilities() const {
  return DesktopBrowserWindowCapabilities::From(this);
}

void Browser::DidBecomeActive() {
  if (!is_active_) {
    is_active_ = true;
    BrowserList::SetLastActive(this);
    did_become_active_callback_list_.Notify(this);
  }
}

void Browser::DidBecomeInactive() {
  if (is_active_) {
    is_active_ = false;
    BrowserList::NotifyBrowserNoLongerActive(this);
    did_become_inactive_callback_list_.Notify(this);
  }
}

#if BUILDFLAG(IS_CHROMEOS)
bool Browser::IsLockedForOnTask() {
  return on_task_locked_;
}

void Browser::SetLockedForOnTask(bool locked) {
  on_task_locked_ = locked;
  GetBrowserView().OnLockedForOnTaskUpdated();
}
#endif

void Browser::OnWindowClosing() {
  // There may be situations where async tasks, such as
  // UnloadController::ProcessPendingTabs, may call into OnWindowClosing() after
  // deletion has already been scheduled and closed notifications have been
  // propagated. No-op in such cases to avoid duplicating browser-closed
  // handling.
  if (is_delete_scheduled_) {
    return;
  }

  if (!HandleBeforeClose()) {
    return;
  }

  // Don't use GetForProfileIfExisting here, we want to force creation of the
  // session service so that user can restore what was open.
  SessionServiceBase* service = GetAppropriateSessionServiceForProfile(this);

  if (service) {
    service->WindowClosing(session_id());
  }

  sessions::TabRestoreService* tab_restore_service =
      TabRestoreServiceFactory::GetForProfile(profile());

  bool notify_restore_service = is_type_normal() && tab_strip_model_->count();
#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
  notify_restore_service |= is_type_app() || is_type_app_popup();
#endif

  if (tab_restore_service && notify_restore_service) {
    tab_restore_service->BrowserClosing(GetFeatures().live_tab_context());
  }

  if (!tab_strip_model_->empty()) {
    // Closing all the tabs results in eventually calling back to
    // OnWindowClosing() again.
    tab_strip_model_->CloseAllTabs();
  } else {
    // If there are no tabs, then a task will be scheduled (by views) to delete
    // this Browser.
    is_delete_scheduled_ = true;

    // Application should shutdown on last window close if the user is
    // explicitly trying to quit, or if there is nothing keeping the browser
    // alive (such as AppController on the Mac, or BackgroundContentsService for
    // background pages).
    const bool should_quit_if_last_browser =
        browser_shutdown::IsTryingToQuit() ||
        KeepAliveRegistry::GetInstance()->IsKeepingAliveOnlyByBrowserOrigin();

    // Below will not consider browsers for which delete has already been
    // scheduled.
    const bool is_last_browser =
        !GetLastActiveBrowserWindowInterfaceWithAnyProfile();

    if (should_quit_if_last_browser && is_last_browser) {
      browser_shutdown::OnShutdownStarting(
          browser_shutdown::ShutdownType::kWindowClose);
    }

    // At this point the browser has successfully closed and is scheduled for
    // deletion.
    browser_did_close_callback_list_.Notify(this);

    // Once a Browser has successfully closed, client code expects control to
    // return to the run loop before the instance is finally deleted. To
    // maintain existing expectations schedule the delete asynchronously here.
    // TODO(crbug.com/413168662): Explore synchronously destroying the browser
    // instead.
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(&Browser::SynchronouslyDestroyBrowser,
                                  weak_factory_.GetWeakPtr()));
  }
}

////////////////////////////////////////////////////////////////////////////////
// In-progress download termination handling:

Browser::DownloadCloseType Browser::OkToCloseWithInProgressDownloads(
    int* num_downloads_blocking) const {
  DCHECK(num_downloads_blocking);
  *num_downloads_blocking = 0;

  // If we're not running a full browser process with a profile manager
  // (testing), it's ok to close the browser.
  if (!g_browser_process->profile_manager()) {
    return DownloadCloseType::kOk;
  }

  int total_download_count =
      DownloadCoreService::BlockingShutdownCountAllProfiles();
  if (total_download_count == 0) {
    return DownloadCloseType::kOk;  // No downloads; can definitely close.
  }

  // Figure out how many windows are open total, and associated with this
  // profile, that are relevant for the ok-to-close decision.
  auto [last_window, last_window_for_profile] = IsLastWindow(*this);

  // If there aren't any other windows, we're at browser shutdown,
  // which would cancel all current downloads.
  if (last_window) {
    *num_downloads_blocking = total_download_count;
    return DownloadCloseType::kBrowserShutdown;
  }

  // If there aren't any other windows on our profile, and we're an Incognito
  // or Guest profile, and there are downloads associated with that profile,
  // those downloads would be cancelled by our window (-> profile) close.
  DownloadCoreService* download_core_service =
      DownloadCoreServiceFactory::GetForBrowserContext(profile());
  if (last_window_for_profile &&
      (download_core_service->BlockingShutdownCount() > 0) &&
      (profile()->IsIncognitoProfile() || profile()->IsGuestSession())) {
    *num_downloads_blocking = download_core_service->BlockingShutdownCount();
    return profile()->IsGuestSession()
               ? DownloadCloseType::kLastWindowInGuestSession
               : DownloadCloseType::kLastWindowInIncognitoProfile;
  }

  // Those are the only conditions under which we will block shutdown.
  return DownloadCloseType::kOk;
}

////////////////////////////////////////////////////////////////////////////////
// Browser, Tab adding/showing functions:

void Browser::WindowFullscreenStateChanged() {
  browser_window_features()
      ->exclusive_access_manager()
      ->fullscreen_controller()
      ->WindowFullscreenStateChanged();
  GetCommandController()->FullscreenStateChanged();
  BookmarkBarController::From(this)->UpdateBookmarkBarState(
      BookmarkBarController::StateChangeReason::kToggleFullscreen);
}

void Browser::FullscreenTopUIStateChanged() {
  GetCommandController()->FullscreenStateChanged();
  BookmarkBarController::From(this)->UpdateBookmarkBarState(
      BookmarkBarController::StateChangeReason::kToolbarOptionChange);
}

void Browser::OnFindBarVisibilityChanged() {
  if (!IsPageActionMigrated(PageActionIconType::kFind)) {
    window()->UpdatePageActionIcon(PageActionIconType::kFind);
  } else {
    GetFeatures().GetFindBarController()->UpdatePageAction();
  }

  GetCommandController()->FindBarVisibilityChanged();
}

///////////////////////////////////////////////////////////////////////////////
// Browser, Assorted browser commands:

void Browser::ToggleFullscreenModeWithExtension(const GURL& extension_url) {
  browser_window_features()
      ->exclusive_access_manager()
      ->fullscreen_controller()
      ->ToggleBrowserFullscreenModeWithExtension(extension_url);
}

bool Browser::SupportsWindowFeature(WindowFeature feature) const {
  bool supports =
      SupportsWindowFeatureImpl(feature, /*check_can_support=*/false);
  // Supported features imply CanSupportWindowFeature.
  DCHECK(!supports || CanSupportWindowFeature(feature));
  return supports;
}

bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
  return SupportsWindowFeatureImpl(feature, /*check_can_support=*/true);
}

void Browser::OpenFile() {
  GetFeatures().browser_select_file_dialog_controller()->OpenFile(
      tab_strip_model_->GetActiveWebContents(), window_->GetNativeWindow(),
      base::BindOnce(&Browser::OnFileSelectedFromDialog, AsWeakPtr()));
}

bool Browser::CanSaveContents(content::WebContents* web_contents) const {
  return chrome::CanSavePage(this);
}

bool Browser::ShouldDisplayFavicon(content::WebContents* web_contents) const {
  // Remove for all other tabbed web apps.
  if (auto* const app_browser_controller = app_controller();
      app_browser_controller && app_browser_controller->has_tab_strip()) {
    return false;
  }

  // Otherwise, always display the favicon.
  return true;
}

///////////////////////////////////////////////////////////////////////////////

void Browser::UpdateUIForNavigationInTab(WebContents* contents,
                                         ui::PageTransition transition,
                                         NavigateParams::WindowAction action,
                                         bool user_initiated) {
  tab_strip_model_->TabNavigating(contents, transition);

  bool contents_is_selected =
      contents == tab_strip_model_->GetActiveWebContents();
  if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
    // Forcibly reset the location bar if the url is going to change in the
    // current tab, since otherwise it won't discard any ongoing user edits,
    // since it doesn't realize this is a user-initiated action.
    window()->GetLocationBar()->Revert();
  }

  std::vector<StatusBubble*> status_bubbles = GetStatusBubbles();
  for (StatusBubble* status_bubble : status_bubbles) {
    status_bubble->Hide();
  }

  // Update the location bar. This is synchronous. We specifically don't
  // update the load state since the load hasn't started yet and updating it
  // will put it out of sync with the actual state like whether we're
  // displaying a favicon, which controls the throbber. If we updated it here,
  // the throbber will show the default favicon for a split second when
  // navigating away from the new tab page.
  ScheduleUIUpdate(contents, content::INVALIDATE_TYPE_URL);

  // Navigating contents can take focus (potentially taking it away from other,
  // currently-focused UI element like the omnibox) if the navigation was
  // initiated by the user (e.g., via omnibox, bookmarks, etc.).
  //
  // Note that focusing contents of NTP-initiated navigations is taken care of
  // elsewhere - see FocusTabAfterNavigationHelper.
  if (user_initiated && contents_is_selected &&
      (window()->IsActive() ||
       action == NavigateParams::WindowAction::kShowWindow)) {
    contents->SetInitialFocus();
  }
}

void Browser::RegisterKeepAlive() {
  keep_alive_ = std::make_unique<ScopedKeepAlive>(
      KeepAliveOrigin::BROWSER, KeepAliveRestartOption::DISABLED);
}
void Browser::UnregisterKeepAlive() {
  keep_alive_.reset();
}

///////////////////////////////////////////////////////////////////////////////
// Browser, PageNavigator implementation:

WebContents* Browser::OpenURL(
    const OpenURLParams& params,
    base::OnceCallback<void(content::NavigationHandle&)>
        navigation_handle_callback) {
#if DCHECK_IS_ON()
  DCHECK(params.Valid());
#endif

  return OpenURLFromTab(nullptr, params, std::move(navigation_handle_callback));
}

///////////////////////////////////////////////////////////////////////////////
// Browser, TabStripModelObserver implementation:

void Browser::OnTabStripModelChanged(TabStripModel* tab_strip_model,
                                     const TabStripModelChange& change,
                                     const TabStripSelectionChange& selection) {
  TRACE_EVENT2("ui", "Browser::OnTabStripModelChanged", "tab_strip_model",
               tab_strip_model, "change", change);
  switch (change.type()) {
    case TabStripModelChange::kInserted: {
      // Initialize find bar controller when tab having active find session
      // is inserted in a new window.
      find_in_page::FindTabHelper* find_tab_helper =
          find_in_page::FindTabHelper::FromWebContents(selection.new_contents);
      if (!HasFindBarController() && find_tab_helper &&
          find_tab_helper->is_find_session_active()) {
        std::ignore = CreateOrGetFindBarController();
      }
      for (const auto& contents : change.GetInsert()->contents) {
        OnTabInsertedAt(contents.contents, contents.index);
      }
      break;
    }
    case TabStripModelChange::kRemoved: {
      for (const auto& contents : change.GetRemove()->contents) {
        if (contents.remove_reason ==
            TabStripModelChange::RemoveReason::kDeleted) {
          OnTabClosing(contents.contents);
        }
        OnTabDetached(contents.contents,
                      contents.contents == selection.old_contents);
      }
      break;
    }
    case TabStripModelChange::kMoved: {
      auto* move = change.GetMove();
      OnTabMoved(move->from_index, move->to_index);
      break;
    }
    case TabStripModelChange::kReplaced: {
      auto* replace = change.GetReplace();
      OnTabReplacedAt(replace->old_contents, replace->new_contents,
                      replace->index);
      break;
    }
    case TabStripModelChange::kSelectionOnly:
      break;
  }

  if (!selection.active_tab_changed()) {
    return;
  }

  if (selection.old_contents) {
    OnTabDeactivated(selection.old_contents);
  }

  if (tab_strip_model_->empty()) {
    return;
  }

  OnActiveTabChanged(
      selection.old_contents, selection.new_contents,
      selection.new_model.active().has_value()
          ? static_cast<int>(selection.new_model.active().value())
          : TabStripModel::kNoTab,
      selection.reason);
}

void Browser::OnTabGroupChanged(const TabGroupChange& change) {
  // If apps ever get tab grouping, this function needs to be updated to
  // retrieve AppSessionService from the correct factory. Additionally,
  // AppSessionService doesn't support SetTabGroupMetadata, so some
  // work to refactor the code to support that into SessionServiceBase
  // would be the best way to achieve that.
  DCHECK(!IsRelevantToAppSessionService(type_));
  DCHECK(tab_strip_model_->group_model());

  if (change.type == TabGroupChange::kVisualsChanged) {
    UpdateTabGroupSessionMetadata(this, change.group);
  } else if (change.type == TabGroupChange::kCreated &&
             change.GetCreateChange()->reason() ==
                 TabGroupChange::TabGroupCreationReason::
                     kInsertedFromAnotherTabstrip) {
    // When a detached group is inserted, we need to update the group of all the
    // corresponding detached tab in session service.
    for (tabs::TabInterface* tab :
         change.GetCreateChange()->GetDetachedTabs()) {
      UpdateTabGroupSessionDataForTab(tab, change.group);
    }
  } else if (change.type == TabGroupChange::kClosed &&
             change.GetCloseChange()->reason() ==
                 TabGroupChange::TabGroupClosureReason::kGroupClosed) {
    // When a group is detached, we do not need to add the information for all
    // the detached tabs in tab restore service.
    sessions::TabRestoreService* tab_restore_service =
        TabRestoreServiceFactory::GetForProfile(profile());
    if (tab_restore_service) {
      tab_restore_service->GroupClosed(change.group);
    }
  }
}

void Browser::TabPinnedStateChanged(TabStripModel* tab_strip_model,
                                    WebContents* contents,
                                    int index) {
  // See comment in Browser::OnTabGroupChanged
  DCHECK(!IsRelevantToAppSessionService(type_));
  SessionService* session_service =
      SessionServiceFactory::GetForProfileIfExisting(profile());
  if (session_service) {
    session_service->SetPinnedState(
        session_id(), sessions::SessionTabHelper::IdForTab(contents),
        tab_strip_model_->IsTabPinned(index));
  }
}

void Browser::TabGroupedStateChanged(
    TabStripModel* tab_strip_model,
    std::optional<tab_groups::TabGroupId> old_group,
    std::optional<tab_groups::TabGroupId> new_group,
    tabs::TabInterface* tab,
    int index) {
  UpdateTabGroupSessionDataForTab(tab, new_group);
}

void Browser::UpdateTabGroupSessionDataForTab(
    tabs::TabInterface* tab,
    std::optional<tab_groups::TabGroupId> group) {
  // See comment in Browser::OnTabGroupChanged
  DCHECK(!IsRelevantToAppSessionService(type_));
  SessionService* const session_service =
      SessionServiceFactory::GetForProfile(profile_);
  if (!session_service) {
    return;
  }

  session_service->SetTabGroup(
      session_id(), sessions::SessionTabHelper::IdForTab(tab->GetContents()),
      std::move(group));
}

void Browser::TabStripEmpty() {
  // Note: even though the tab strip is empty, the call to Close() may not
  // result in closing this Browser. This can happen in the case of closing
  // the last Browser with ongoing downloads.
  window_->Close();
}

void Browser::OnSplitTabChanged(const SplitTabChange& change) {
  switch (change.type) {
    case SplitTabChange::Type::kAdded: {
      for (std::pair<tabs::TabInterface*, int> split_tabs :
           change.GetAddedChange()->tabs()) {
        UpdateSplitTabSessionData(split_tabs.first, change.split_id);
      }

      UpdateSplitTabSessionVisualData(change.split_id);
      break;
    }

    case SplitTabChange::Type::kVisualsChanged: {
      // Update for resize from the handle is done from multicontent view
      // delegate.
      if (!GetBrowserView().multi_contents_view()->IsSplitResizing()) {
        UpdateSplitTabSessionVisualData(change.split_id);
      }
      break;
    }

    case SplitTabChange::Type::kContentsChanged: {
      // No need to do anything here since split is still present and no visual
      // information changed.
      break;
    }

    case SplitTabChange::Type::kRemoved: {
      for (std::pair<tabs::TabInterface*, int> split_tabs :
           change.GetRemovedChange()->tabs()) {
        UpdateSplitTabSessionData(split_tabs.first, std::nullopt);
      }
      break;
    }
  }
}

void Browser::UpdateSplitTabSessionData(
    tabs::TabInterface* tab,
    std::optional<split_tabs::SplitTabId> split_id) {
  DCHECK(!IsRelevantToAppSessionService(type_));
  SessionService* const session_service =
      SessionServiceFactory::GetForProfile(profile_);
  if (!session_service) {
    return;
  }

  session_service->SetSplitTab(
      session_id(), sessions::SessionTabHelper::IdForTab(tab->GetContents()),
      std::move(split_id));
}

void Browser::UpdateSplitTabSessionVisualData(
    const split_tabs::SplitTabId& split_id) {
  SessionService* const session_service =
      SessionServiceFactory::GetForProfile(profile());
  if (!session_service) {
    return;
  }

  const split_tabs::SplitTabVisualData* visual_data =
      tab_strip_model()->GetSplitData(split_id)->visual_data();
  session_service->SetSplitTabData(session_id(), split_id, visual_data);
}

void Browser::SetTopControlsShownRatio(content::WebContents* web_contents,
                                       float ratio) {
  window_->SetTopControlsShownRatio(web_contents, ratio);
}

int Browser::GetTopControlsHeight() {
  return window_->GetTopControlsHeight();
}

bool Browser::DoBrowserControlsShrinkRendererSize(
    content::WebContents* contents) {
  return window_->DoBrowserControlsShrinkRendererSize(contents);
}

int Browser::GetVirtualKeyboardHeight(content::WebContents* contents) {
  // This API is currently only used by View Transitions when the virtual
  // keyboard resizes content.  On desktop platforms, the virtual keyboard can
  // only inset the visual viewport so it shouldn't ever be called.
  NOTIMPLEMENTED();
  return 0;
}

void Browser::SetTopControlsGestureScrollInProgress(bool in_progress) {
  window_->SetTopControlsGestureScrollInProgress(in_progress);
}

bool Browser::CanOverscrollContent() {
#if defined(USE_AURA)
  return GetFeatures().overscroll_pref_manager()->CanOverscrollContent();
#else
  return false;
#endif
}

bool Browser::ShouldPreserveAbortedURLs(WebContents* source) {
  // Allow failed URLs to stick around in the omnibox on the NTP, but not when
  // other pages have committed.
  Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
  if (!profile || !source->GetController().GetLastCommittedEntry()) {
    return false;
  }
  GURL committed_url(source->GetController().GetLastCommittedEntry()->GetURL());
  return search::IsNTPOrRelatedURL(committed_url, profile);
}

void Browser::SetFocusToLocationBar() {
  // Two differences between this and FocusLocationBar():
  // (1) This doesn't get recorded in user metrics, since it's called
  //     internally.
  // (2) This is called with |is_user_initiated| == false, because this is a
  //     renderer initiated focus (this method is a WebContentsDelegate
  //     override).
  window_->SetFocusToLocationBar(false);
}

void Browser::PreHandleDragUpdate(const content::DropData& drop_data,
                                  const gfx::PointF& client_pt) {
  window()->PreHandleDragUpdate(drop_data, client_pt);
}

void Browser::PreHandleDragExit() {
  window()->PreHandleDragExit();
}

void Browser::HandleDragEnded() {
  window()->HandleDragEnded();
}

content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent(
    content::WebContents* source,
    const NativeWebKeyboardEvent& event) {
  // Forward keyboard events to the manager for fullscreen / mouse lock. This
  // may consume the event (e.g., Esc exits fullscreen mode).
  // TODO(koz): Write a test for this http://crbug.com/100441.
  if (browser_window_features()->exclusive_access_manager()->HandleUserKeyEvent(
          event)) {
    return content::KeyboardEventProcessingResult::HANDLED;
  }

  return window()->PreHandleKeyboardEvent(event);
}

bool Browser::HandleKeyboardEvent(content::WebContents* source,
                                  const NativeWebKeyboardEvent& event) {
  DevToolsWindow* devtools_window =
      DevToolsWindow::GetInstanceForInspectedWebContents(source);
  return (devtools_window && devtools_window->ForwardKeyboardEvent(event)) ||
         window()->HandleKeyboardEvent(event);
}

bool Browser::TabsNeedBeforeUnloadFired() const {
  return unload_controller_.TabsNeedBeforeUnloadFired();
}

bool Browser::PreHandleGestureEvent(content::WebContents* source,
                                    const blink::WebGestureEvent& event) {
  // Disable pinch zooming in undocked dev tools window due to poor UX.
  if (app_name() == DevToolsWindow::kDevToolsApp) {
    return blink::WebInputEvent::IsPinchGestureEventType(event.GetType());
  }
  return false;
}

bool Browser::CanDragEnter(content::WebContents* source,
                           const content::DropData& data,
                           blink::DragOperationsMask operations_allowed) {
#if BUILDFLAG(IS_CHROMEOS)
  // Disallow drag-and-drop navigation for Settings windows which do not support
  // external navigation.
  if ((operations_allowed & blink::kDragOperationLink) &&
      chrome::SettingsWindowManager::GetInstance()->IsSettingsBrowser(this)) {
    return false;
  }
#endif
  return true;
}

void Browser::CreateSmsPrompt(content::RenderFrameHost*,
                              const std::vector<url::Origin>&,
                              const std::string& one_time_code,
                              base::OnceClosure on_confirm,
                              base::OnceClosure on_cancel) {
  // TODO(crbug.com/40103792): implementation left pending deliberately.
  std::move(on_confirm).Run();
}

bool Browser::ShouldAllowRunningInsecureContent(
    content::WebContents* web_contents,
    bool allowed_per_prefs,
    const url::Origin& origin,
    const GURL& resource_url) {
  // Note: this implementation is a mirror of
  // ContentSettingsObserver::allowRunningInsecureContent.
  if (allowed_per_prefs) {
    return true;
  }

  Profile* profile =
      Profile::FromBrowserContext(web_contents->GetBrowserContext());
  HostContentSettingsMap* content_settings =
      HostContentSettingsMapFactory::GetForProfile(profile);
  return content_settings->GetContentSetting(
             web_contents->GetLastCommittedURL(), GURL(),
             ContentSettingsType::MIXEDSCRIPT) == CONTENT_SETTING_ALLOW;
}

void Browser::OnDidBlockNavigation(
    content::WebContents* web_contents,
    const GURL& blocked_url,
    blink::mojom::NavigationBlockedReason reason) {
  if (reason ==
      blink::mojom::NavigationBlockedReason::kRedirectWithNoUserGesture) {
    if (auto* framebust_helper =
            FramebustBlockTabHelper::FromWebContents(web_contents)) {
      auto on_click = [](const GURL& url, size_t index, size_t total_elements) {
        UMA_HISTOGRAM_ENUMERATION(
            "WebCore.Framebust.ClickThroughPosition",
            blocked_content::GetListItemPositionFromDistance(index,
                                                             total_elements));
      };
      framebust_helper->AddBlockedUrl(blocked_url, base::BindOnce(on_click));
    }
  }
}

content::PictureInPictureResult Browser::EnterPictureInPicture(
    content::WebContents* web_contents) {
  return PictureInPictureWindowManager::GetInstance()
      ->EnterVideoPictureInPicture(web_contents);
}

void Browser::ExitPictureInPicture() {
  PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture();
}

bool Browser::IsBackForwardCacheSupported(content::WebContents& web_contents) {
  return true;
}

content::PreloadingEligibility Browser::IsPrerender2Supported(
    content::WebContents& web_contents,
    content::PreloadingTriggerType trigger_type) {
  Profile* profile =
      Profile::FromBrowserContext(web_contents.GetBrowserContext());
  return prefetch::IsSomePreloadingEnabled(*profile->GetPrefs());
}

bool Browser::ShouldShowStaleContentOnEviction(content::WebContents* source) {
#if BUILDFLAG(IS_CHROMEOS)
  return source == tab_strip_model_->GetActiveWebContents();
#else
  return false;
#endif  // BUILDFLAG(IS_CHROMEOS)
}

bool Browser::IsPointerLocked() const {
  return browser_window_features()
      ->exclusive_access_manager()
      ->pointer_lock_controller()
      ->IsPointerLocked();
}

void Browser::OnWindowDidShow() {
  if (window_has_shown_) {
    return;
  }
  window_has_shown_ = true;

  startup_metric_utils::GetBrowser().RecordBrowserWindowDisplay(
      base::TimeTicks::Now());

  // Nothing to do for non-tabbed windows.
  if (!is_type_normal()) {
    return;
  }

  // Show any pending global error bubble.
  GlobalErrorService* service =
      GlobalErrorServiceFactory::GetForProfile(profile());
  GlobalError* error = service->GetFirstGlobalErrorWithBubbleView();
  if (error) {
    error->ShowBubbleView(this);
  }
}

///////////////////////////////////////////////////////////////////////////////
// Browser, content::WebContentsDelegate implementation:

WebContents* Browser::OpenURLFromTab(
    WebContents* source,
    const OpenURLParams& params,
    base::OnceCallback<void(content::NavigationHandle&)>
        navigation_handle_callback) {
  TRACE_EVENT1("navigation", "Browser::OpenURLFromTab", "source", source);
#if DCHECK_IS_ON()
  DCHECK(params.Valid());
#endif

  if (is_type_devtools()) {
    DevToolsWindow* window = DevToolsWindow::AsDevToolsWindow(source);
    DCHECK(window);
    return window->OpenURLFromTab(source, params,
                                  std::move(navigation_handle_callback));
  }

  NavigateParams nav_params(this, params.url, params.transition);
  nav_params.FillNavigateParamsFromOpenURLParams(params);
  nav_params.source_contents = source;
  nav_params.tabstrip_add_types = AddTabTypes::ADD_NONE;
  if (params.user_gesture) {
    nav_params.window_action = NavigateParams::WindowAction::kShowWindow;
  }
  bool is_popup =
      source && blocked_content::ConsiderForPopupBlocking(params.disposition);
  auto popup_delegate =
      std::make_unique<ChromePopupNavigationDelegate>(std::move(nav_params));
  if (is_popup) {
    popup_delegate.reset(static_cast<ChromePopupNavigationDelegate*>(
        blocked_content::MaybeBlockPopup(
            source, nullptr, std::move(popup_delegate), &params,
            blink::mojom::WindowFeatures(),
            HostContentSettingsMapFactory::GetForProfile(
                source->GetBrowserContext()))
            .release()));
    if (!popup_delegate) {
      return nullptr;
    }
  }

  chrome::ConfigureTabGroupForNavigation(popup_delegate->nav_params());

  base::WeakPtr<content::NavigationHandle> navigation_handle =
      Navigate(popup_delegate->nav_params());

  if (navigation_handle_callback && navigation_handle) {
    std::move(navigation_handle_callback).Run(*navigation_handle);
  }

  content::WebContents* navigated_or_inserted_contents =
      popup_delegate->nav_params()->navigated_or_inserted_contents;
  if (is_popup && navigated_or_inserted_contents) {
    auto* tracker = blocked_content::PopupTracker::CreateForWebContents(
        navigated_or_inserted_contents, source, params.disposition);
    tracker->set_is_trusted(
        params.triggering_event_info !=
        blink::mojom::TriggeringEventInfo::kFromUntrustedEvent);
  }

  TRACE_EVENT_INSTANT1(
      "navigation", "Browser::OpenURLFromTab_Result", TRACE_EVENT_SCOPE_THREAD,
      "navigated_or_inserted_contents", navigated_or_inserted_contents);

  return navigated_or_inserted_contents;
}

void Browser::NavigationStateChanged(WebContents* source,
                                     content::InvalidateTypes changed_flags) {
  // If we're shutting down we should refuse to process this message.
  // See crbug.com/1306297; it's possible that a WebContents sends navigation
  // state messages while destructing during browser tear-down. Ironically we
  // can't use IsShuttingDown() because by this point the browser is entirely
  // removed from the browser list.
  if (is_delete_scheduled_) {
    return;
  }

  // Only update the UI when something visible has changed.
  if (changed_flags) {
    ScheduleUIUpdate(source, changed_flags);
  }

  // We can synchronously update commands since they will only change once per
  // navigation, so we don't have to worry about flickering. We do, however,
  // need to update the command state early on load to always present usable
  // actions in the face of slow-to-commit pages.
  if (changed_flags &
      (content::INVALIDATE_TYPE_URL | content::INVALIDATE_TYPE_LOAD |
       content::INVALIDATE_TYPE_TAB)) {
    GetCommandController()->TabStateChanged();
  }

  if (auto* const app_browser_controller = app_controller()) {
    app_browser_controller->UpdateCustomTabBarVisibility(true);
  }
}

void Browser::VisibleSecurityStateChanged(WebContents* source) {
  // When the current tab's security state changes, we need to update the URL
  // bar to reflect the new state.
  DCHECK(source);
  if (tab_strip_model_->GetActiveWebContents() == source) {
    UpdateToolbarSecurityState();

    if (auto* const app_browser_controller = app_controller()) {
      app_browser_controller->UpdateCustomTabBarVisibility(true);
    }
  }
}

content::WebContents* Browser::AddNewContents(
    WebContents* source,
    std::unique_ptr<WebContents> new_contents,
    const GURL& target_url,
    WindowOpenDisposition disposition,
    const blink::mojom::WindowFeatures& window_features,
    bool user_gesture,
    bool* was_blocked) {
  FullscreenController* fullscreen_controller = browser_window_features()
                                                    ->exclusive_access_manager()
                                                    ->fullscreen_controller();
#if BUILDFLAG(IS_MAC)
  // On the Mac, the convention is to turn popups into new tabs when in browser
  // fullscreen mode. Only worry about user-initiated fullscreen as showing a
  // popup in HTML5 fullscreen would have kicked the page out of fullscreen.
  // However if this Browser is for an app or the popup is being requested on a
  // different display, we don't want to turn popups into new tabs. Popups
  // should open as new windows instead.
  display::Screen* screen = display::Screen::Get();
  bool targeting_different_display =
      screen && source && source->GetContentNativeView() &&
      screen->GetDisplayNearestView(source->GetContentNativeView()) !=
          screen->GetDisplayMatching(window_features.bounds);
  if (!app_controller() && disposition == WindowOpenDisposition::NEW_POPUP &&
      fullscreen_controller->IsFullscreenForBrowser() &&
      !targeting_different_display) {
    disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  }
#endif

  // At this point the |new_contents| is beyond the popup blocker, but we use
  // the same logic for determining if the popup tracker needs to be attached.
  if (source && blocked_content::ConsiderForPopupBlocking(disposition)) {
    blocked_content::PopupTracker::CreateForWebContents(new_contents.get(),
                                                        source, disposition);
  }

  // Postpone activating popups opened by content-fullscreen tabs. This permits
  // popups on other screens and retains fullscreen focus for exit accelerators.
  // Popups are activated when the opener exits fullscreen, which happens
  // immediately if the popup would overlap the fullscreen window.
  // Allow fullscreen-within-tab openers to open popups normally.
  NavigateParams::WindowAction window_action =
      NavigateParams::WindowAction::kShowWindow;
  if (disposition == WindowOpenDisposition::NEW_POPUP &&
      GetFullscreenState(source).target_mode ==
          content::FullscreenMode::kContent) {
    window_action = NavigateParams::WindowAction::kShowWindowInactive;
    fullscreen_controller->FullscreenTabOpeningPopup(source,
                                                     new_contents.get());
    // Defer popup creation if the opener has a fullscreen transition in
    // progress. This works around a defect on Mac where separate displays
    // cannot switch their independent spaces simultaneously (crbug.com/1315749)
    auto web_contents_creation_callback = base::BindOnce(
        &chrome::AddWebContents, this, source, std::move(new_contents),
        target_url, disposition, window_features, window_action, user_gesture);
    fullscreen_controller->RunOrDeferUntilTransitionIsComplete(base::BindOnce(
        base::IgnoreResult(std::move(web_contents_creation_callback))));
    return nullptr;
  }

  return chrome::AddWebContents(this, source, std::move(new_contents),
                                target_url, disposition, window_features,
                                window_action, user_gesture);
}

void Browser::ActivateContents(WebContents* contents) {
  // A WebContents can ask to activate after it's been removed from the
  // TabStripModel. See https://crbug.com/1060986
  int index = tab_strip_model_->GetIndexOfWebContents(contents);
  if (index == TabStripModel::kNoTab) {
    return;
  }
  tab_strip_model_->ActivateTabAt(index);
  window_->Activate();
}

bool Browser::IsContentsActive(content::WebContents* contents) {
  return tab_strip_model_->GetActiveWebContents() == contents;
}

void Browser::LoadingStateChanged(WebContents* source,
                                  bool should_show_loading_ui) {
  ScheduleUIUpdate(source, content::INVALIDATE_TYPE_LOAD);
  UpdateWindowForLoadingStateChanged(source, should_show_loading_ui);
}

void Browser::CloseContents(WebContents* source) {
  if (unload_controller_.CanCloseContents(source)) {
    chrome::CloseWebContents(this, source, true);
  }
}

void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
  if (is_type_normal()) {
    return;
  }

  std::vector<blink::mojom::WebFeature> features = {
      blink::mojom::WebFeature::kMovedOrResizedPopup};
  if (creation_timer_.Elapsed() > base::Seconds(2)) {
    // Additionally measure whether a popup was moved after creation, to
    // distinguish between popups that reposition themselves after load and
    // those which move popups continuously.
    features.push_back(
        blink::mojom::WebFeature::kMovedOrResizedPopup2sAfterCreation);
  }

  page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage(
      source->GetPrimaryMainFrame(), std::move(features));
  window_->SetBounds(bounds);
}

void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
  std::vector<StatusBubble*> status_bubbles = GetStatusBubbles();
  for (StatusBubble* status_bubble : status_bubbles) {
    StatusBubbleViews* status_bubble_views =
        static_cast<StatusBubbleViews*>(status_bubble);
    ContentsWebView* anchor =
        static_cast<ContentsWebView*>(status_bubble_views->base_view());
    if (source == anchor->GetWebContents()) {
      status_bubble->SetURL(url);
      break;
    }
  }
}

void Browser::ContentsMouseEvent(WebContents* source, const ui::Event& event) {
  const ui::EventType type = event.type();
  const bool exited = type == ui::EventType::kMouseExited;
  // Disregard synthesized events, and mouse enter and exit, which may occur
  // without explicit user input events during window state changes.
  if (type != ui::EventType::kMouseEntered && !exited &&
      !event.IsSynthesized()) {
    browser_window_features()->exclusive_access_manager()->OnUserInput();
  }

  // Mouse motion events update the status bubble, if it exists.
  std::vector<StatusBubble*> status_bubbles = GetStatusBubbles();
  for (StatusBubble* status_bubble : status_bubbles) {
    StatusBubbleViews* status_bubble_views =
        static_cast<StatusBubbleViews*>(status_bubble);
    ContentsWebView* anchor =
        static_cast<ContentsWebView*>(status_bubble_views->base_view());
    if (source == anchor->GetWebContents() &&
        (type == ui::EventType::kMouseMoved || exited)) {
      status_bubble->MouseMoved(exited);
      if (exited) {
        status_bubble->SetURL(GURL());
      }
      break;
    }
  }
}

void Browser::ContentsZoomChange(bool zoom_in) {
  chrome::ExecuteCommand(this, zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
}

bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
  return false;
}

bool Browser::DidAddMessageToConsole(
    content::WebContents* source,
    blink::mojom::ConsoleMessageLevel log_level,
    const std::u16string& message,
    int32_t line_no,
    const std::u16string& source_id) {
  static bool is_headless_mode = headless::IsHeadlessMode();
  if (is_headless_mode) {
    const bool is_builtin_component = !!source->GetWebUI();
    headless::LogConsoleMessage(log_level, message, line_no,
                                is_builtin_component, source_id);
    return true;
  }
  return false;
}

void Browser::BeforeUnloadFired(WebContents* web_contents,
                                bool proceed,
                                bool* proceed_to_fire_unload) {
  if (is_type_devtools() &&
      DevToolsWindow::HandleBeforeUnload(web_contents, proceed,
                                         proceed_to_fire_unload)) {
    return;
  }

  *proceed_to_fire_unload =
      unload_controller_.BeforeUnloadFired(web_contents, proceed);
}

bool Browser::ShouldFocusLocationBarByDefault(WebContents* source) {
  // Navigations in background tabs shouldn't change the focus state of the
  // omnibox, since it's associated with the foreground tab.
  if (source != tab_strip_model_->GetActiveWebContents()) {
    return false;
  }

  // This should be based on the pending entry if there is one, so that
  // back/forward navigations to the NTP are handled.  The visible entry can't
  // be used here, since back/forward navigations are not treated as visible
  // entries to avoid URL spoofs.
  content::NavigationEntry* entry =
      source->GetController().GetPendingEntry()
          ? source->GetController().GetPendingEntry()
          : source->GetController().GetLastCommittedEntry();
  if (entry) {
    const GURL& url = entry->GetURL();
    const GURL& virtual_url = entry->GetVirtualURL();

    if (virtual_url.SchemeIs(content::kViewSourceScheme)) {
      return false;
    }

    if ((url.SchemeIs(content::kChromeUIScheme) &&
         url.host() == chrome::kChromeUINewTabHost) ||
        (virtual_url.SchemeIs(content::kChromeUIScheme) &&
         virtual_url.host() == chrome::kChromeUINewTabHost)) {
      return true;
    }

    if (url.spec() == chrome::kChromeUISplitViewNewTabPageURL) {
      return true;
    }
  }

  return search::NavEntryIsInstantNTP(source, entry);
}

bool Browser::ShouldFocusPageAfterCrash(WebContents* source) {
  // Focus only the active page when reloading after a crash, otherwise
  // return false. This is to ensure background reloads via hovercard
  // don't end up causing a focus loss which results in its dismissal.
  return source == tab_strip_model_->GetActiveWebContents();
}

void Browser::ShowRepostFormWarningDialog(WebContents* source) {
  TabModalConfirmDialog::Create(
      std::make_unique<RepostFormWarningController>(source), source);
}

bool Browser::IsWebContentsCreationOverridden(
    content::RenderFrameHost* opener,
    content::SiteInstance* source_site_instance,
    content::mojom::WindowContainerType window_container_type,
    const GURL& opener_url,
    const std::string& frame_name,
    const GURL& target_url) {
  if (HasActorTask(profile(), opener)) {
    // If an ExecutionEngine is acting on the opener, prevent it from creating a
    // new WebContents. We'll instead force the navigation to happen in the same
    // tab. Note, we do this even if the task isn't active (e.g. paused) so that
    // a user action on behalf of the actor has the same behavior since the
    // resumed task will still be fixed to the tab.
    return true;
  }

  return (window_container_type ==
              content::mojom::WindowContainerType::BACKGROUND &&
          ShouldCreateBackgroundContents(source_site_instance, opener_url,
                                         frame_name));
}

WebContents* Browser::CreateCustomWebContents(
    content::RenderFrameHost* opener,
    content::SiteInstance* source_site_instance,
    bool is_new_browsing_instance,
    const GURL& opener_url,
    const std::string& frame_name,
    const GURL& target_url,
    const content::StoragePartitionConfig& partition_config,
    content::SessionStorageNamespace* session_storage_namespace) {
  if (auto* opener_contents = content::WebContents::FromRenderFrameHost(opener);
      HasActorTask(profile(), opener)) {
    // If an ExecutionEngine is acting on the opener, we force the navigation
    // to happen in the same tab.
    content::NavigationController::LoadURLParams params(target_url);
    params.initiator_frame_token = opener->GetFrameToken();
    params.initiator_process_id = opener->GetProcess()->GetDeprecatedID();
    params.initiator_origin = opener->GetLastCommittedOrigin();
    params.source_site_instance = source_site_instance;
    params.transition_type = ui::PAGE_TRANSITION_LINK;
    params.is_renderer_initiated = true;
    opener_contents->GetController().LoadURLWithParams(params);
    VLOG(1) << "Actor treated window open as same tab navigation. "
            << target_url;
    return nullptr;
  }

  BackgroundContents* background_contents = CreateBackgroundContents(
      source_site_instance, opener, opener_url, is_new_browsing_instance,
      frame_name, target_url, partition_config, session_storage_namespace);
  if (background_contents) {
    return background_contents->web_contents();
  }
  return nullptr;
}

void Browser::WebContentsCreated(WebContents* source_contents,
                                 int opener_render_process_id,
                                 int opener_render_frame_id,
                                 const std::string& frame_name,
                                 const GURL& target_url,
                                 WebContents* new_contents) {
  // Note: Consult owners before adding new code here.
  // This method is called from WebContentsImpl::CreateNewWindow() for a created
  // `new_contents`. This occurs before ownership of `new_contents` is
  // transferred to Browser and `new_contents` is added to a TabModel. Tab
  // specific initialization should be performed by TabModel and not added here.

  // SafeBrowsingNavigationObserver relies on recording a precise sequence of
  // navigation events, with tabs tracked via their SessionID, managed by
  // SessionTabHelper. The current safe browsing implementation requires
  // tracking new contents from the moment of creation, at which point TabModel
  // and tab helpers have not yet been initialized for `new_contents`.
  // Explicitly instantiate the SessionTabHelper here to ensure SessionIDs are
  // available when needed.
  // TODO(crbug.com/362038317): Once SafeBrowsingNavigationObserver is updated
  // to track `new_contents` after it is added to its TabModel this override can
  // be removed.
  CreateSessionServiceTabHelper(new_contents);
}

void Browser::RendererUnresponsive(
    WebContents* source,
    content::RenderWidgetHost* render_widget_host,
    base::RepeatingClosure hang_monitor_restarter) {
  // Don't show the page hung dialog when a HTML popup hangs because
  // the dialog will take the focus and immediately close the popup.
  RenderWidgetHostView* view = render_widget_host->GetView();
  if (view && !render_widget_host->GetView()->IsHTMLFormPopup()) {
    TabDialogs::FromWebContents(source)->ShowHungRendererDialog(
        render_widget_host, std::move(hang_monitor_restarter));
  }
}

void Browser::RendererResponsive(
    WebContents* source,
    content::RenderWidgetHost* render_widget_host) {
  RenderWidgetHostView* view = render_widget_host->GetView();
  if (view && !render_widget_host->GetView()->IsHTMLFormPopup()) {
    TabDialogs::FromWebContents(source)->HideHungRendererDialog(
        render_widget_host);
  }
}

content::JavaScriptDialogManager* Browser::GetJavaScriptDialogManager(
    WebContents* source) {
  return javascript_dialogs::TabModalDialogManager::FromWebContents(source);
}

bool Browser::GuestSaveFrame(content::WebContents* guest_web_contents) {
  auto* guest_view =
      extensions::MimeHandlerViewGuest::FromWebContents(guest_web_contents);
  return guest_view && guest_view->PluginDoSave();
}

std::unique_ptr<content::EyeDropper> Browser::OpenEyeDropper(
    content::RenderFrameHost* frame,
    content::EyeDropperListener* listener) {
  return window()->OpenEyeDropper(frame, listener);
}

void Browser::InitiatePreview(content::WebContents& web_contents,
                              const GURL& url) {
#if !BUILDFLAG(IS_ANDROID)
  PreviewManager::CreateForWebContents(&web_contents);
  PreviewManager* manager = PreviewManager::FromWebContents(&web_contents);
  CHECK(manager);
  manager->InitiatePreview(url);
#endif
}

bool Browser::ShouldUseInstancedSystemMediaControls() const {
  return is_type_app() || is_type_app_popup();
}

void Browser::DraggableRegionsChanged(
    const std::vector<blink::mojom::DraggableRegionPtr>& regions,
    content::WebContents* contents) {
  if (auto* const app_browser_controller = app_controller()) {
    app_browser_controller->DraggableRegionsChanged(regions, contents);
  }
}

std::vector<blink::mojom::RelatedApplicationPtr>
Browser::GetSavedRelatedApplications(WebContents* web_contents) {
  Profile* profile =
      Profile::FromBrowserContext(web_contents->GetBrowserContext());
  CHECK(profile);
  if (!web_app::AreWebAppsEnabled(profile)) {
    return {};
  }
  const webapps::AppId* app_id =
      web_app::WebAppTabHelper::GetAppId(web_contents);
  if (!app_id || app_id->empty()) {
    return {};
  }
  web_app::WebAppProvider* provider =
      web_app::WebAppProvider::GetForWebApps(profile);
  CHECK(provider);
  std::vector<blink::Manifest::RelatedApplication> saved_related_apps =
      provider->registrar_unsafe().GetRelatedApplications(*app_id);
  std::vector<blink::mojom::RelatedApplicationPtr> related_apps_ptr;
  for (const auto& app : saved_related_apps) {
    auto related_app = blink::mojom::RelatedApplication::New();
    related_app->platform =
        base::UTF16ToUTF8(app.platform.value_or(std::u16string()));
    related_app->id = base::UTF16ToUTF8(app.id.value_or(std::u16string()));
    if (!app.url.is_empty()) {
      related_app->url = app.url.spec();
    }
    related_apps_ptr.push_back(std::move(related_app));
  }
  return related_apps_ptr;
}

content::WebContents* Browser::GetResponsibleWebContents(
    content::WebContents* web_contents) {
  // Tabs are the proper choice for modal scope.
  return web_contents;
}

void Browser::RunFileChooser(
    content::RenderFrameHost* render_frame_host,
    scoped_refptr<content::FileSelectListener> listener,
    const blink::mojom::FileChooserParams& params) {
  FileSelectHelper::RunFileChooser(render_frame_host, std::move(listener),
                                   params);
}

void Browser::EnumerateDirectory(
    WebContents* web_contents,
    scoped_refptr<content::FileSelectListener> listener,
    const base::FilePath& path) {
  FileSelectHelper::EnumerateDirectory(web_contents, std::move(listener), path);
}

void Browser::OnWebApiWindowResizableChanged() {
  window_->OnWebApiWindowResizableChanged();
}

bool Browser::GetCanResize() {
  return window_->GetCanResize();
}

#if !BUILDFLAG(IS_ANDROID)
bool Browser::CanUseWindowingControls(
    content::RenderFrameHost* requesting_frame) {
  if (!app_controller()) {
    requesting_frame->AddMessageToConsole(
        blink::mojom::ConsoleMessageLevel::kWarning,
        "API called from something else than a web_app.");
    return false;
  }
  return true;
}

void Browser::MinimizeFromWebAPI() {
  window_->Minimize();
}

void Browser::MaximizeFromWebAPI() {
  window_->Maximize();
}

void Browser::RestoreFromWebAPI() {
  window_->Restore();
}
#endif  // !BUILDFLAG(IS_ANDROID)

ui::mojom::WindowShowState Browser::GetWindowShowState() const {
  return window_->GetWindowShowState();
}

bool Browser::CanEnterFullscreenModeForTab(
    content::RenderFrameHost* requesting_frame) {
  // If the tab strip isn't editable then a drag session is in progress, and it
  // is not safe to enter fullscreen. https://crbug.com/1315080
  if (!tab_strip_model_delegate_->IsTabStripEditable()) {
    return false;
  }

  return browser_window_features()
      ->exclusive_access_manager()
      ->fullscreen_controller()
      ->CanEnterFullscreenModeForTab(requesting_frame);
}

void Browser::EnterFullscreenModeForTab(
    content::RenderFrameHost* requesting_frame,
    const blink::mojom::FullscreenOptions& options) {
  browser_window_features()
      ->exclusive_access_manager()
      ->fullscreen_controller()
      ->EnterFullscreenModeForTab(requesting_frame,
                                  FullscreenTabParams{options.display_id});
}

void Browser::ExitFullscreenModeForTab(WebContents* web_contents) {
  browser_window_features()
      ->exclusive_access_manager()
      ->fullscreen_controller()
      ->ExitFullscreenModeForTab(web_contents);
}

bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) {
  const content::FullscreenState state = GetFullscreenState(web_contents);
  return state.target_mode == content::FullscreenMode::kContent ||
         state.target_mode == content::FullscreenMode::kPseudoContent;
}

content::FullscreenState Browser::GetFullscreenState(
    const WebContents* web_contents) const {
  return browser_window_features()
      ->exclusive_access_manager()
      ->fullscreen_controller()
      ->GetFullscreenState(web_contents);
}

blink::mojom::DisplayMode Browser::GetDisplayMode(
    const WebContents* web_contents) {
  if (window_->IsFullscreen()) {
    return blink::mojom::DisplayMode::kFullscreen;
  }

  if (is_type_picture_in_picture()) {
    return blink::mojom::DisplayMode::kPictureInPicture;
  }

  if (is_type_app() || is_type_devtools() || is_type_app_popup()) {
    auto* const app_browser_controller = app_controller();
    if (app_browser_controller &&
        app_browser_controller->HasMinimalUiButtons()) {
      return blink::mojom::DisplayMode::kMinimalUi;
    }

    if (app_browser_controller &&
        app_browser_controller->AppUsesWindowControlsOverlay() &&
        !web_contents->GetWindowsControlsOverlayRect().IsEmpty()) {
      return blink::mojom::DisplayMode::kWindowControlsOverlay;
    }

    if (app_browser_controller && app_browser_controller->AppUsesTabbed()) {
      return blink::mojom::DisplayMode::kTabbed;
    }

    if (app_browser_controller &&
        app_browser_controller->AppUsesBorderlessMode() &&
        window_->IsBorderlessModeEnabled()) {
      return blink::mojom::DisplayMode::kBorderless;
    }

    return blink::mojom::DisplayMode::kStandalone;
  }

  return blink::mojom::DisplayMode::kBrowser;
}

blink::ProtocolHandlerSecurityLevel Browser::GetProtocolHandlerSecurityLevel(
    content::RenderFrameHost* requesting_frame) {
  content::BrowserContext* context = requesting_frame->GetBrowserContext();
  extensions::ProcessMap* process_map = extensions::ProcessMap::Get(context);
  const Extension* owner_extension =
      extensions::ProcessManager::Get(context)->GetExtensionForRenderFrameHost(
          requesting_frame);
  if (owner_extension &&
      process_map->IsPrivilegedExtensionProcess(
          *owner_extension,
          requesting_frame->GetProcess()->GetDeprecatedID())) {
    return blink::ProtocolHandlerSecurityLevel::kExtensionFeatures;
  }
  return blink::ProtocolHandlerSecurityLevel::kStrict;
}

void Browser::RegisterProtocolHandler(
    content::RenderFrameHost* requesting_frame,
    const std::string& protocol,
    const GURL& url,
    bool user_gesture) {
  content::BrowserContext* context = requesting_frame->GetBrowserContext();
  if (context->IsOffTheRecord()) {
    return;
  }

  auto* web_contents =
      content::WebContents::FromRenderFrameHost(requesting_frame);

  ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(
      protocol, url, GetProtocolHandlerSecurityLevel(requesting_frame));

  // The parameters's normalization process defined in the spec has been already
  // applied in the WebContentImpl class, so at this point it shouldn't be
  // possible to create an invalid handler.
  // https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
  DCHECK(handler.IsValid());

  custom_handlers::ProtocolHandlerRegistry* registry =
      ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
  if (registry->SilentlyHandleRegisterHandlerRequest(handler)) {
    return;
  }

  // TODO(carlscab): This should probably be FromFrame() once it becomes
  // PageSpecificContentSettingsDelegate
  auto* page_content_settings_delegate =
      PageSpecificContentSettingsDelegate::FromWebContents(web_contents);
  if (!user_gesture && window_) {
    page_content_settings_delegate->set_pending_protocol_handler(handler);
    page_content_settings_delegate->set_previous_protocol_handler(
        registry->GetHandlerFor(handler.protocol()));
    window_->GetLocationBar()->UpdateContentSettingsIcons();
    return;
  }

  // Make sure content-setting icon is turned off in case the page does
  // ungestured and gestured RPH calls.
  if (window_) {
    page_content_settings_delegate->ClearPendingProtocolHandler();
    window_->GetLocationBar()->UpdateContentSettingsIcons();
  }

  if (registry->registration_mode() ==
      custom_handlers::RphRegistrationMode::kAutoAccept) {
    registry->OnAcceptRegisterProtocolHandler(handler);
    return;
  }

  permissions::PermissionRequestManager* permission_request_manager =
      permissions::PermissionRequestManager::FromWebContents(web_contents);
  if (permission_request_manager) {
    // At this point, there will be UI presented, and running a dialog causes an
    // exit to webpage-initiated fullscreen. http://crbug.com/728276
    base::ScopedClosureRunner fullscreen_block =
        web_contents->ForSecurityDropFullscreen(
            /*display_id=*/display::kInvalidDisplayId);

    permission_request_manager->AddRequest(
        requesting_frame,
        std::make_unique<
            custom_handlers::RegisterProtocolHandlerPermissionRequest>(
            registry, handler, url, std::move(fullscreen_block)));
  }
}

void Browser::UnregisterProtocolHandler(
    content::RenderFrameHost* requesting_frame,
    const std::string& protocol,
    const GURL& url,
    bool user_gesture) {
  // user_gesture will be used in case we decide to have confirmation bubble
  // for user while un-registering the handler.
  content::BrowserContext* context = requesting_frame->GetBrowserContext();
  if (context->IsOffTheRecord()) {
    return;
  }

  ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(
      protocol, url, GetProtocolHandlerSecurityLevel(requesting_frame));

  custom_handlers::ProtocolHandlerRegistry* registry =
      ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
  registry->RemoveHandler(handler);
}

void Browser::FindReply(WebContents* web_contents,
                        int request_id,
                        int number_of_matches,
                        const gfx::Rect& selection_rect,
                        int active_match_ordinal,
                        bool final_update) {
  find_in_page::FindTabHelper* find_tab_helper =
      find_in_page::FindTabHelper::FromWebContents(web_contents);
  if (!find_tab_helper) {
    return;
  }

  find_tab_helper->HandleFindReply(request_id, number_of_matches,
                                   selection_rect, active_match_ordinal,
                                   final_update);
}

void Browser::RequestPointerLock(WebContents* web_contents,
                                 bool user_gesture,
                                 bool last_unlocked_by_target) {
  browser_window_features()
      ->exclusive_access_manager()
      ->pointer_lock_controller()
      ->RequestToLockPointer(web_contents, user_gesture,
                             last_unlocked_by_target);
}

void Browser::LostPointerLock() {
  browser_window_features()
      ->exclusive_access_manager()
      ->pointer_lock_controller()
      ->ExitExclusiveAccessToPreviousState();
}

bool Browser::IsWaitingForPointerLockPrompt(WebContents* web_contents) {
  return browser_window_features()
      ->exclusive_access_manager()
      ->pointer_lock_controller()
      ->IsWaitingForPointerLockPrompt(web_contents);
}

void Browser::RequestKeyboardLock(WebContents* web_contents,
                                  bool esc_key_locked) {
  browser_window_features()
      ->exclusive_access_manager()
      ->keyboard_lock_controller()
      ->RequestKeyboardLock(web_contents, esc_key_locked);
}

void Browser::CancelKeyboardLockRequest(WebContents* web_contents) {
  browser_window_features()
      ->exclusive_access_manager()
      ->keyboard_lock_controller()
      ->CancelKeyboardLockRequest(web_contents);
}

void Browser::RequestMediaAccessPermission(
    content::WebContents* web_contents,
    const content::MediaStreamRequest& request,
    content::MediaResponseCallback callback) {
  const extensions::Extension* extension =
      GetExtensionForOrigin(profile_, request.security_origin);
  MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
      web_contents, request, std::move(callback), extension);
}

void Browser::ProcessSelectAudioOutput(
    const content::SelectAudioOutputRequest& request,
    content::SelectAudioOutputCallback callback) {
#if defined(TOOLKIT_VIEWS)
  MediaCaptureDevicesDispatcher::GetInstance()->ProcessSelectAudioOutputRequest(
      this, request, std::move(callback));
#else
  std::move(callback).Run(
      base::unexpected(content::SelectAudioOutputError::kUnknown));
#endif
}

bool Browser::CheckMediaAccessPermission(
    content::RenderFrameHost* render_frame_host,
    const url::Origin& security_origin,
    blink::mojom::MediaStreamType type) {
  Profile* profile =
      Profile::FromBrowserContext(render_frame_host->GetBrowserContext());
  const extensions::Extension* extension =
      GetExtensionForOrigin(profile, security_origin.GetURL());
  return MediaCaptureDevicesDispatcher::GetInstance()
      ->CheckMediaAccessPermission(render_frame_host, security_origin, type,
                                   extension);
}

std::string Browser::GetTitleForMediaControls(WebContents* web_contents) {
  auto* const app_browser_controller = app_controller();
  return app_browser_controller
             ? app_browser_controller->GetTitleForMediaControls()
             : std::string();
}

#if BUILDFLAG(ENABLE_PRINTING)
void Browser::PrintCrossProcessSubframe(
    content::WebContents* web_contents,
    const gfx::Rect& rect,
    int document_cookie,
    content::RenderFrameHost* subframe_host) const {
  auto* client = printing::PrintCompositeClient::FromWebContents(web_contents);
  if (client) {
    client->PrintCrossProcessSubframe(rect, document_cookie, subframe_host);
  }
}
#endif

#if BUILDFLAG(ENABLE_PAINT_PREVIEW)
void Browser::CapturePaintPreviewOfSubframe(
    content::WebContents* web_contents,
    const gfx::Rect& rect,
    const base::UnguessableToken& guid,
    content::RenderFrameHost* render_frame_host) {
  auto* client =
      paint_preview::PaintPreviewClient::FromWebContents(web_contents);
  if (client) {
    client->CaptureSubframePaintPreview(guid, rect, render_frame_host);
  }
}
#endif

///////////////////////////////////////////////////////////////////////////////
// Browser, web_modal::WebContentsModalDialogManagerDelegate implementation:

void Browser::SetWebContentsBlocked(content::WebContents* web_contents,
                                    bool blocked) {
  int index = tab_strip_model_->GetIndexOfWebContents(web_contents);
  if (index == TabStripModel::kNoTab) {
    // Removal of tabs from the TabStripModel can cause observer callbacks to
    // invoke this method. The WebContents may no longer exist in the
    // TabStripModel.
    // If the WebContents has a DevTools window,
    // the call is meant for the DevTools area.
    if (DevToolsWindow::AsDevToolsWindow(web_contents)) {
      window_->SetDevToolsScrimVisibility(blocked);
    }
    return;
  }

  // Drop HTML fullscreen to give users context for making informed decisions.
  // Skip browser-fullscreen, which is more expressly user-initiated.
  // Skip fullscreen-within-tab, which shows the browser frame.
  if (blocked && GetFullscreenState(web_contents).target_mode ==
                     content::FullscreenMode::kContent) {
    // Skip URLs with the automatic fullscreen content setting granted.
    const GURL& url = web_contents->GetLastCommittedURL();
    const HostContentSettingsMap* const content_settings =
        HostContentSettingsMapFactory::GetForProfile(
            web_contents->GetBrowserContext());
    if (content_settings->GetContentSetting(
            url, url, ContentSettingsType::AUTOMATIC_FULLSCREEN) !=
        CONTENT_SETTING_ALLOW) {
      web_contents->ExitFullscreen(true);
    }
  }

  tab_strip_model_->SetTabBlocked(index, blocked);

  const bool browser_active =
      GetLastActiveBrowserWindowInterfaceWithAnyProfile() == this;
  bool contents_is_active =
      tab_strip_model_->GetActiveWebContents() == web_contents;
  // If the WebContents is foremost (the active tab in the front-most browser)
  // and is being unblocked, focus it to make sure that input works again.
  if (!blocked && contents_is_active && browser_active) {
    web_contents->Focus();
  }
}

web_modal::WebContentsModalDialogHost* Browser::GetWebContentsModalDialogHost(
    content::WebContents* web_contents) {
  return window_->GetWebContentsModalDialogHostFor(web_contents);
}

///////////////////////////////////////////////////////////////////////////////
// Browser, BookmarkTabHelperObserver implementation:

void Browser::URLStarredChanged(content::WebContents* web_contents,
                                bool starred) {
  if (web_contents == tab_strip_model_->GetActiveWebContents()) {
    window_->SetStarredState(starred);
  }
}

///////////////////////////////////////////////////////////////////////////////
// Browser, ZoomObserver implementation:

void Browser::OnZoomControllerDestroyed(zoom::ZoomController* zoom_controller) {
  // SetAsDelegate() takes care of removing the observers.
}

void Browser::OnZoomChanged(
    const zoom::ZoomController::ZoomChangedEventData& data) {
  if (data.web_contents == tab_strip_model_->GetActiveWebContents()) {
    window_->ZoomChangedForActiveTab(data.can_show_bubble);
    // Change the zoom commands state based on the zoom state
    GetCommandController()->ZoomStateChanged();
  }
}

///////////////////////////////////////////////////////////////////////////////
// Browser, ThemeServiceObserver implementation:

void Browser::OnThemeChanged() {
  window()->UserChangedTheme(BrowserThemeChangeType::kBrowserTheme);
}

///////////////////////////////////////////////////////////////////////////////
// Browser, Command and state updating (private):

void Browser::OnTabInsertedAt(WebContents* contents, int index) {
  // If this Browser is about to be deleted, then WebContents should not be
  // added to it. This is because scheduling the delete can not be undone, and
  // proper cleanup is not done if a WebContents is added once delete it
  // scheduled (WebContents is leaked, unload handlers aren't checked...).
  // TODO(crbug.com/40064092): this should check that `is_delete_scheduled_` is
  // false.
  DUMP_WILL_BE_CHECK(!is_delete_scheduled_);

  SetAsDelegate(contents, true);

  sessions::SessionTabHelper::FromWebContents(contents)->SetWindowID(
      session_id());

  SyncHistoryWithTabs(index);

  // Make sure the loading state is updated correctly, otherwise the throbber
  // won't start if the page is loading. Note that we don't want to
  // ScheduleUIUpdate() because the tab may not have been inserted in the UI
  // yet if this function is called before TabStripModel::TabInsertedAt().
  UpdateWindowForLoadingStateChanged(contents, true);

  SessionServiceBase* service = GetAppropriateSessionServiceForProfile(this);

  if (service) {
    service->TabInserted(contents);
    int new_active_index = tab_strip_model_->active_index();
    if (index < new_active_index) {
      service->SetSelectedTabInWindow(session_id(), new_active_index);
    }
  }
}

void Browser::OnTabClosing(WebContents* contents) {
  // When this function is called |contents| has been removed from the
  // TabStripModel. Some of the following code may trigger calling to the
  // WebContentsDelegate, which is |this|, which may try to look for the
  // WebContents in the TabStripModel, and fail because the WebContents has
  // been removed. To avoid these problems the delegate is reset now.
  SetAsDelegate(contents, false);

  // Typically, ModalDialogs are closed when the WebContents is destroyed.
  // However, when the tab is being closed, we must first close the dialogs [to
  // give them an opportunity to clean up after themselves] while the state
  // associated with their tab is still valid.
  WebContentsModalDialogManager::FromWebContents(contents)->CloseAllDialogs();

  // Page load metrics need to be informed that the WebContents will soon be
  // destroyed, so that upcoming visibility changes can be ignored.
  page_load_metrics::MetricsWebContentsObserver* metrics_observer =
      page_load_metrics::MetricsWebContentsObserver::FromWebContents(contents);
  metrics_observer->WebContentsWillSoonBeDestroyed();

  browser_window_features()->exclusive_access_manager()->OnTabClosing(contents);
  SessionServiceBase* service = GetAppropriateSessionServiceForProfile(this);

  if (service) {
    service->TabClosing(contents);
  }
}

void Browser::OnTabDetached(WebContents* contents, bool was_active) {
  if (!tab_strip_model_->closing_all()) {
    SessionServiceBase* service = GetAppropriateSessionServiceIfExisting(this);
    if (service) {
      service->SetSelectedTabInWindow(session_id(),
                                      tab_strip_model_->active_index());
    }
  }

  TabDetachedAtImpl(contents, was_active, DetachType::kDetach);

  window_->OnTabDetached(contents, was_active);
}

void Browser::OnTabDeactivated(WebContents* contents) {
  browser_window_features()->exclusive_access_manager()->OnTabDeactivated(
      contents);
  SearchTabHelper::FromWebContents(contents)->OnTabDeactivated();

  // Save what the user's currently typing, so it can be restored when we
  // switch back to this tab.
  window_->GetLocationBar()->SaveStateToContents(contents);
}

void Browser::OnActiveTabChanged(WebContents* old_contents,
                                 WebContents* new_contents,
                                 int index,
                                 int reason) {
  TRACE_EVENT0("ui", "Browser::OnActiveTabChanged");
// Mac correctly sets the initial background color of new tabs to the theme
// background color, so it does not need this block of code. Aura should
// implement this as well.
// https://crbug.com/719230
#if !BUILDFLAG(IS_MAC)
  // Copies the background color from an old WebContents to a new one that
  // replaces it on the screen. This allows the new WebContents to use the
  // old one's background color as the starting background color, before having
  // loaded any contents. As a result, we avoid flashing white when moving to
  // a new tab. (There is also code in RenderFrameHostManager to do something
  // similar for intra-tab navigations.)
  if (old_contents && new_contents) {
    // While GetPrimaryMainFrame() is guaranteed to return non-null, GetView()
    // is not, e.g. between WebContents creation and creation of the
    // RenderWidgetHostView.
    RenderWidgetHostView* old_view =
        old_contents->GetPrimaryMainFrame()->GetView();
    RenderWidgetHostView* new_view =
        new_contents->GetPrimaryMainFrame()->GetView();
    if (old_view && new_view) {
      new_view->CopyBackgroundColorIfPresentFrom(*old_view);
    }
  }
#endif

  base::RecordAction(UserMetricsAction("ActiveTabChanged"));

  // Update the bookmark state, since the BrowserWindow may query it during
  // OnActiveTabChanged() below.
  BookmarkBarController::From(this)->UpdateBookmarkBarState(
      BookmarkBarController::StateChangeReason::kTabSwitch);

  // Let the BrowserWindow do its handling.  On e.g. views this changes the
  // focused object, which should happen before we update the toolbar below,
  // since the omnibox expects the correct element to already be focused when
  // it is updated.
  window_->OnActiveTabChanged(old_contents, new_contents, index, reason);

  browser_window_features()->exclusive_access_manager()->OnTabDetachedFromView(
      old_contents);

  // If we have any update pending, do it now.
  if (chrome_updater_factory_.HasWeakPtrs() && old_contents) {
    ProcessPendingUIUpdates();
  }

  // Propagate the profile to the location bar.
  UpdateToolbar((reason & CHANGE_REASON_REPLACED) == 0);

  // Update reload/stop state.
  chrome::BrowserCommandController* const browser_command_controller =
      GetCommandController();
  browser_command_controller->LoadingStateChanged(new_contents->IsLoading(),
                                                  true);

  // Update commands to reflect current state.
  browser_command_controller->TabStateChanged();

  // Reset the status bubble.
  std::vector<StatusBubble*> status_bubbles = GetStatusBubbles();
  for (StatusBubble* status_bubble : status_bubbles) {
    status_bubble->Hide();

    // Show the loading state (if any).
    if (status_bubble == status_bubbles.front()) {
      status_bubble->SetStatus(CoreTabHelper::FromWebContents(
                                   tab_strip_model_->GetActiveWebContents())
                                   ->GetStatusText());
    }
  }

  if (HasFindBarController()) {
    CreateOrGetFindBarController()->HandleActiveTabChanged(new_contents);
  }

  // Update sessions (selected tab index and last active time). Don't force
  // creation of sessions. If sessions doesn't exist, the change will be picked
  // up by sessions when created.
  SessionServiceBase* service = GetAppropriateSessionServiceIfExisting(this);
  if (service && !tab_strip_model_->closing_all()) {
    service->SetSelectedTabInWindow(session_id(),
                                    tab_strip_model_->active_index());
    service->SetLastActiveTime(
        session_id(), sessions::SessionTabHelper::IdForTab(new_contents),
        base::Time::Now());
  }

  SearchTabHelper::FromWebContents(new_contents)->OnTabActivated();
  did_active_tab_change_callback_list_.Notify(this);
}

void Browser::OnTabMoved(int from_index, int to_index) {
  DCHECK(from_index >= 0 && to_index >= 0);
  // Notify the history service.
  SyncHistoryWithTabs(std::min(from_index, to_index));
}

void Browser::OnTabReplacedAt(WebContents* old_contents,
                              WebContents* new_contents,
                              int index) {
  bool was_active = index == tab_strip_model_->active_index();
  if (was_active) {
    did_active_tab_change_callback_list_.Notify(this);
  }
  TabDetachedAtImpl(old_contents, was_active, DetachType::kReplace);
  browser_window_features()->exclusive_access_manager()->OnTabClosing(
      old_contents);
  SessionServiceBase* session_service =
      GetAppropriateSessionServiceForProfile(this);
  if (session_service) {
    session_service->TabClosing(old_contents);
  }
  OnTabInsertedAt(new_contents, index);

  if (!new_contents->GetController().IsInitialBlankNavigation()) {
    // Send out notification so that observers are updated appropriately.
    int entry_count = new_contents->GetController().GetEntryCount();
    new_contents->GetController().NotifyEntryChanged(
        new_contents->GetController().GetEntryAtIndex(entry_count - 1));
  }

  if (session_service) {
    // The new_contents may end up with a different navigation stack. Force
    // the session service to update itself.
    session_service->TabRestored(new_contents,
                                 tab_strip_model_->IsTabPinned(index));
  }
}

void Browser::OnDevToolsAvailabilityChanged() {
  for (auto& agent_host : content::DevToolsAgentHost::GetAll()) {
    if (!DevToolsWindow::AllowDevToolsFor(profile_,
                                          agent_host->GetWebContents())) {
      agent_host->ForceDetachAllSessions();
    }
  }
}

///////////////////////////////////////////////////////////////////////////////
// Browser, UI update coalescing and handling (private):

void Browser::UpdateToolbar(bool should_restore_state) {
  TRACE_EVENT0("ui", "Browser::UpdateToolbar");
  window_->UpdateToolbar(should_restore_state
                             ? tab_strip_model_->GetActiveWebContents()
                             : nullptr);
}

void Browser::UpdateToolbarSecurityState() {
  TRACE_EVENT0("ui", "Browser::UpdateToolbarSecurityState");
  window_->UpdateToolbarSecurityState();
}

void Browser::ScheduleUIUpdate(WebContents* source, unsigned changed_flags) {
  DCHECK(source);
  // WebContents may in some rare cases send updates after they've been detached
  // from the tabstrip but before they are deleted, causing a potential crash if
  // we proceed. For now bail out.
  // TODO(crbug.com/40100269) Figure out a safe way to detach browser delegate
  // from WebContents when it's removed so this doesn't happen - then put a
  // DCHECK back here.
  if (tab_strip_model_->GetIndexOfWebContents(source) ==
      TabStripModel::kNoTab) {
    return;
  }

  // Do some synchronous updates.
  if (changed_flags & content::INVALIDATE_TYPE_URL) {
    if (source == tab_strip_model_->GetActiveWebContents()) {
      // Only update the URL for the current tab. Note that we do not update
      // the navigation commands since those would have already been updated
      // synchronously by NavigationStateChanged.
      UpdateToolbar(false);
    } else {
      // Clear the saved tab state for the tab that navigated, so that we don't
      // restore any user text after the old URL has been invalidated (e.g.,
      // after a new navigation commits in that tab while unfocused).
      window_->ResetToolbarTabState(source);
    }
    changed_flags &= ~content::INVALIDATE_TYPE_URL;
  }

  if (changed_flags & content::INVALIDATE_TYPE_LOAD) {
    // Update the loading state synchronously. This is so the throbber will
    // immediately start/stop, which gives a more snappy feel. We want to do
    // this for any tab so they start & stop quickly.
    tab_strip_model_->UpdateWebContentsStateAt(
        tab_strip_model_->GetIndexOfWebContents(source),
        TabChangeType::kLoadingOnly);
    // The status bubble needs to be updated during INVALIDATE_TYPE_LOAD too,
    // but we do that asynchronously by not stripping INVALIDATE_TYPE_LOAD from
    // changed_flags.
  }

  // If the only updates were synchronously handled above, we're done.
  if (changed_flags == 0) {
    return;
  }

  // Save the dirty bits.
  scheduled_updates_[source] |= changed_flags;

  if (!chrome_updater_factory_.HasWeakPtrs()) {
    base::TimeDelta delay = update_ui_immediately_for_testing_
                                ? base::Milliseconds(0)
                                : kUIUpdateCoalescingTime;
    // No task currently scheduled, start another.
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&Browser::ProcessPendingUIUpdates,
                       chrome_updater_factory_.GetWeakPtr()),
        delay);
  }
}

void Browser::ProcessPendingUIUpdates() {
#ifndef NDEBUG
  // Validate that all tabs we have pending updates for exist. This is scary
  // because the pending list must be kept in sync with any detached or
  // deleted tabs.
  for (UpdateMap::const_iterator i = scheduled_updates_.begin();
       i != scheduled_updates_.end(); ++i) {
    bool found = false;
    for (int tab = 0; tab < tab_strip_model_->count(); tab++) {
      if (tab_strip_model_->GetWebContentsAt(tab) == i->first) {
        found = true;
        break;
      }
    }
    DCHECK(found);
  }
#endif

  chrome_updater_factory_.InvalidateWeakPtrs();

  for (UpdateMap::const_iterator i = scheduled_updates_.begin();
       i != scheduled_updates_.end(); ++i) {
    // Do not dereference |contents|, it may be out-of-date!
    const WebContents* contents = i->first;
    unsigned flags = i->second;

    if (contents == tab_strip_model_->GetActiveWebContents()) {
      // Updates that only matter when the tab is selected go here.

      // Updating the URL happens synchronously in ScheduleUIUpdate.
      std::vector<StatusBubble*> status_bubbles = GetStatusBubbles();
      if (flags & content::INVALIDATE_TYPE_LOAD && status_bubbles.size() > 0) {
        status_bubbles.front()->SetStatus(
            CoreTabHelper::FromWebContents(
                tab_strip_model_->GetActiveWebContents())
                ->GetStatusText());
      }

      if (flags &
          (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
        window_->UpdateTitleBar();
      }
    }

    // Updates that don't depend upon the selected state go here.
    if (flags & (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE |
                 content::INVALIDATE_TYPE_AUDIO)) {
      tab_strip_model_->UpdateWebContentsStateAt(
          tab_strip_model_->GetIndexOfWebContents(contents),
          TabChangeType::kAll);
    }

    // Update the bookmark bar and PWA install icon. It may happen that the tab
    // is crashed, and if so, the bookmark bar and PWA install icon should be
    // hidden.
    if (flags & content::INVALIDATE_TYPE_TAB) {
      // Update bookmark bar state with kTabState to handle tab state changes
      // (like crashes). This is different from kTabSwitch which is already
      // handled in Browser::OnActiveTabChanged().
      BookmarkBarController::From(this)->UpdateBookmarkBarState(
          BookmarkBarController::StateChangeReason::kTabState);

      // TODO(crbug.com/40122780): Ideally, we should simply ask the state to
      // update, and doing that in an appropriate and efficient manner.
      window()->UpdatePageActionIcon(PageActionIconType::kPwaInstall);
    }

    // We don't need to process INVALIDATE_STATE, since that's not visible.
  }

  scheduled_updates_.clear();
}

void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
  if (!contents) {
    return;
  }

  auto i = scheduled_updates_.find(contents);
  if (i != scheduled_updates_.end()) {
    scheduled_updates_.erase(i);
  }
}

void Browser::OnFileSelectedFromDialog(const GURL& url) {
  OpenURL(OpenURLParams(url, Referrer(), WindowOpenDisposition::CURRENT_TAB,
                        ui::PAGE_TRANSITION_TYPED, false),
          /*navigation_handle_callback=*/{});
}

///////////////////////////////////////////////////////////////////////////////
// Browser, Getters for UI (private):

std::vector<StatusBubble*> Browser::GetStatusBubbles() {
  // For kiosk and exclusive app mode we want to always hide the status bubble.
  if (IsRunningInAppMode()) {
    return {};
  }

  // We hide the status bar for web apps windows as this matches native
  // experience. However, we include the status bar for 'minimal-ui' display
  // mode, as the minimal browser UI includes the status bar.
  auto* const app_browser_controller = app_controller();
  if (app_browser_controller &&
      !app_browser_controller->HasMinimalUiButtons()) {
    return {};
  }

  if (window_) {
    return window_->GetStatusBubbles();
  } else {
    return {};
  }
}

chrome::BrowserCommandController* Browser::GetCommandController() {
  return GetFeatures().browser_command_controller();
}

///////////////////////////////////////////////////////////////////////////////
// Browser, Session restore functions (private):

void Browser::SyncHistoryWithTabs(int index) {
  SessionServiceBase* service = GetAppropriateSessionServiceForProfile(this);

  SessionService* session_service =
      SessionServiceFactory::GetForProfileIfExisting(profile());

  if (!service && !session_service) {
    return;
  }

  for (int i = index; i < tab_strip_model_->count(); ++i) {
    WebContents* web_contents = tab_strip_model_->GetWebContentsAt(i);
    if (web_contents) {
      SessionID tab_id = sessions::SessionTabHelper::IdForTab(web_contents);
      if (service) {
        service->SetPinnedState(session_id(), tab_id,
                                tab_strip_model_->IsTabPinned(i));
      }

      if (!IsRelevantToAppSessionService(type_) && session_service) {
        session_service->SetTabIndexInWindow(session_id(), tab_id, i);

        std::optional<tab_groups::TabGroupId> group_id =
            tab_strip_model_->GetTabGroupForTab(i);
        session_service->SetTabGroup(session_id(), tab_id, std::move(group_id));
      }
    }
  }
}

///////////////////////////////////////////////////////////////////////////////
// Browser, In-progress download termination handling (private):

bool Browser::CanCloseWithInProgressDownloads() {
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
  // On Mac and ChromeOS, non-incognito and non-Guest downloads can still
  // continue after window is closed.
  if (!profile_->IsOffTheRecord()) {
    return true;
  }
#endif

  // If we've prompted, we need to hear from the user before we
  // can close.
  if (cancel_download_confirmation_state_ !=
      CancelDownloadConfirmationState::kNotPrompted) {
    return cancel_download_confirmation_state_ !=
           CancelDownloadConfirmationState::kWaitingForResponse;
  }

  int num_downloads_blocking;
  DownloadCloseType dialog_type =
      OkToCloseWithInProgressDownloads(&num_downloads_blocking);
  if (dialog_type == DownloadCloseType::kOk) {
    return true;
  }

  // Closing this window will kill some downloads; prompt to make sure
  // that's ok.
  cancel_download_confirmation_state_ =
      CancelDownloadConfirmationState::kWaitingForResponse;
  window_->ConfirmBrowserCloseWithPendingDownloads(
      num_downloads_blocking, dialog_type,
      base::BindOnce(&Browser::InProgressDownloadResponse,
                     weak_factory_.GetWeakPtr()));

  // Return false so the browser does not close.  We'll close if the user
  // confirms in the dialog.
  return false;
}

void Browser::InProgressDownloadResponse(bool cancel_downloads) {
  if (cancel_downloads) {
    cancel_download_confirmation_state_ =
        CancelDownloadConfirmationState::kResponseReceived;

    if (ShouldShowCookieMigrationNoticeForBrowser(*this)) {
      ShowCookieClearOnExitMigrationNotice(
          *this, base::BindOnce(&Browser::CookieMigrationNoticeResponse,
                                weak_factory_.GetWeakPtr()));
    } else {
      std::move(warn_before_closing_callback_)
          .Run(WarnBeforeClosingResult::kOkToClose);
    }
    return;
  }

  // Sets the confirmation state to
  // CancelDownloadConfirmationState::kNotPrompted so that if the user tries to
  // close again we'll show the warning again.
  cancel_download_confirmation_state_ =
      CancelDownloadConfirmationState::kNotPrompted;

  // Show the download page so the user can figure-out what downloads are still
  // in-progress.
  chrome::ShowDownloads(this);

  std::move(warn_before_closing_callback_)
      .Run(WarnBeforeClosingResult::kDoNotClose);
}

void Browser::CookieMigrationNoticeResponse(bool proceed_closing) {
  std::move(warn_before_closing_callback_)
      .Run(proceed_closing ? WarnBeforeClosingResult::kOkToClose
                           : WarnBeforeClosingResult::kDoNotClose);
}

void Browser::FinishWarnBeforeClosing(WarnBeforeClosingResult result) {
  switch (result) {
    case WarnBeforeClosingResult::kOkToClose:
      chrome::CloseWindow(this);
      break;
    case WarnBeforeClosingResult::kDoNotClose:
      // Reset UnloadController::is_attempting_to_close_browser_ so that we
      // don't prompt every time any tab is closed. http://crbug.com/305516
      unload_controller_.CancelWindowClose();
  }
}

///////////////////////////////////////////////////////////////////////////////
// Browser, Assorted utility functions (private):

void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
  Browser* delegate = set_delegate ? this : nullptr;

  // WebContents...
  web_contents->SetDelegate(delegate);

  // ...and all the helpers.
  WebContentsModalDialogManager::FromWebContents(web_contents)
      ->SetDelegate(delegate);
  zoom::ZoomController* zoom_controller =
      zoom::ZoomController::FromWebContents(web_contents);
  if (delegate) {
    zoom_controller->AddObserver(this);
    BookmarkTabHelper::FromWebContents(web_contents)->AddObserver(this);
    web_contents_collection_.StartObserving(web_contents);
  } else {
    zoom_controller->RemoveObserver(this);
    BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this);
    web_contents_collection_.StopObserving(web_contents);
  }
}

void Browser::TabDetachedAtImpl(content::WebContents* contents,
                                bool was_active,
                                DetachType type) {
  if (type == DetachType::kDetach) {
    // Save the current location bar state, but only if the tab being detached
    // is the selected tab.  Because saving state can conditionally revert the
    // location bar, saving the current tab's location bar state to a
    // non-selected tab can corrupt both tabs.
    if (was_active) {
      LocationBar* location_bar = window()->GetLocationBar();
      if (location_bar) {
        location_bar->SaveStateToContents(contents);
      }
    }

    if (!tab_strip_model_->closing_all()) {
      SyncHistoryWithTabs(0);
    }
  }

  SetAsDelegate(contents, false);
  RemoveScheduledUpdatesFor(contents);

  if (HasFindBarController() && was_active) {
    CreateOrGetFindBarController()->ChangeWebContents(nullptr);
  }
}

void Browser::UpdateWindowForLoadingStateChanged(content::WebContents* source,
                                                 bool should_show_loading_ui) {
  window_->UpdateLoadingAnimations(/* is_visible=*/!window_->IsMinimized());
  window_->UpdateTitleBar();

  WebContents* selected_contents = tab_strip_model_->GetActiveWebContents();
  if (source == selected_contents) {
    bool is_loading = source->IsLoading() && should_show_loading_ui;
    GetCommandController()->LoadingStateChanged(is_loading, false);

    std::vector<StatusBubble*> status_bubbles = GetStatusBubbles();
    if (status_bubbles.size() > 0) {
      status_bubbles.front()->SetStatus(
          CoreTabHelper::FromWebContents(selected_contents)->GetStatusText());
    }
  }
}

bool Browser::NormalBrowserSupportsWindowFeature(WindowFeature feature,
                                                 bool check_can_support) const {
  const base::FunctionRef<bool(const Browser*)> fullscreen =
      MaybeLazyIsFullscreen(this);
  switch (feature) {
    case WindowFeature::kFeatureBookmarkBar:
      return true;
    case WindowFeature::kFeatureTabStrip:
    case WindowFeature::kFeatureToolbar:
    case WindowFeature::kFeatureLocationBar:
      return check_can_support || !fullscreen(this);
    case WindowFeature::kFeatureTitleBar:
    case WindowFeature::kFeatureNone:
      return false;
  }
}

bool Browser::PopupBrowserSupportsWindowFeature(WindowFeature feature,
                                                bool check_can_support) const {
  const base::FunctionRef<bool(const Browser*)> fullscreen =
      MaybeLazyIsFullscreen(this);
  switch (feature) {
    case WindowFeature::kFeatureTitleBar:
    case WindowFeature::kFeatureLocationBar:
      return check_can_support || (!fullscreen(this) && !is_trusted_source());
    case WindowFeature::kFeatureTabStrip:
    case WindowFeature::kFeatureToolbar:
    case WindowFeature::kFeatureBookmarkBar:
    case WindowFeature::kFeatureNone:
      return false;
  }
}

bool Browser::AppPopupBrowserSupportsWindowFeature(
    WindowFeature feature,
    bool check_can_support) const {
  const base::FunctionRef<bool(const Browser*)> fullscreen =
      MaybeLazyIsFullscreen(this);
  switch (feature) {
    case WindowFeature::kFeatureTitleBar:
      return check_can_support || !fullscreen(this);
    case WindowFeature::kFeatureLocationBar:
      return app_controller() && (check_can_support || !fullscreen(this));
    default:
      return PopupBrowserSupportsWindowFeature(feature, check_can_support);
  }
}

bool Browser::AppBrowserSupportsWindowFeature(WindowFeature feature,
                                              bool check_can_support) const {
  auto* const app_browser_controller = app_controller();
  DCHECK(app_browser_controller);
  const base::FunctionRef<bool(const Browser*)> fullscreen =
      MaybeLazyIsFullscreen(this);
  switch (feature) {
    // Web apps should always support the toolbar, so the title/origin of the
    // current page can be shown when browsing a url that is not inside the app.
    // Note: Final determination of whether or not the toolbar is shown is made
    // by the |AppBrowserController|.
    // TODO(crbug.com/40639933): Make this control the visibility of Browser
    // Controls more generally.
    case WindowFeature::kFeatureToolbar:
      return true;
    case WindowFeature::kFeatureTitleBar:
    // TODO(crbug.com/40639933): Make this control the visibility of
    // CustomTabBarView.
    case WindowFeature::kFeatureLocationBar:
      return check_can_support || !fullscreen(this);
    case WindowFeature::kFeatureTabStrip:
      // Even when the app has a tab strip, it should be hidden in
      // fullscreen. This is consistent with the behavior of
      // NormalBrowserSupportsWindowFeature().
      return app_browser_controller->has_tab_strip() &&
             (check_can_support || !fullscreen(this));
    case WindowFeature::kFeatureBookmarkBar:
    case WindowFeature::kFeatureNone:
      return false;
  }
}

#if BUILDFLAG(IS_CHROMEOS)
// TODO(b/64863368): Consider Fullscreen mode.
bool Browser::CustomTabBrowserSupportsWindowFeature(
    WindowFeature feature) const {
  switch (feature) {
    case WindowFeature::kFeatureToolbar:
      return true;
    case WindowFeature::kFeatureTitleBar:
    case WindowFeature::kFeatureLocationBar:
    case WindowFeature::kFeatureTabStrip:
    case WindowFeature::kFeatureBookmarkBar:
    case WindowFeature::kFeatureNone:
      return false;
  }
}
#endif

bool Browser::PictureInPictureBrowserSupportsWindowFeature(
    WindowFeature feature,
    bool check_can_support) const {
  switch (feature) {
    case WindowFeature::kFeatureTitleBar:
      return true;
    case WindowFeature::kFeatureLocationBar:
    case WindowFeature::kFeatureTabStrip:
    case WindowFeature::kFeatureToolbar:
    case WindowFeature::kFeatureBookmarkBar:
    case WindowFeature::kFeatureNone:
      return false;
  }
}

bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
                                        bool check_can_support) const {
  switch (type_) {
    case TYPE_NORMAL:
      return NormalBrowserSupportsWindowFeature(feature, check_can_support);
    case TYPE_POPUP:
      return PopupBrowserSupportsWindowFeature(feature, check_can_support);
    case TYPE_APP:
      if (app_controller()) {
        return AppBrowserSupportsWindowFeature(feature, check_can_support);
      }
      // TODO(crbug.com/40639933): Change legacy apps to TYPE_APP_POPUP.
      return AppPopupBrowserSupportsWindowFeature(feature, check_can_support);
    case TYPE_DEVTOOLS:
    case TYPE_APP_POPUP:
      return AppPopupBrowserSupportsWindowFeature(feature, check_can_support);
#if BUILDFLAG(IS_CHROMEOS)
    case TYPE_CUSTOM_TAB:
      return CustomTabBrowserSupportsWindowFeature(feature);
#endif
    case TYPE_PICTURE_IN_PICTURE:
      return PictureInPictureBrowserSupportsWindowFeature(feature,
                                                          check_can_support);
  }
}

bool Browser::ShouldCreateBackgroundContents(
    content::SiteInstance* source_site_instance,
    const GURL& opener_url,
    const std::string& frame_name) {
  extensions::ExtensionSystem* extension_system =
      extensions::ExtensionSystem::Get(profile_);

  if (!opener_url.is_valid() || frame_name.empty() ||
      !extension_system->is_ready()) {
    return false;
  }

  // Only hosted apps have web extents, so this ensures that only hosted apps
  // can create BackgroundContents. We don't have to check for background
  // permission as that is checked in RenderMessageFilter when the CreateWindow
  // message is processed.
  const Extension* extension = extensions::ExtensionRegistry::Get(profile_)
                                   ->enabled_extensions()
                                   .GetHostedAppByURL(opener_url);
  if (!extension) {
    return false;
  }

  // No BackgroundContents allowed if BackgroundContentsService doesn't exist.
  BackgroundContentsService* service =
      BackgroundContentsServiceFactory::GetForProfile(profile_);
  if (!service) {
    return false;
  }

  // Ensure that we're trying to open this from the extension's process.
  extensions::ProcessMap* process_map = extensions::ProcessMap::Get(profile_);
  if (!source_site_instance->HasProcess() ||
      !process_map->Contains(
          extension->id(),
          source_site_instance->GetProcess()->GetDeprecatedID())) {
    return false;
  }

  return true;
}

BackgroundContents* Browser::CreateBackgroundContents(
    content::SiteInstance* source_site_instance,
    content::RenderFrameHost* opener,
    const GURL& opener_url,
    bool is_new_browsing_instance,
    const std::string& frame_name,
    const GURL& target_url,
    const content::StoragePartitionConfig& partition_config,
    content::SessionStorageNamespace* session_storage_namespace) {
  BackgroundContentsService* service =
      BackgroundContentsServiceFactory::GetForProfile(profile_);
  const Extension* extension = extensions::ExtensionRegistry::Get(profile_)
                                   ->enabled_extensions()
                                   .GetHostedAppByURL(opener_url);
  bool allow_js_access = extensions::BackgroundInfo::AllowJSAccess(extension);
  // Only allow a single background contents per app.
  BackgroundContents* existing =
      service->GetAppBackgroundContents(extension->id());
  if (existing) {
    // For non-scriptable background contents, ignore the request altogether,
    // Note that ShouldCreateBackgroundContents() returning true will also
    // suppress creation of the normal WebContents.
    if (!allow_js_access) {
      return nullptr;
    }
    // For scriptable background pages, if one already exists, close it (even
    // if it was specified in the manifest).
    service->DeleteBackgroundContents(existing);
  }

  // Passed all the checks, so this should be created as a BackgroundContents.
  if (allow_js_access) {
    return service->CreateBackgroundContents(
        source_site_instance, opener, is_new_browsing_instance, frame_name,
        extension->id(), partition_config, session_storage_namespace);
  }

  // If script access is not allowed, create the the background contents in a
  // new SiteInstance, so that a separate process is used. We must not use any
  // of the passed-in routing IDs, as they are objects in the opener's
  // process.
  BackgroundContents* contents = service->CreateBackgroundContents(
      content::SiteInstance::Create(source_site_instance->GetBrowserContext()),
      nullptr, is_new_browsing_instance, frame_name, extension->id(),
      partition_config, session_storage_namespace);

  // When a separate process is used, the original renderer cannot access the
  // new window later, thus we need to navigate the window now.
  contents->web_contents()->GetController().LoadURL(
      target_url, content::Referrer(), ui::PAGE_TRANSITION_LINK,
      std::string());  // No extra headers.

  return contents;
}

FindBarController* Browser::CreateOrGetFindBarController() {
  return GetFeatures().GetFindBarController();
}

bool Browser::HasFindBarController() {
  return GetFeatures().HasFindBarController();
}

Browser::ScopedWindowCallToActionImpl::ScopedWindowCallToActionImpl(
    Browser* browser)
    : browser_(browser->weak_factory_.GetWeakPtr()) {
  DCHECK(!browser_->showing_call_to_action_);
  browser_->showing_call_to_action_ = true;
}

Browser::ScopedWindowCallToActionImpl::~ScopedWindowCallToActionImpl() {
  browser_->showing_call_to_action_ = false;
}
