blob: 25ab77d11fddc8d797c0f7013d4772fe86d36844 [file] [log] [blame]
// Copyright 2024 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_window/public/browser_window_features.h"
#include <memory>
#include "base/check_is_test.h"
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "chrome/browser/actor/ui/actor_border_view_controller.h"
#include "chrome/browser/actor/ui/actor_overlay_window_controller.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/collaboration/collaboration_service_factory.h"
#include "chrome/browser/commerce/shopping_service_factory.h"
#include "chrome/browser/devtools/devtools_ui_controller.h"
#include "chrome/browser/enterprise/data_protection/data_protection_ui_controller.h"
#include "chrome/browser/extensions/browser_extension_window_controller.h"
#include "chrome/browser/extensions/manifest_v2_experiment_manager.h"
#include "chrome/browser/extensions/mv2_experiment_stage.h"
#include "chrome/browser/lens/region_search/lens_region_search_controller.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_group_sync/tab_group_sync_service_factory.h"
#include "chrome/browser/ui/bookmarks/bookmark_bar_controller.h"
#include "chrome/browser/ui/breadcrumb_manager_browser_agent.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_actions.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h"
#include "chrome/browser/ui/browser_element_identifiers.h"
#include "chrome/browser/ui/browser_instant_controller.h"
#include "chrome/browser/ui/browser_live_tab_context.h"
#include "chrome/browser/ui/browser_location_bar_model_delegate.h"
#include "chrome/browser/ui/browser_select_file_dialog_controller.h"
#include "chrome/browser/ui/browser_tab_menu_model_delegate.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/browser_window/public/desktop_browser_window_capabilities.h"
#include "chrome/browser/ui/commerce/product_specifications_entry_point_controller.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/extensions/mv2_disabled_dialog_controller.h"
#include "chrome/browser/ui/find_bar/find_bar.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/lens/lens_overlay_entry_point_controller.h"
#include "chrome/browser/ui/performance_controls/memory_saver_bubble_controller.h"
#include "chrome/browser/ui/performance_controls/memory_saver_opt_in_iph_controller.h"
#include "chrome/browser/ui/signin/signin_view_controller.h"
#include "chrome/browser/ui/sync/browser_synced_window_delegate.h"
#include "chrome/browser/ui/tabs/features.h"
#include "chrome/browser/ui/tabs/glic_nudge_controller.h"
#include "chrome/browser/ui/tabs/organization/tab_declutter_controller.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/most_recent_shared_tab_update_store.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/session_service_tab_group_sync_observer.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/shared_tab_group_feedback_controller.h"
#include "chrome/browser/ui/tabs/split_tab_highlight_controller.h"
#include "chrome/browser/ui/tabs/tab_group_deletion_dialog_controller.h"
#include "chrome/browser/ui/tabs/tab_list_bridge.h"
#include "chrome/browser/ui/tabs/tab_strip_api/tab_strip_service_impl.h"
#include "chrome/browser/ui/tabs/vertical_tab_strip_state_controller.h"
#include "chrome/browser/ui/toasts/toast_controller.h"
#include "chrome/browser/ui/toasts/toast_features.h"
#include "chrome/browser/ui/toasts/toast_service.h"
#include "chrome/browser/ui/toolbar/chrome_labs/chrome_labs_utils.h"
#include "chrome/browser/ui/toolbar/pinned_toolbar/tab_search_toolbar_button_controller.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/color_provider_browser_helper.h"
#include "chrome/browser/ui/views/data_sharing/data_sharing_bubble_controller.h"
#include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/contents_border_controller.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
#include "chrome/browser/ui/views/frame/scrim_view_controller.h"
#include "chrome/browser/ui/views/frame/tab_strip_region_view.h"
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h"
#include "chrome/browser/ui/views/incognito_clear_browsing_data_dialog_coordinator.h"
#include "chrome/browser/ui/views/interaction/browser_elements_views_impl.h"
#include "chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/media_router/cast_browser_controller.h"
#include "chrome/browser/ui/views/new_tab_footer/footer_controller.h"
#include "chrome/browser/ui/views/profiles/profile_menu_coordinator.h"
#include "chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_bubble_controller.h"
#include "chrome/browser/ui/views/side_panel/bookmarks/bookmarks_side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/comments/comments_side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/extensions/extension_side_panel_manager.h"
#include "chrome/browser/ui/views/side_panel/history/history_side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/reading_list/reading_list_side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
#include "chrome/browser/ui/views/tabs/recent_activity_bubble_dialog_view.h"
#include "chrome/browser/ui/views/tabs/tab_strip_action_container.h"
#include "chrome/browser/ui/views/toolbar/chrome_labs/chrome_labs_coordinator.h"
#include "chrome/browser/ui/views/toolbar/pinned_toolbar_actions_controller.h"
#include "chrome/browser/ui/views/translate/translate_bubble_controller.h"
#include "chrome/browser/ui/views/upgrade_notification_controller.h"
#include "chrome/browser/ui/views/user_education/impl/browser_user_education_interface_impl.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/ui/webui_browser/browser_elements_webui_browser.h"
#include "chrome/browser/ui/webui_browser/webui_browser.h"
#include "chrome/browser/ui/webui_browser/webui_browser_side_panel_ui.h"
#include "chrome/browser/ui/webui_browser/webui_browser_window.h"
#include "chrome/common/chrome_features.h"
#include "components/breadcrumbs/core/breadcrumbs_status.h"
#include "components/collaboration/public/collaboration_service.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/feature_utils.h"
#include "components/commerce/core/shopping_service.h"
#include "components/lens/lens_features.h"
#include "components/omnibox/browser/location_bar_model.h"
#include "components/omnibox/browser/location_bar_model_impl.h"
#include "components/prefs/pref_service.h"
#include "components/profile_metrics/browser_profile_type.h"
#include "components/saved_tab_groups/public/features.h"
#include "components/search/ntp_features.h"
#include "components/search/search.h"
#include "content/public/common/content_constants.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/extension_browser_window_helper.h"
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#include "chrome/browser/ui/pdf/infobar/pdf_infobar_controller.h"
#include "chrome/browser/ui/startup/default_browser_prompt/pin_infobar/pin_infobar_controller.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "chrome/browser/ui/views/frame/windows_taskbar_icon_updater.h"
#endif
#if !BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/download/bubble/download_bubble_ui_controller.h"
#include "chrome/browser/download/bubble/download_display_controller.h"
#include "chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.h"
#endif
#if BUILDFLAG(ENABLE_GLIC)
#include "chrome/browser/glic/browser_ui/glic_button_controller.h"
#include "chrome/browser/glic/browser_ui/glic_iph_controller.h"
#include "chrome/browser/glic/public/glic_enabling.h"
#include "chrome/browser/glic/public/glic_keyed_service.h"
#include "chrome/browser/glic/widget/glic_side_panel_coordinator.h"
#include "chrome/browser/ui/tabs/glic_actor_task_icon_controller.h"
#endif
#if defined(USE_AURA)
#include "chrome/browser/ui/overscroll_pref_manager.h"
#endif // defined(USE_AURA)
BrowserWindowFeatures::BrowserWindowFeatures() = default;
BrowserWindowFeatures::~BrowserWindowFeatures() = default;
void BrowserWindowFeatures::Init(BrowserWindowInterface* browser) {
// This is used only for the controllers which will be created on demand
// later.
browser_ = browser;
app_browser_controller_ = web_app::MaybeCreateAppBrowserController(browser);
browser_actions_ = std::make_unique<BrowserActions>(browser);
browser_command_controller_ =
std::make_unique<chrome::BrowserCommandController>(browser);
browser_actions_->InitializeBrowserActions();
if (webui_browser::IsWebUIBrowserEnabled()) {
browser_elements_ =
GetUserDataFactory().CreateInstance<BrowserElementsWebUiBrowser>(
*browser, *browser);
} else {
browser_elements_ =
GetUserDataFactory().CreateInstance<BrowserElementsViewsImpl>(*browser,
*browser);
}
// Initialize bookmark bar controller for all browser types.
bookmark_bar_controller_ =
GetUserDataFactory().CreateInstance<BookmarkBarController>(
*browser, *browser, *browser->GetTabStripModel());
// Avoid passing `browser` directly to features. Instead, pass the minimum
// necessary state or controllers necessary.
// Ping erikchen for assistance. This comment will be deleted after there are
// 10+ features.
//
// Features that are only enabled for normal browser windows (e.g. a window
// with an omnibox and a tab strip). By default most features should be
// instantiated in this block.
Profile* const profile = browser->GetProfile();
if (browser->GetType() == BrowserWindowInterface::Type::TYPE_NORMAL) {
if (search::IsInstantExtendedAPIEnabled()) {
instant_controller_ = std::make_unique<BrowserInstantController>(
profile, browser->GetTabStripModel());
}
if (profile->IsRegularProfile()) {
auto* shopping_service =
commerce::ShoppingServiceFactory::GetForBrowserContext(profile);
if (shopping_service && commerce::CanLoadProductSpecificationsFullPageUi(
shopping_service->GetAccountChecker())) {
product_specifications_entry_point_controller_ =
GetUserDataFactory()
.CreateInstance<
commerce::ProductSpecificationsEntryPointController>(
*browser, browser);
}
}
if (profile->IsRegularProfile() &&
browser->GetTabStripModel()->SupportsTabGroups() &&
tab_groups::TabGroupSyncServiceFactory::GetForProfile(profile)) {
session_service_tab_group_sync_observer_ =
std::make_unique<tab_groups::SessionServiceTabGroupSyncObserver>(
profile, browser->GetTabStripModel(), browser->GetSessionID());
most_recent_shared_tab_update_store_ =
std::make_unique<tab_groups::MostRecentSharedTabUpdateStore>(browser);
}
if (features::IsTabstripDeclutterEnabled() &&
(profile->IsRegularProfile() || profile->IsGuestSession())) {
tab_declutter_controller_ =
std::make_unique<tabs::TabDeclutterController>(browser);
}
#if BUILDFLAG(ENABLE_GLIC)
if (glic::GlicEnabling::IsProfileEligible(profile)) {
DCHECK(features::HasTabSearchToolbarButton());
glic_iph_controller_ = std::make_unique<glic::GlicIphController>(browser);
glic_nudge_controller_ =
std::make_unique<tabs::GlicNudgeController>(browser);
}
#endif // BUILDFLAG(ENABLE_GLIC)
if (tabs::AreVerticalTabsEnabled()) {
vertical_tab_strip_state_controller_ =
std::make_unique<tabs::VerticalTabStripStateController>(
profile->GetPrefs());
}
}
// The LensOverlayEntryPointController is constructed for all browser types
// but is only initialized for normal browser windows. This simplifies the
// logic for code shared by both normal and non-normal windows.
lens_overlay_entry_point_controller_ =
std::make_unique<lens::LensOverlayEntryPointController>();
lens_region_search_controller_ =
std::make_unique<lens::LensRegionSearchController>();
tab_strip_model_ = browser->GetTabStripModel();
tab_strip_service_ =
std::make_unique<TabStripServiceImpl>(browser, tab_strip_model_);
memory_saver_bubble_controller_ =
std::make_unique<memory_saver::MemorySaverBubbleController>(browser);
translate_bubble_controller_ =
GetUserDataFactory().CreateInstance<TranslateBubbleController>(
*browser, browser, browser_actions_->root_action_item());
cookie_controls_bubble_coordinator_ =
GetUserDataFactory().CreateInstance<CookieControlsBubbleCoordinator>(
*browser, browser);
tab_menu_model_delegate_ =
std::make_unique<chrome::BrowserTabMenuModelDelegate>(
browser->GetSessionID(), profile, app_browser_controller_.get());
tab_group_deletion_dialog_controller_ =
std::make_unique<tab_groups::DeletionDialogController>(browser, profile,
tab_strip_model_);
user_education_ =
GetUserDataFactory().CreateInstance<BrowserUserEducationInterfaceImpl>(
*browser, browser);
location_bar_model_delegate_ =
std::make_unique<BrowserLocationBarModelDelegate>(tab_strip_model_);
location_bar_model_ = std::make_unique<LocationBarModelImpl>(
location_bar_model_delegate_.get(), content::kMaxURLDisplayChars);
reading_list_side_panel_coordinator_ =
std::make_unique<ReadingListSidePanelCoordinator>(
profile, browser->GetTabStripModel());
bookmarks_side_panel_coordinator_ =
std::make_unique<BookmarksSidePanelCoordinator>();
signin_view_controller_ = std::make_unique<SigninViewController>(
browser, profile, tab_strip_model_);
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
if (base::FeatureList::IsEnabled(features::kPdfInfoBar)) {
pdf_infobar_controller_ =
std::make_unique<pdf::infobar::PdfInfoBarController>(browser);
}
if (base::FeatureList::IsEnabled(features::kOfferPinToTaskbarInfoBar)) {
pin_infobar_controller_ =
std::make_unique<default_browser::PinInfoBarController>(browser);
}
#endif
data_sharing_bubble_controller_ =
std::make_unique<DataSharingBubbleController>(browser, profile,
tab_strip_model_);
content_setting_bubble_model_delegate_ =
std::make_unique<BrowserContentSettingBubbleModelDelegate>(browser);
tab_list_bridge_ = std::make_unique<TabListBridge>(
*tab_strip_model_, browser->GetUnownedUserDataHost());
#if BUILDFLAG(ENABLE_EXTENSIONS)
extension_browser_window_helper_ =
std::make_unique<extensions::ExtensionBrowserWindowHelper>(
browser_command_controller_.get(), browser->GetTabStripModel(),
profile);
#endif
if (breadcrumbs::IsEnabled(g_browser_process->local_state())) {
breadcrumb_manager_browser_agent_ =
std::make_unique<BreadcrumbManagerBrowserAgent>(
browser->GetTabStripModel(), profile);
}
#if defined(USE_AURA)
overscroll_pref_manager_ = std::make_unique<OverscrollPrefManager>(
tab_strip_model_,
browser->GetType() == BrowserWindowInterface::Type::TYPE_DEVTOOLS);
#endif // defined(USE_AURA)
if (features::kGlicActorUiBorderGlow.Get()) {
actor_border_view_controller_ =
std::make_unique<ActorBorderViewController>(browser);
}
browser_select_file_dialog_controller_ =
std::make_unique<BrowserSelectFileDialogController>(profile);
}
void BrowserWindowFeatures::InitPostWindowConstruction(Browser* browser) {
desktop_browser_window_capabilities_ =
GetUserDataFactory().CreateInstance<DesktopBrowserWindowCapabilities>(
*browser, browser, browser->window(),
browser->GetUnownedUserDataHost());
exclusive_access_manager_ = std::make_unique<ExclusiveAccessManager>(
browser->window()->GetExclusiveAccessContext());
// This code needs exclusive access manager to be initialized.
#if !BUILDFLAG(IS_CHROMEOS)
if (download_toolbar_ui_controller_) {
download_toolbar_ui_controller_->display_controller()
->ListenToFullScreenChanges();
}
#endif
Profile* const profile = browser_->GetProfile();
// Features that are only enabled for normal browser windows (e.g. a window
// with an omnibox and a tab strip). By default most features should be
// instantiated in this block.
if (browser->is_type_normal()) {
BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
if (IsChromeLabsEnabled()) {
chrome_labs_coordinator_ =
std::make_unique<ChromeLabsCoordinator>(browser);
}
send_tab_to_self_toolbar_bubble_controller_ = std::make_unique<
send_tab_to_self::SendTabToSelfToolbarBubbleController>(browser);
if (browser_view) {
// Initialize fullscreen control host after exclusive access manager is
// ready.
fullscreen_control_host_ = std::make_unique<FullscreenControlHost>(
browser_view, exclusive_access_manager_.get());
// The controller should only be created if the
// PinnedToolbarActionsContainer exists for the browser, this might not be
// the case for browsers with a custom tab toolbar.
if (auto* pinned_toolbar_actions_container =
browser_view->toolbar_button_provider()
->GetPinnedToolbarActionsContainer()) {
pinned_toolbar_actions_controller_ =
std::make_unique<PinnedToolbarActionsController>(
pinned_toolbar_actions_container);
}
}
// TODO(crbug.com/350508658): Ideally, we don't pass in a reference to
// browser as per the guidance in the comment above. However, currently,
// we need browser to properly determine if the lens overlay is enabled.
// Cannot be in Init since needs to listen to the fullscreen controller
// and location bar view which are initialized after Init.
if (lens::features::IsLensOverlayEnabled()) {
views::View* location_bar = nullptr;
// TODO(crbug.com/360163254): We should really be using
// Browser::GetBrowserView, which always returns a non-null BrowserView
// in production, but this crashes during unittests using
// BrowserWithTestWindowTest; these should eventually be refactored.
if (browser_view) {
location_bar = browser_view->GetLocationBarView();
}
lens_overlay_entry_point_controller_->Initialize(
browser, browser_command_controller_.get(), location_bar);
}
auto* experiment_manager =
extensions::ManifestV2ExperimentManager::Get(profile);
if (experiment_manager) {
extensions::MV2ExperimentStage experiment_stage =
experiment_manager->GetCurrentExperimentStage();
if (experiment_stage ==
extensions::MV2ExperimentStage::kDisableWithReEnable ||
experiment_stage == extensions::MV2ExperimentStage::kUnsupported) {
mv2_disabled_dialog_controller_ =
std::make_unique<extensions::Mv2DisabledDialogController>(browser);
}
}
if (features::HasTabSearchToolbarButton()) {
// TODO(crbug.com/360163254): We should really be using
// Browser::GetBrowserView, which always returns a non-null BrowserView
// in production, but this crashes during unittests using
// BrowserWithTestWindowTest; these should eventually be refactored.
if (browser_view) {
tab_search_toolbar_button_controller_ =
std::make_unique<TabSearchToolbarButtonController>(
browser_view, browser_view->GetTabSearchBubbleHost());
}
}
if (browser->GetTabStripModel()->SupportsTabGroups() &&
tab_groups::SavedTabGroupUtils::SupportsSharedTabGroups() &&
tab_groups::TabGroupSyncServiceFactory::GetForProfile(profile)) {
if (browser_view) {
shared_tab_group_feedback_controller_ =
std::make_unique<tab_groups::SharedTabGroupFeedbackController>(
browser_view->browser());
shared_tab_group_feedback_controller_->Init();
}
recent_activity_bubble_coordinator_ =
GetUserDataFactory().CreateInstance<RecentActivityBubbleCoordinator>(
*browser, browser);
}
if (base::FeatureList::IsEnabled(features::kSideBySide)) {
if (browser_view) {
split_tab_highlight_controller_ =
std::make_unique<split_tabs::SplitTabHighlightController>(
browser_view);
}
}
}
synced_window_delegate_ = std::make_unique<BrowserSyncedWindowDelegate>(
browser, browser->GetTabStripModel(), browser->GetSessionID(),
browser->GetType());
extension_window_controller_ =
std::make_unique<extensions::BrowserExtensionWindowController>(browser);
profile_menu_coordinator_ =
std::make_unique<ProfileMenuCoordinator>(browser, profile);
upgrade_notification_controller_ =
std::make_unique<UpgradeNotificationController>(browser);
incognito_clear_browsing_data_dialog_coordinator_ =
std::make_unique<IncognitoClearBrowsingDataDialogCoordinator>(profile);
if (auto* browser_view = BrowserView::GetBrowserViewForBrowser(browser)) {
color_provider_browser_helper_ =
std::make_unique<ColorProviderBrowserHelper>(
browser->GetTabStripModel(), browser_view->GetWidget());
}
live_tab_context_ = std::make_unique<BrowserLiveTabContext>(
browser, browser->GetTabStripModel(), profile, browser->GetWindow(),
browser->GetType(), browser->app_name(), browser->GetSessionID());
if (browser->is_type_normal() || browser->is_type_app()) {
toast_service_ = std::make_unique<ToastService>(browser);
}
if (BrowserView* const browser_view =
BrowserView::GetBrowserViewForBrowser(browser)) {
contents_border_controller_ =
std::make_unique<ContentsBorderController>(browser_view);
// Focus manager can be null in tests.
if (views::FocusManager* focus_manager = browser_view->GetFocusManager()) {
extension_keybinding_registry_ =
std::make_unique<ExtensionKeybindingRegistryViews>(
profile, focus_manager,
extensions::ExtensionKeybindingRegistry::ALL_EXTENSIONS,
browser_view);
}
// BrowserView is an AcceleratorProvider.
accelerator_provider_ = browser_view;
}
if (auto* const provider =
browser_elements_->AsA<BrowserElementsWebUiBrowser>()) {
provider->Init(views::Widget::GetWidgetForNativeWindow(
browser->window()->GetNativeWindow()));
}
if (WebUIBrowserWindow* webui_browser_window =
WebUIBrowserWindow::FromBrowser(browser)) {
webui_browser_side_panel_ui_ =
std::make_unique<WebUIBrowserSidePanelUI>(browser);
// WebUIBrowserWindow is an AcceleratorProvider.
accelerator_provider_ = webui_browser_window;
}
}
void BrowserWindowFeatures::InitPostBrowserViewConstruction(
BrowserView* browser_view) {
if (auto* const provider =
browser_elements_->AsA<BrowserElementsViewsImpl>()) {
provider->Init(browser_view);
}
scrim_view_controller_ = std::make_unique<ScrimViewController>(browser_view);
// TODO(crbug.com/346148093): Move SidePanelCoordinator construction to Init.
// TODO(crbug.com/346148554): Do not create a SidePanelCoordinator for most
// browser.h types
// Conceptually, SidePanelCoordinator handles the "model" whereas
// BrowserView::unified_side_panel_ handles the "ui". When we stop making this
// for most browser.h types, we should also stop making the
// unified_side_panel_.
side_panel_coordinator_ =
std::make_unique<SidePanelCoordinator>(browser_view);
if (HistorySidePanelCoordinator::IsSupported()) {
history_side_panel_coordinator_ =
std::make_unique<HistorySidePanelCoordinator>(browser_view->browser());
}
history_clusters_side_panel_coordinator_ =
std::make_unique<HistoryClustersSidePanelCoordinator>(
browser_, browser_->GetProfile(), side_panel_coordinator_.get());
if (CommentsSidePanelCoordinator::IsSupported()) {
comments_side_panel_coordinator_ =
std::make_unique<CommentsSidePanelCoordinator>(browser_view->browser());
}
#if BUILDFLAG(ENABLE_GLIC)
glic_side_panel_coordinator_ =
std::make_unique<glic::GlicSidePanelCoordinator>();
#endif // BUILDFLAG(ENABLE_GLIC)
side_panel_coordinator_->Init(browser_view->browser());
extension_side_panel_manager_ =
std::make_unique<extensions::ExtensionSidePanelManager>(
browser_view->browser(),
side_panel_coordinator_->GetWindowRegistry());
immersive_mode_controller_ =
chrome::CreateImmersiveModeController(browser_view);
if (browser_view->GetIsNormalType()) {
#if BUILDFLAG(ENABLE_GLIC)
glic::GlicKeyedService* glic_service =
glic::GlicKeyedService::Get(browser_view->GetProfile());
if (glic_service) {
glic_button_controller_ = std::make_unique<glic::GlicButtonController>(
browser_view->GetProfile(),
BrowserElementsViews::From(browser_view->browser())
->GetViewAs<TabStripActionContainer>(
kTabStripActionContainerElementId),
glic_service);
if (features::kGlicActorUiTaskIcon.Get() &&
browser_->GetProfile()->IsRegularProfile()) {
// Includes browser twice to enable injecting for testing.
glic_actor_task_icon_controller_ =
GetUserDataFactory()
.CreateInstance<tabs::GlicActorTaskIconController>(
*browser_, browser_,
BrowserElementsViews::From(browser_view->browser())
->GetViewAs<TabStripActionContainer>(
kTabStripActionContainerElementId));
}
}
#endif // BUILDFLAG(ENABLE_GLIC)
// Memory Saver mode is default off but is available to turn on.
// The controller relies on performance manager which isn't initialized in
// some unit tests without browser view.
memory_saver_opt_in_iph_controller_ =
std::make_unique<MemorySaverOptInIPHController>(
browser_view->browser());
if (media_router::MediaRouterEnabled(browser_view->browser()->profile())) {
cast_browser_controller_ =
std::make_unique<media_router::CastBrowserController>(
browser_view->browser());
}
if (features::kGlicActorUiOverlay.Get()) {
std::vector<std::pair<views::WebView*, views::View*>>
container_overlay_view_pairs;
for (auto* contents_container :
browser_view->GetContentsContainerViews()) {
container_overlay_view_pairs.emplace_back(
contents_container->contents_view(),
contents_container->actor_overlay_view());
}
actor_overlay_window_controller_ =
GetUserDataFactory().CreateInstance<ActorOverlayWindowController>(
*browser_, browser_, std::move(container_overlay_view_pairs));
}
data_protection_ui_controller_ =
GetUserDataFactory()
.CreateInstance<
enterprise_data_protection::DataProtectionUIController>(
*browser_view->browser(), browser_view);
}
#if !BUILDFLAG(IS_CHROMEOS)
download_toolbar_ui_controller_ =
std::make_unique<DownloadToolbarUIController>(browser_view);
#endif
if (base::FeatureList::IsEnabled(ntp_features::kNtpFooter)) {
new_tab_footer_controller_ =
std::make_unique<new_tab_footer::NewTabFooterController>(
browser_view->browser()->GetProfile(),
browser_view->GetContentsContainerViews());
}
devtools_ui_controller_ = std::make_unique<DevtoolsUIController>(
browser_view->GetContentsContainerViews());
#if BUILDFLAG(IS_WIN)
windows_taskbar_icon_updater_ =
std::make_unique<WindowsTaskbarIconUpdater>(*browser_view);
#endif
user_education_->Init(browser_view);
}
void BrowserWindowFeatures::TearDownPreBrowserWindowDestruction() {
accelerator_provider_ = nullptr;
extension_keybinding_registry_.reset();
contents_border_controller_.reset();
live_tab_context_.reset();
upgrade_notification_controller_.reset();
memory_saver_opt_in_iph_controller_.reset();
lens_overlay_entry_point_controller_.reset();
tab_search_toolbar_button_controller_.reset();
profile_menu_coordinator_.reset();
toast_service_.reset();
extension_window_controller_.reset();
actor_border_view_controller_.reset();
actor_overlay_window_controller_.reset();
#if BUILDFLAG(ENABLE_GLIC)
glic_button_controller_.reset();
glic_actor_task_icon_controller_.reset();
#endif
#if !BUILDFLAG(IS_CHROMEOS)
if (download_toolbar_ui_controller_) {
download_toolbar_ui_controller_->TearDownPreBrowserWindowDestruction();
}
#endif
comments_side_panel_coordinator_.reset();
history_clusters_side_panel_coordinator_.reset();
// TODO(crbug.com/346148093): This logic should not be gated behind a
// conditional.
if (side_panel_coordinator_) {
side_panel_coordinator_->TearDownPreBrowserWindowDestruction();
}
if (mv2_disabled_dialog_controller_) {
mv2_disabled_dialog_controller_->TearDown();
}
color_provider_browser_helper_.reset();
if (shared_tab_group_feedback_controller_) {
shared_tab_group_feedback_controller_->TearDown();
}
if (chrome_labs_coordinator_) {
chrome_labs_coordinator_->TearDown();
}
if (new_tab_footer_controller_) {
new_tab_footer_controller_->TearDown();
}
if (devtools_ui_controller_) {
devtools_ui_controller_->TearDown();
}
data_protection_ui_controller_.reset();
desktop_browser_window_capabilities_.reset();
signin_view_controller_->TearDownPreBrowserWindowDestruction();
// Destroy fullscreen control host before exclusive access manager.
fullscreen_control_host_.reset();
if (pinned_toolbar_actions_controller_) {
pinned_toolbar_actions_controller_->TearDown();
}
// TODO(crbug.com/423956131): Update reset order once FindBarController is
// deterministically constructed.
find_bar_controller_.reset();
split_tab_highlight_controller_.reset();
#if BUILDFLAG(IS_WIN)
windows_taskbar_icon_updater_.reset();
#endif
if (user_education_) {
user_education_->TearDown();
}
immersive_mode_controller_.reset();
exclusive_access_manager_.reset();
scrim_view_controller_.reset();
if (auto* const provider = browser_elements_->AsA<BrowserElementsViews>()) {
provider->TearDown();
}
}
SidePanelUI* BrowserWindowFeatures::side_panel_ui() {
if (webui_browser::IsWebUIBrowserEnabled()) {
return webui_browser_side_panel_ui_.get();
}
return side_panel_coordinator_.get();
}
ToastController* BrowserWindowFeatures::toast_controller() {
return toast_service_ ? toast_service_->toast_controller() : nullptr;
}
FindBarController* BrowserWindowFeatures::GetFindBarController() {
if (!find_bar_controller_.get()) {
CHECK(browser_);
find_bar_controller_ = std::make_unique<FindBarController>(
browser_->GetBrowserForMigrationOnly()->window()->CreateFindBar());
find_bar_controller_->find_bar()->SetFindBarController(
find_bar_controller_.get());
find_bar_controller_->ChangeWebContents(
tab_strip_model_->GetActiveWebContents());
find_bar_controller_->find_bar()->MoveWindowIfNecessary();
}
return find_bar_controller_.get();
}
bool BrowserWindowFeatures::HasFindBarController() const {
return find_bar_controller_.get() != nullptr;
}
// static
ui::UserDataFactoryWithOwner<BrowserWindowInterface>&
BrowserWindowFeatures::GetUserDataFactoryForTesting() {
return GetUserDataFactory();
}
// static
ui::UserDataFactoryWithOwner<BrowserWindowInterface>&
BrowserWindowFeatures::GetUserDataFactory() {
static base::NoDestructor<
ui::UserDataFactoryWithOwner<BrowserWindowInterface>>
factory;
return *factory;
}