Files
brave-core/browser/ui/brave_browser_command_controller.cc
Darnell Andries 075088f2a4 Add Email Aliases metrics (#36469)
* Add metrics for Email Aliases

* Add notes and copy metrics for email aliases

* Presubmit fix

* fix ups

* Add tests

* Address PR feedback

* Pass metrics remote as a prop
2026-05-28 11:37:29 -07:00

876 lines
30 KiB
C++

/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/browser/ui/brave_browser_command_controller.h"
#include <optional>
#include "base/check.h"
#include "base/check_is_test.h"
#include "base/containers/fixed_flat_set.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/types/to_address.h"
#include "brave/app/brave_command_ids.h"
#include "brave/browser/profiles/profile_util.h"
#include "brave/browser/ui/brave_pages.h"
#include "brave/browser/ui/browser_commands.h"
#include "brave/browser/ui/focus_mode/focus_mode_utils.h"
#include "brave/browser/ui/sidebar/sidebar_utils.h"
#include "brave/browser/workspaces/features.h"
#include "brave/browser/workspaces/workspace_service.h"
#include "brave/browser/workspaces/workspace_service_factory.h"
#include "brave/components/ai_chat/core/common/buildflags/buildflags.h"
#include "brave/components/brave_news/common/buildflags/buildflags.h"
#include "brave/components/brave_rewards/core/rewards_util.h"
#include "brave/components/brave_talk/buildflags/buildflags.h"
#include "brave/components/brave_vpn/common/buildflags/buildflags.h"
#include "brave/components/brave_wallet/common/buildflags/buildflags.h"
#include "brave/components/brave_wayback_machine/buildflags/buildflags.h"
#include "brave/components/commander/common/buildflags/buildflags.h"
#include "brave/components/commands/common/features.h"
#include "brave/components/constants/pref_names.h"
#include "brave/components/containers/buildflags/buildflags.h"
#include "brave/components/email_aliases/buildflags/buildflags.h"
#include "brave/components/playlist/core/common/buildflags/buildflags.h"
#include "brave/components/speedreader/common/buildflags/buildflags.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
#include "chrome/browser/ui/tabs/features.h"
#include "chrome/browser/ui/tabs/tab_change_type.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/sync/base/command_line_switches.h"
#include "content/public/browser/web_contents.h"
#if BUILDFLAG(ENABLE_AI_CHAT)
#include "brave/browser/ai_chat/ai_chat_utils.h"
#include "brave/components/ai_chat/core/browser/utils.h"
#include "brave/components/ai_chat/core/common/features.h"
#include "brave/components/ai_chat/core/common/pref_names.h"
#endif
#if BUILDFLAG(ENABLE_BRAVE_VPN)
#include "brave/browser/brave_vpn/brave_vpn_service_factory.h"
#include "brave/browser/brave_vpn/vpn_utils.h"
#include "brave/components/brave_vpn/browser/brave_vpn_service.h"
#include "brave/components/brave_vpn/common/pref_names.h"
#endif
#if BUILDFLAG(ENABLE_SPEEDREADER)
#include "brave/components/speedreader/common/features.h"
#endif
#if BUILDFLAG(ENABLE_PLAYLIST_WEBUI)
#include "brave/browser/playlist/playlist_service_factory.h"
#include "brave/components/playlist/core/browser/utils.h"
#endif
#if BUILDFLAG(ENABLE_COMMANDER)
#include "brave/browser/ui/commander/commander_service.h"
#endif
#if BUILDFLAG(ENABLE_TOR)
#include "brave/browser/tor/tor_profile_service_factory.h"
#endif
#if BUILDFLAG(ENABLE_BRAVE_NEWS)
#include "brave/components/brave_news/common/pref_names.h"
#endif
#if BUILDFLAG(ENABLE_BRAVE_TALK)
#include "brave/components/brave_talk/pref_names.h"
#endif
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
#endif
#if BUILDFLAG(ENABLE_EMAIL_ALIASES)
#include "brave/browser/email_aliases/email_aliases_service_factory.h"
#include "brave/browser/ui/email_aliases/email_aliases_controller.h"
#include "brave/components/email_aliases/features.h"
#endif
#if BUILDFLAG(ENABLE_CONTAINERS)
#include "brave/browser/containers/containers_service_factory.h"
#endif
namespace {
bool IsBraveCommands(int id) {
return id >= IDC_BRAVE_COMMANDS_START && id <= IDC_BRAVE_COMMANDS_LAST;
}
bool IsBraveOverrideCommands(int id) {
static constexpr auto kOverrideCommands = base::MakeFixedFlatSet<int>({
IDC_NEW_WINDOW,
IDC_NEW_INCOGNITO_WINDOW,
IDC_TOGGLE_VERTICAL_TABS,
});
return kOverrideCommands.contains(id);
}
} // namespace
namespace chrome {
BraveBrowserCommandController::BraveBrowserCommandController(
BrowserWindowInterface* bwi)
: BrowserCommandController(bwi),
browser_(*bwi->GetBrowserForMigrationOnly()),
brave_command_updater_(nullptr) {
InitBraveCommandState();
#if BUILDFLAG(ENABLE_BRAVE_VPN)
if (auto* vpn_service = brave_vpn::BraveVpnServiceFactory::GetForProfile(
browser_->profile())) {
brave_vpn::BraveVPNServiceObserver::Observe(vpn_service);
}
#endif
}
BraveBrowserCommandController::~BraveBrowserCommandController() = default;
void BraveBrowserCommandController::OnTabChangedAt(tabs::TabInterface* tab,
int index,
TabChangeType change_type) {
BrowserCommandController::OnTabChangedAt(tab, index, change_type);
UpdateCommandEnabled(IDC_CLOSE_DUPLICATE_TABS,
brave::HasDuplicateTabs(&*browser_));
UpdateCommandsForTabs();
UpdateCommandsForSend();
}
void BraveBrowserCommandController::OnTabPinnedStateChanged(
tabs::TabInterface* tab,
int index) {
UpdateCommandsForPin();
}
void BraveBrowserCommandController::OnTabStripModelChanged(
TabStripModel* tab_strip_model,
const TabStripModelChange& change,
const TabStripSelectionChange& selection) {
BrowserCommandController::OnTabStripModelChanged(tab_strip_model, change,
selection);
UpdateCommandEnabled(IDC_WINDOW_CLOSE_TABS_TO_LEFT,
brave::CanCloseTabsToLeft(&*browser_));
UpdateCommandEnabled(IDC_CLOSE_DUPLICATE_TABS,
brave::HasDuplicateTabs(&*browser_));
UpdateCommandsForTabs();
UpdateCommandsForSend();
UpdateCommandsForPin();
if (browser_->is_type_normal() && selection.active_tab_changed()) {
UpdateCommandForSplitView();
}
}
void BraveBrowserCommandController::OnSplitTabChanged(
const SplitTabChange& change) {
UpdateCommandForSplitView();
}
void BraveBrowserCommandController::OnTabGroupChanged(
const TabGroupChange& change) {
UpdateCommandsForTabs();
}
bool BraveBrowserCommandController::SupportsCommand(int id) const {
return IsBraveCommands(id) ? brave_command_updater_.SupportsCommand(id)
: BrowserCommandController::SupportsCommand(id);
}
bool BraveBrowserCommandController::IsCommandEnabled(int id) const {
return IsBraveCommands(id) ? brave_command_updater_.IsCommandEnabled(id)
: BrowserCommandController::IsCommandEnabled(id);
}
bool BraveBrowserCommandController::ExecuteCommandWithDisposition(
int id,
WindowOpenDisposition disposition,
base::TimeTicks time_stamp) {
return IsBraveCommands(id) || IsBraveOverrideCommands(id)
? ExecuteBraveCommandWithDisposition(id, disposition, time_stamp)
: BrowserCommandController::ExecuteCommandWithDisposition(
id, disposition, time_stamp);
}
void BraveBrowserCommandController::AddCommandObserver(
int id,
CommandObserver* observer) {
IsBraveCommands(id)
? brave_command_updater_.AddCommandObserver(id, observer)
: BrowserCommandController::AddCommandObserver(id, observer);
}
void BraveBrowserCommandController::RemoveCommandObserver(
int id,
CommandObserver* observer) {
IsBraveCommands(id)
? brave_command_updater_.RemoveCommandObserver(id, observer)
: BrowserCommandController::RemoveCommandObserver(id, observer);
}
void BraveBrowserCommandController::RemoveCommandObserver(
CommandObserver* observer) {
brave_command_updater_.RemoveCommandObserver(observer);
BrowserCommandController::RemoveCommandObserver(observer);
}
bool BraveBrowserCommandController::UpdateCommandEnabled(int id, bool state) {
return IsBraveCommands(id)
? brave_command_updater_.UpdateCommandEnabled(id, state)
: BrowserCommandController::UpdateCommandEnabled(id, state);
}
void BraveBrowserCommandController::InitBraveCommandState() {
// Sync, Rewards, and Wallet pages don't work in tor(guest) sessions.
// They also don't work in private windows but they are redirected
// to a normal window in this case.
const bool is_guest_session = browser_->profile()->IsGuestSession();
if (!is_guest_session) {
// If Rewards is not supported due to OFAC sanctions we still want to show
// the menu item.
if (brave_rewards::IsSupported(browser_->profile()->GetPrefs())) {
UpdateCommandForBraveRewards();
}
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
if (brave_wallet::IsAllowed(browser_->profile()->GetPrefs())) {
UpdateCommandForBraveWallet();
}
#endif
if (syncer::IsSyncAllowedByFlag()) {
UpdateCommandForBraveSync();
}
}
UpdateCommandForWebcompatReporter();
#if BUILDFLAG(ENABLE_TOR)
UpdateCommandForTor();
#endif
UpdateCommandForSidebar();
UpdateCommandForBraveVPN();
UpdateCommandForPlaylist();
UpdateCommandForWaybackMachine();
pref_change_registrar_.Init(browser_->profile()->GetPrefs());
#if BUILDFLAG(ENABLE_AI_CHAT)
UpdateCommandForAIChat();
if (ai_chat::IsAllowedForContext(browser_->profile(), false)) {
pref_change_registrar_.Add(
ai_chat::prefs::kEnabledByPolicy,
base::BindRepeating(
&BraveBrowserCommandController::UpdateCommandForAIChat,
base::Unretained(this)));
}
#endif
#if BUILDFLAG(ENABLE_BRAVE_VPN)
if (brave_vpn::IsAllowedForContext(browser_->profile())) {
pref_change_registrar_.Add(
brave_vpn::prefs::kManagedBraveVPNDisabled,
base::BindRepeating(
&BraveBrowserCommandController::UpdateCommandForBraveVPN,
base::Unretained(this)));
}
#endif
bool add_new_profile_enabled = !is_guest_session;
bool open_guest_profile_enabled = !is_guest_session;
if (!is_guest_session) {
if (PrefService* local_state = g_browser_process->local_state()) {
add_new_profile_enabled =
local_state->GetBoolean(prefs::kBrowserAddPersonEnabled);
open_guest_profile_enabled =
local_state->GetBoolean(prefs::kBrowserGuestModeEnabled);
}
}
UpdateCommandEnabled(IDC_ADD_NEW_PROFILE, add_new_profile_enabled);
UpdateCommandEnabled(IDC_OPEN_GUEST_PROFILE, open_guest_profile_enabled);
UpdateCommandEnabled(IDC_COPY_CLEAN_LINK, true);
UpdateCommandEnabled(IDC_TOGGLE_TAB_MUTE, true);
#if BUILDFLAG(ENABLE_SPEEDREADER)
if (base::FeatureList::IsEnabled(
speedreader::features::kSpeedreaderFeature)) {
UpdateCommandEnabled(IDC_SPEEDREADER_ICON_ONCLICK, true);
}
#endif
#if BUILDFLAG(ENABLE_COMMANDER)
UpdateCommandEnabled(IDC_COMMANDER, commander::IsEnabled());
#endif
UpdateCommandEnabled(IDC_SHOW_APPS_PAGE,
!browser_->profile()->IsPrimaryOTRProfile());
UpdateCommandEnabled(IDC_BRAVE_BOOKMARK_BAR_SUBMENU, true);
UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS_WINDOW_TITLE, true);
UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS_EXPANDED, true);
#if BUILDFLAG(ENABLE_BRAVE_NEWS)
UpdateCommandEnabled(IDC_CONFIGURE_BRAVE_NEWS,
!browser_->profile()->IsOffTheRecord() &&
!browser_->profile()->GetPrefs()->GetBoolean(
brave_news::prefs::kBraveNewsDisabledByPolicy));
#endif // BUILDFLAG(ENABLE_BRAVE_NEWS)
UpdateCommandEnabled(
IDC_CONFIGURE_SHORTCUTS,
base::FeatureList::IsEnabled(commands::features::kBraveCommands));
#if BUILDFLAG(ENABLE_BRAVE_TALK)
UpdateCommandEnabled(IDC_SHOW_BRAVE_TALK,
!browser_->profile()->GetPrefs()->GetBoolean(
brave_talk::prefs::kDisabledByPolicy));
#endif
UpdateCommandEnabled(IDC_TOGGLE_SHIELDS, true);
UpdateCommandEnabled(IDC_TOGGLE_JAVASCRIPT, true);
UpdateCommandEnabled(IDC_CLOSE_DUPLICATE_TABS,
brave::HasDuplicateTabs(&*browser_));
UpdateCommandEnabled(IDC_WINDOW_ADD_ALL_TABS_TO_NEW_GROUP, true);
UpdateCommandEnabled(IDC_SCROLL_TAB_TO_TOP, true);
UpdateCommandEnabled(IDC_SCROLL_TAB_TO_BOTTOM, true);
UpdateCommandEnabled(IDC_BRAVE_SEND_TAB_TO_SELF, true);
UpdateCommandsForTabs();
UpdateCommandsForSend();
UpdateCommandsForPin();
UpdateCommandEnabled(IDC_TOGGLE_ALL_BOOKMARKS_BUTTON_VISIBILITY, true);
UpdateCommandEnabled(IDC_EXPORT_ALL_BOOKMARKS, true);
#if BUILDFLAG(ENABLE_EMAIL_ALIASES)
UpdateCommandEnabled(
IDC_SHOW_EMAIL_ALIASES,
email_aliases::features::IsEmailAliasesEnabled() &&
email_aliases::EmailAliasesServiceFactory::GetServiceForProfile(
browser_->profile()));
#endif
#if BUILDFLAG(ENABLE_CONTAINERS)
UpdateCommandEnabled(
IDC_NEW_TEMPORARY_CONTAINER,
ContainersServiceFactory::GetForProfile(browser_->profile()));
#endif
// Reload options if person has an update in workspaces
if (base::FeatureList::IsEnabled(features::kWorkspaces) &&
browser_->is_type_normal()) {
UpdateCommandForWorkspace();
pref_change_registrar_.Add(
kWorkspacesMetadataPref,
base::BindRepeating(
&BraveBrowserCommandController::UpdateCommandForWorkspace,
base::Unretained(this)));
}
if (browser_->is_type_normal()) {
// Delete these when upstream enables by default.
UpdateCommandEnabled(IDC_READING_LIST_MENU, true);
UpdateCommandEnabled(IDC_READING_LIST_MENU_ADD_TAB, true);
UpdateCommandEnabled(IDC_READING_LIST_MENU_SHOW_UI, true);
}
UpdateCommandEnabled(IDC_FORCE_PASTE, true);
UpdateCommandForFocusMode();
}
void BraveBrowserCommandController::UpdateCommandsForFullscreenMode() {
BrowserCommandController::UpdateCommandsForFullscreenMode();
// On macOS, we block vertical tab mode toggling in fullscreen.
// Immersive fullscreen feeature is enabled by default but
// it's not compatible with vertical tab. See the comments in
// BraveBrowserView::UsesImmersiveFullscreenMode() for more datail. Otherwise,
// crash happens when turn on vertical tab while fullscreen.
#if BUILDFLAG(IS_MAC)
UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS,
window() && !window()->IsFullscreen());
#endif
}
void BraveBrowserCommandController::UpdateCommandForBraveRewards() {
UpdateCommandEnabled(IDC_SHOW_BRAVE_REWARDS, true);
}
void BraveBrowserCommandController::UpdateCommandForWebcompatReporter() {
UpdateCommandEnabled(IDC_SHOW_BRAVE_WEBCOMPAT_REPORTER, true);
}
#if BUILDFLAG(ENABLE_TOR)
void BraveBrowserCommandController::UpdateCommandForTor() {
// Enable new tor connection only for tor profile.
UpdateCommandEnabled(IDC_NEW_TOR_CONNECTION_FOR_SITE,
browser_->profile()->IsTor());
UpdateCommandEnabled(
IDC_NEW_OFFTHERECORD_WINDOW_TOR,
!TorProfileServiceFactory::IsTorDisabled(browser_->profile()));
}
#endif
void BraveBrowserCommandController::UpdateCommandForSidebar() {
if (sidebar::CanUseSidebar(&*browser_)) {
UpdateCommandEnabled(IDC_SIDEBAR_SHOW_OPTION_MENU, true);
UpdateCommandEnabled(IDC_SIDEBAR_TOGGLE_POSITION, true);
UpdateCommandEnabled(IDC_TOGGLE_SIDEBAR, true);
}
}
#if BUILDFLAG(ENABLE_AI_CHAT)
void BraveBrowserCommandController::UpdateCommandForAIChat() {
// AI Chat command implementation needs sidebar
bool allowed_for_context = ai_chat::IsAllowedForContext(browser_->profile());
UpdateCommandEnabled(IDC_TOGGLE_AI_CHAT, sidebar::CanUseSidebar(&*browser_) &&
allowed_for_context);
UpdateCommandEnabled(
IDC_OPEN_FULL_PAGE_CHAT,
ai_chat::features::IsAIChatHistoryEnabled() && allowed_for_context);
}
#endif
void BraveBrowserCommandController::UpdateCommandForBraveVPN() {
#if BUILDFLAG(ENABLE_BRAVE_VPN)
if (!brave_vpn::IsBraveVPNEnabled(browser_->profile())) {
UpdateCommandEnabled(IDC_SHOW_BRAVE_VPN_PANEL, false);
UpdateCommandEnabled(IDC_BRAVE_VPN_MENU, false);
UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN_TOOLBAR_BUTTON, false);
UpdateCommandEnabled(IDC_SEND_BRAVE_VPN_FEEDBACK, false);
UpdateCommandEnabled(IDC_ABOUT_BRAVE_VPN, false);
UpdateCommandEnabled(IDC_MANAGE_BRAVE_VPN_PLAN, false);
UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN, false);
#if BUILDFLAG(IS_WIN)
UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN_TRAY_ICON, false);
#endif
return;
}
UpdateCommandEnabled(IDC_SHOW_BRAVE_VPN_PANEL, true);
UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN_TOOLBAR_BUTTON, true);
#if BUILDFLAG(IS_WIN)
UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN_TRAY_ICON, true);
#endif
UpdateCommandEnabled(IDC_SEND_BRAVE_VPN_FEEDBACK, true);
UpdateCommandEnabled(IDC_ABOUT_BRAVE_VPN, true);
UpdateCommandEnabled(IDC_MANAGE_BRAVE_VPN_PLAN, true);
if (auto* vpn_service = brave_vpn::BraveVpnServiceFactory::GetForProfile(
browser_->profile())) {
// Only show vpn sub menu for purchased user.
UpdateCommandEnabled(IDC_BRAVE_VPN_MENU, vpn_service->IsPurchased());
UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN, vpn_service->IsPurchased());
}
#endif
}
void BraveBrowserCommandController::UpdateCommandForPlaylist() {
#if BUILDFLAG(ENABLE_PLAYLIST_WEBUI)
if (playlist::IsPlaylistAllowed(browser_->profile()->GetPrefs())) {
UpdateCommandEnabled(
IDC_SHOW_PLAYLIST_BUBBLE,
browser_->is_type_normal() &&
playlist::PlaylistServiceFactory::GetForBrowserContext(
browser_->profile()));
}
#endif
}
void BraveBrowserCommandController::UpdateCommandForWaybackMachine() {
#if BUILDFLAG(ENABLE_BRAVE_WAYBACK_MACHINE)
UpdateCommandEnabled(IDC_SHOW_WAYBACK_MACHINE_BUBBLE, true);
#endif
}
void BraveBrowserCommandController::UpdateCommandsForTabs() {
UpdateCommandEnabled(IDC_WINDOW_MUTE_ALL_TABS,
brave::CanMuteAllTabs(&*browser_, false));
UpdateCommandEnabled(IDC_WINDOW_MUTE_OTHER_TABS,
brave::CanMuteAllTabs(&*browser_, true));
UpdateCommandEnabled(IDC_WINDOW_UNMUTE_ALL_TABS,
brave::CanUnmuteAllTabs(&*browser_));
UpdateCommandEnabled(IDC_GROUP_TABS_ON_CURRENT_ORIGIN, true);
UpdateCommandEnabled(IDC_MOVE_GROUP_TO_NEW_WINDOW, true);
bool is_in_group = brave::IsInGroup(&*browser_);
bool has_ungrouped_tabs = brave::HasUngroupedTabs(&*browser_);
UpdateCommandEnabled(IDC_WINDOW_GROUP_UNGROUPED_TABS, has_ungrouped_tabs);
UpdateCommandEnabled(IDC_WINDOW_UNGROUP_GROUP, is_in_group);
UpdateCommandEnabled(IDC_WINDOW_REMOVE_TAB_FROM_GROUP, is_in_group);
UpdateCommandEnabled(IDC_WINDOW_NAME_GROUP, is_in_group);
UpdateCommandEnabled(IDC_WINDOW_NEW_TAB_IN_GROUP, is_in_group);
UpdateCommandEnabled(IDC_WINDOW_UNGROUP_ALL_TABS,
brave::CanUngroupAllTabs(&*browser_));
UpdateCommandEnabled(IDC_WINDOW_TOGGLE_GROUP_EXPANDED, is_in_group);
UpdateCommandEnabled(IDC_WINDOW_CLOSE_UNGROUPED_TABS, has_ungrouped_tabs);
UpdateCommandEnabled(IDC_WINDOW_CLOSE_TABS_NOT_IN_CURRENT_GROUP, is_in_group);
UpdateCommandEnabled(IDC_WINDOW_CLOSE_GROUP, is_in_group);
UpdateCommandEnabled(IDC_WINDOW_BRING_ALL_TABS,
brave::CanBringAllTabs(&*browser_));
}
void BraveBrowserCommandController::UpdateCommandsForSend() {
UpdateCommandEnabled(
IDC_BRAVE_SEND_TAB_TO_SELF,
send_tab_to_self::ShouldDisplayEntryPoint(
browser_->tab_strip_model()->GetActiveWebContents()));
}
void BraveBrowserCommandController::UpdateCommandsForPin() {
UpdateCommandEnabled(IDC_WINDOW_CLOSE_UNPINNED_TABS,
brave::CanCloseUnpinnedTabs(&*browser_));
}
void BraveBrowserCommandController::UpdateCommandForFocusMode() {
UpdateCommandEnabled(IDC_TOGGLE_FOCUS_MODE,
BrowserSupportsFocusMode(base::to_address(browser_)));
}
void BraveBrowserCommandController::UpdateCommandForSplitView() {
UpdateCommandEnabled(
IDC_NEW_SPLIT_VIEW,
brave::CanOpenNewSplitTabsWithSideBySide(base::to_address(browser_)));
UpdateCommandEnabled(IDC_TILE_TABS, brave::CanSplitTabsWithSideBySide(
base::to_address(browser_)));
const bool is_split_tabs = brave::IsSplitTabs(base::to_address(browser_));
for (auto command_enabled_when_tab_is_split :
{IDC_BREAK_TILE, IDC_SWAP_SPLIT_VIEW}) {
UpdateCommandEnabled(command_enabled_when_tab_is_split, is_split_tabs);
}
}
void BraveBrowserCommandController::UpdateCommandForWorkspace() {
auto* service = WorkspaceServiceFactory::GetForProfile(browser_->profile());
if (!service) {
return;
}
UpdateCommandEnabled(IDC_SAVE_WORKSPACE, true);
UpdateCommandEnabled(IDC_OPEN_WORKSPACE, !service->ListWorkspaces().empty());
}
void BraveBrowserCommandController::UpdateCommandForBraveSync() {
UpdateCommandEnabled(IDC_SHOW_BRAVE_SYNC, true);
}
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
void BraveBrowserCommandController::UpdateCommandForBraveWallet() {
UpdateCommandEnabled(IDC_SHOW_BRAVE_WALLET, true);
UpdateCommandEnabled(IDC_SHOW_BRAVE_WALLET_PANEL, true);
UpdateCommandEnabled(IDC_CLOSE_BRAVE_WALLET_PANEL, true);
}
#endif
bool BraveBrowserCommandController::ExecuteBraveCommandWithDisposition(
int id,
WindowOpenDisposition disposition,
base::TimeTicks time_stamp) {
if (!SupportsCommand(id) || !IsCommandEnabled(id)) {
return false;
}
if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab) {
return true;
}
DCHECK(IsCommandEnabled(id)) << "Invalid/disabled command " << id;
switch (id) {
case IDC_NEW_WINDOW:
// Use chromium's action for non-Tor profiles.
if (!browser_->profile()->IsTor()) {
return BrowserCommandController::ExecuteCommandWithDisposition(
id, disposition, time_stamp);
}
NewEmptyWindow(browser_->profile()->GetOriginalProfile());
break;
case IDC_NEW_INCOGNITO_WINDOW:
// Use chromium's action for non-Tor profiles.
if (!browser_->profile()->IsTor()) {
return BrowserCommandController::ExecuteCommandWithDisposition(
id, disposition, time_stamp);
}
NewIncognitoWindow(browser_->profile()->GetOriginalProfile());
break;
case IDC_SHOW_BRAVE_REWARDS:
brave::ShowBraveRewards(&*browser_);
break;
case IDC_SHOW_BRAVE_WEBCOMPAT_REPORTER:
brave::ShowWebcompatReporter(&*browser_);
break;
#if BUILDFLAG(ENABLE_TOR)
case IDC_NEW_OFFTHERECORD_WINDOW_TOR:
brave::NewOffTheRecordWindowTor(&*browser_);
break;
case IDC_NEW_TOR_CONNECTION_FOR_SITE:
brave::NewTorConnectionForSite(&*browser_);
break;
#endif
case IDC_SHOW_BRAVE_SYNC:
brave::ShowSync(&*browser_);
break;
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
case IDC_SHOW_BRAVE_WALLET:
brave::ShowBraveWallet(&*browser_);
break;
#endif
#if BUILDFLAG(ENABLE_AI_CHAT)
case IDC_TOGGLE_AI_CHAT:
brave::ToggleAIChat(&*browser_);
break;
case IDC_OPEN_FULL_PAGE_CHAT:
brave::ShowFullpageChat(&*browser_);
break;
#endif
case IDC_SPEEDREADER_ICON_ONCLICK:
brave::MaybeDistillAndShowSpeedreaderBubble(&*browser_);
break;
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
case IDC_SHOW_BRAVE_WALLET_PANEL:
brave::ShowWalletBubble(&*browser_);
break;
case IDC_CLOSE_BRAVE_WALLET_PANEL:
brave::CloseWalletBubble(&*browser_);
break;
#endif
case IDC_SHOW_BRAVE_VPN_PANEL:
brave::ShowBraveVPNBubble(&*browser_);
break;
case IDC_TOGGLE_BRAVE_VPN_TRAY_ICON:
brave::ToggleBraveVPNTrayIcon();
break;
case IDC_TOGGLE_BRAVE_VPN_TOOLBAR_BUTTON:
brave::ToggleBraveVPNButton(&*browser_);
break;
case IDC_SEND_BRAVE_VPN_FEEDBACK:
case IDC_ABOUT_BRAVE_VPN:
case IDC_MANAGE_BRAVE_VPN_PLAN:
brave::OpenBraveVPNUrls(&*browser_, id);
break;
case IDC_SIDEBAR_TOGGLE_POSITION:
brave::ToggleSidebarPosition(&*browser_);
break;
case IDC_TOGGLE_SIDEBAR:
brave::ToggleSidebar(&*browser_);
break;
case IDC_COPY_CLEAN_LINK:
brave::CopySanitizedURL(
&*browser_,
browser_->tab_strip_model()->GetActiveWebContents()->GetVisibleURL());
break;
case IDC_TOGGLE_TAB_MUTE:
brave::ToggleActiveTabAudioMute(&*browser_);
break;
case IDC_TOGGLE_VERTICAL_TABS:
brave::ToggleVerticalTabStrip(&*browser_);
break;
case IDC_TOGGLE_VERTICAL_TABS_WINDOW_TITLE:
brave::ToggleWindowTitleVisibilityForVerticalTabs(&*browser_);
break;
case IDC_TOGGLE_VERTICAL_TABS_EXPANDED:
brave::ToggleVerticalTabStripExpanded(&*browser_);
break;
#if BUILDFLAG(ENABLE_BRAVE_NEWS)
case IDC_CONFIGURE_BRAVE_NEWS:
brave::ShowBraveNewsConfigure(&*browser_);
break;
#endif // BUILDFLAG(ENABLE_BRAVE_NEWS)
case IDC_CONFIGURE_SHORTCUTS:
brave::ShowShortcutsPage(&*browser_);
break;
#if BUILDFLAG(ENABLE_BRAVE_TALK)
case IDC_SHOW_BRAVE_TALK:
brave::ShowBraveTalk(&*browser_);
break;
#endif
case IDC_TOGGLE_SHIELDS:
brave::ToggleShieldsEnabled(&*browser_);
break;
case IDC_TOGGLE_JAVASCRIPT:
brave::ToggleJavascriptEnabled(&*browser_);
break;
case IDC_SHOW_PLAYLIST_BUBBLE:
#if BUILDFLAG(ENABLE_PLAYLIST_WEBUI)
brave::ShowPlaylistBubble(&*browser_);
break;
#else
NOTREACHED() << " This command shouldn't be enabled";
#endif
case IDC_SHOW_WAYBACK_MACHINE_BUBBLE:
#if BUILDFLAG(ENABLE_BRAVE_WAYBACK_MACHINE)
brave::ShowWaybackMachineBubble(&*browser_);
#endif
break;
case IDC_GROUP_TABS_ON_CURRENT_ORIGIN:
brave::GroupTabsOnCurrentOrigin(&*browser_);
break;
case IDC_MOVE_GROUP_TO_NEW_WINDOW:
brave::MoveGroupToNewWindow(&*browser_);
break;
case IDC_CLOSE_DUPLICATE_TABS:
brave::CloseDuplicateTabs(&*browser_);
break;
case IDC_WINDOW_CLOSE_TABS_TO_LEFT:
brave::CloseTabsToLeft(&*browser_);
break;
case IDC_WINDOW_CLOSE_UNPINNED_TABS:
brave::CloseUnpinnedTabs(&*browser_);
break;
case IDC_WINDOW_ADD_ALL_TABS_TO_NEW_GROUP:
brave::AddAllTabsToNewGroup(&*browser_);
break;
case IDC_WINDOW_MUTE_ALL_TABS:
brave::MuteAllTabs(&*browser_, false);
break;
case IDC_WINDOW_MUTE_OTHER_TABS:
brave::MuteAllTabs(&*browser_, true);
break;
case IDC_WINDOW_UNMUTE_ALL_TABS:
brave::UnmuteAllTabs(&*browser_);
break;
case IDC_SCROLL_TAB_TO_TOP:
brave::ScrollTabToTop(&*browser_);
break;
case IDC_SCROLL_TAB_TO_BOTTOM:
brave::ScrollTabToBottom(&*browser_);
break;
case IDC_BRAVE_SEND_TAB_TO_SELF:
chrome::SendTabToSelf(&*browser_);
break;
case IDC_TOGGLE_ALL_BOOKMARKS_BUTTON_VISIBILITY:
brave::ToggleAllBookmarksButtonVisibility(base::to_address(browser_));
break;
case IDC_EXPORT_ALL_BOOKMARKS:
brave::ExportAllBookmarks(&*browser_);
break;
case IDC_COMMANDER:
#if BUILDFLAG(ENABLE_COMMANDER)
brave::ToggleCommander(base::to_address(browser_));
#endif
break;
case IDC_SHOW_APPS_PAGE:
brave::ShowAppsPage(&*browser_);
break;
#if BUILDFLAG(ENABLE_EMAIL_ALIASES)
case IDC_SHOW_EMAIL_ALIASES:
browser_->GetFeatures().email_aliases_controller()->OpenSettingsPage(
email_aliases::SettingsPageMethod::kAppMenu);
break;
#endif
#if BUILDFLAG(ENABLE_CONTAINERS)
case IDC_NEW_TEMPORARY_CONTAINER:
brave::CreateTemporaryContainerAndOpenUrl(base::to_address(browser_),
browser_->GetNewTabURL(),
/*is_link=*/false);
break;
#endif
case IDC_WINDOW_GROUP_UNGROUPED_TABS:
brave::GroupUngroupedTabs(&*browser_);
break;
case IDC_WINDOW_UNGROUP_GROUP:
brave::UngroupCurrentGroup(&*browser_);
break;
case IDC_WINDOW_REMOVE_TAB_FROM_GROUP:
brave::RemoveTabFromGroup(&*browser_);
break;
case IDC_WINDOW_UNGROUP_ALL_TABS:
brave::UngroupAllTabs(&*browser_);
break;
case IDC_WINDOW_NAME_GROUP:
brave::NameGroup(&*browser_);
break;
case IDC_WINDOW_NEW_TAB_IN_GROUP:
brave::NewTabInGroup(&*browser_);
break;
case IDC_WINDOW_TOGGLE_GROUP_EXPANDED:
brave::ToggleGroupExpanded(&*browser_);
break;
case IDC_WINDOW_CLOSE_UNGROUPED_TABS:
brave::CloseUngroupedTabs(&*browser_);
break;
case IDC_WINDOW_CLOSE_TABS_NOT_IN_CURRENT_GROUP:
brave::CloseTabsNotInCurrentGroup(&*browser_);
break;
case IDC_WINDOW_CLOSE_GROUP:
brave::CloseGroup(&*browser_);
break;
case IDC_WINDOW_BRING_ALL_TABS:
brave::BringAllTabs(&*browser_);
break;
case IDC_NEW_SPLIT_VIEW: {
chrome::NewSplitTab(base::to_address(browser_),
split_tabs::SplitTabCreatedSource::kToolbarButton);
break;
}
case IDC_TILE_TABS: {
brave::SplitTabsWithSideBySide(
base::to_address(browser_),
split_tabs::SplitTabCreatedSource::kToolbarButton);
break;
}
case IDC_BREAK_TILE: {
brave::RemoveSplitWithSideBySide(base::to_address(browser_));
break;
}
case IDC_SWAP_SPLIT_VIEW: {
brave::SwapTabsInSplitWithSideBySide(base::to_address(browser_));
break;
}
case IDC_FORCE_PASTE: {
brave::ForcePasteInBrowser(base::to_address(browser_));
break;
}
case IDC_TOGGLE_FOCUS_MODE:
brave::ToggleFocusMode(base::to_address(browser_));
break;
case IDC_SAVE_WORKSPACE:
if (auto* svc =
WorkspaceServiceFactory::GetForProfile(browser_->profile())) {
svc->ShowSaveWorkspaceDialog();
}
break;
case IDC_OPEN_WORKSPACE:
if (auto* svc =
WorkspaceServiceFactory::GetForProfile(browser_->profile())) {
svc->ShowOpenWorkspaceDialog();
}
break;
default:
LOG(WARNING) << "Received Unimplemented Command: " << id;
break;
}
return true;
}
#if BUILDFLAG(ENABLE_BRAVE_VPN)
void BraveBrowserCommandController::OnPurchasedStateChanged(
brave_vpn::mojom::PurchasedState state,
const std::optional<std::string>& description) {
UpdateCommandForBraveVPN();
}
#endif
} // namespace chrome