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

#include <stddef.h>

#include <string>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/debug/debugging_buildflags.h"
#include "base/debug/profiler.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/i18n/rtl.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/user_metrics.h"
#include "base/time/time.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/commerce/browser_utils.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/feedback/public/feedback_source.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/sessions/tab_restore_service_factory.h"
#include "chrome/browser/sharing_hub/sharing_hub_features.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_promo.h"
#include "chrome/browser/signin/signin_ui_util.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_actions.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_navigator.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/bubble_anchor_util.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/customize_chrome/side_panel_controller.h"
#include "chrome/browser/ui/lens/lens_overlay_controller.h"
#include "chrome/browser/ui/managed_ui.h"
#include "chrome/browser/ui/page_info/page_info_dialog.h"
#include "chrome/browser/ui/passwords/ui_utils.h"
#include "chrome/browser/ui/profiles/profile_picker.h"
#include "chrome/browser/ui/profiles/profile_view_utils.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.h"
#include "chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_prefs.h"
#include "chrome/browser/ui/tabs/features.h"
#include "chrome/browser/ui/tabs/public/tab_features.h"
#include "chrome/browser/ui/tabs/split_tab_metrics.h"
#include "chrome/browser/ui/tabs/tab_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_user_gesture_details.h"
#include "chrome/browser/ui/toolbar/chrome_labs/chrome_labs_utils.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry_id.h"
#include "chrome/browser/ui/views/side_panel/side_panel_ui.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h"
#include "chrome/browser/ui/webui/inspect/inspect_ui.h"
#include "chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_section.h"
#include "chrome/browser/web_applications/web_app_install_params.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/content_restriction.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "components/bookmarks/common/bookmark_pref_names.h"
#include "components/dom_distiller/core/dom_distiller_features.h"
#include "components/input/native_web_keyboard_event.h"
#include "components/lens/buildflags.h"
#include "components/password_manager/core/browser/manage_passwords_referrer.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/sessions/content/session_tab_helper.h"
#include "components/sessions/core/tab_restore_service.h"
#include "components/signin/public/base/signin_buildflags.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/translate/core/browser/translate_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/profiling.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/common/extension_urls.h"
#include "printing/buildflags/buildflags.h"
#include "ui/actions/actions.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/window_open_disposition.h"
#include "ui/events/keycodes/keyboard_codes.h"

#if BUILDFLAG(IS_MAC)
#include "chrome/browser/ui/browser_commands_mac.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#include "content/public/browser/gpu_data_manager.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/platform_util.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h"
#include "chrome/browser/ui/browser_commands_chromeos.h"
#include "components/session_manager/core/session_manager.h"
#include "components/user_manager/user_manager.h"
#endif

#if BUILDFLAG(IS_LINUX)
#include "ui/base/ime/text_edit_commands.h"
#include "ui/base/ime/text_input_flags.h"
#include "ui/linux/linux_ui.h"
#endif

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

#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
#include "chrome/browser/ui/shortcuts/desktop_shortcuts_utils.h"
#endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)

#if BUILDFLAG(ENABLE_GLIC)
#include "chrome/browser/glic/fre/glic_fre_controller.h"
#include "chrome/browser/glic/glic_enums.h"
#include "chrome/browser/glic/glic_pref_names.h"
#include "chrome/browser/glic/glic_profile_manager.h"
#include "chrome/browser/glic/public/glic_enabling.h"
#include "chrome/browser/glic/public/glic_keyed_service_factory.h"
#include "chrome/browser/glic/widget/glic_window_controller.h"
#endif

using WebExposedIsolationLevel = content::WebExposedIsolationLevel;

namespace chrome {

namespace {

// Ensures that - if we have not popped up an infobar to prompt the user to e.g.
// reload the current page - that the content pane of the browser is refocused.
void AppInfoDialogClosedCallback(SessionID session_id,
                                 views::Widget::ClosedReason closed_reason,
                                 bool reload_prompt) {
  if (reload_prompt) {
    return;
  }

  // If the user clicked on something specific or focus was changed, don't
  // override the focus.
  if (closed_reason != views::Widget::ClosedReason::kEscKeyPressed &&
      closed_reason != views::Widget::ClosedReason::kCloseButtonClicked) {
    return;
  }

  // Ensure that the session id we have is still valid. It's possible
  // (though unlikely) that either the browser or session has been pulled
  // out from underneath us.
  Browser* const browser = chrome::FindBrowserWithID(session_id);
  if (!browser) {
    return;
  }

  // We want to focus the active web contents, which again, might not be the
  // original web contents (though it should be the vast majority of the time).
  content::WebContents* const active_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  if (active_contents) {
    active_contents->Focus();
  }
}

bool CanOpenFile(Browser* browser) {
  if (browser->is_type_devtools() || browser->is_type_app() ||
      browser->is_type_app_popup()) {
    return false;
  }

  PrefService* local_state = g_browser_process->local_state();
  // May be null in unit tests.
  if (local_state) {
    return local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
  }

  return true;
}

void InvokeAction(actions::ActionId id, actions::ActionItem* scope) {
  actions::ActionManager::Get().FindAction(id, scope)->InvokeAction();
}

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// BrowserCommandController, public:

// TODO(crbug.com/434734349): Implement dependency injection for this class to
// allow removing the Browser dependency.
BrowserCommandController::BrowserCommandController(BrowserWindowInterface* bwi)
    : browser_(bwi->GetBrowserForMigrationOnly()) {
  browser_->tab_strip_model()->AddObserver(this);
  PrefService* local_state = g_browser_process->local_state();
  if (local_state) {
    local_pref_registrar_.Init(local_state);
    local_pref_registrar_.Add(
        prefs::kAllowFileSelectionDialogs,
        base::BindRepeating(
            &BrowserCommandController::UpdateCommandsForFileSelectionDialogs,
            base::Unretained(this)));
  }

  profile_pref_registrar_.Init(profile()->GetPrefs());
  profile_pref_registrar_.Add(
      prefs::kDevToolsAvailability,
      base::BindRepeating(&BrowserCommandController::UpdateCommandsForDevTools,
                          base::Unretained(this)));
  profile_pref_registrar_.Add(
      bookmarks::prefs::kEditBookmarksEnabled,
      base::BindRepeating(
          &BrowserCommandController::UpdateCommandsForBookmarkEditing,
          base::Unretained(this)));
  profile_pref_registrar_.Add(
      bookmarks::prefs::kShowBookmarkBar,
      base::BindRepeating(
          &BrowserCommandController::UpdateCommandsForBookmarkBar,
          base::Unretained(this)));
  profile_pref_registrar_.Add(
      policy::policy_prefs::kIncognitoModeAvailability,
      base::BindRepeating(
          &BrowserCommandController::UpdateCommandsForIncognitoAvailability,
          base::Unretained(this)));
#if BUILDFLAG(ENABLE_PRINTING)
  profile_pref_registrar_.Add(
      prefs::kPrintingEnabled,
      base::BindRepeating(&BrowserCommandController::UpdatePrintingState,
                          base::Unretained(this)));
#endif  // BUILDFLAG(ENABLE_PRINTING)
  profile_pref_registrar_.Add(
      policy::policy_prefs::kDownloadRestrictions,
      base::BindRepeating(&BrowserCommandController::UpdateSaveAsState,
                          base::Unretained(this)));
#if !BUILDFLAG(IS_MAC)
  profile_pref_registrar_.Add(
      prefs::kFullscreenAllowed,
      base::BindRepeating(
          &BrowserCommandController::UpdateCommandsForFullscreenMode,
          base::Unretained(this)));
#endif  //! BUILDFLAG(IS_MAC)

#if BUILDFLAG(ENABLE_GLIC)
  if (glic::GlicEnabling::IsEnabledByFlags()) {
    auto* glic_service =
        glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile());
    if (glic_service) {
      glic_enabling_subscription_ = std::make_unique<
          base::CallbackListSubscription>(

          glic_service->enabling().RegisterAllowedChanged(base::BindRepeating(
              &BrowserCommandController::UpdateCommandsForEnableGlicChanged,
              base::Unretained(this))));
    }
  }
#endif  // BUILDFLAG(ENABLE_GLIC)

#if BUILDFLAG(ENABLE_GLIC)
  if (glic::GlicEnabling::IsEnabledByFlags()) {
    auto* service =
        glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile());
    if (service) {
      glic_window_activation_subscription_ =
          service->window_controller().AddWindowActivationChangedCallback(
              base::BindRepeating(
                  &BrowserCommandController::GlicWindowActivationChanged,
                  base::Unretained(this)));
      glic_fre_state_change_subscription_ =
          service->fre_controller().AddWebUiStateChangedCallback(
              base::BindRepeating(
                  &BrowserCommandController::GlicFreStateChanged,
                  base::Unretained(this)));
    }
  }
#endif

  InitCommandState();

  sessions::TabRestoreService* tab_restore_service =
      TabRestoreServiceFactory::GetForProfile(profile());
  if (tab_restore_service) {
    tab_restore_service->AddObserver(this);
    if (!tab_restore_service->IsLoaded()) {
      tab_restore_service->LoadTabsFromLastSession();
    }
  }
}

BrowserCommandController::~BrowserCommandController() {
  // TabRestoreService may have been shutdown by the time we get here. Don't
  // trigger creating it.
  sessions::TabRestoreService* tab_restore_service =
      TabRestoreServiceFactory::GetForProfileIfExisting(profile());
  if (tab_restore_service) {
    tab_restore_service->RemoveObserver(this);
  }
  profile_pref_registrar_.RemoveAll();
  local_pref_registrar_.RemoveAll();
  glic_enabling_subscription_.reset();
}

bool BrowserCommandController::IsReservedCommandOrKey(
    int command_id,
    const input::NativeWebKeyboardEvent& event) {
  // In Apps mode, no keys are reserved.
  if (browser_->is_type_app() || browser_->is_type_app_popup()) {
    return false;
  }

#if BUILDFLAG(IS_CHROMEOS)
  // On Chrome OS, the top row of keys are mapped to browser actions like
  // back/forward or refresh. We don't want web pages to be able to change the
  // behavior of these keys.  Ash handles F4 and up; this leaves us needing to
  // reserve browser back/forward and refresh here.
  ui::KeyboardCode key_code =
      static_cast<ui::KeyboardCode>(event.windows_key_code);
  if ((key_code == ui::VKEY_BROWSER_BACK && command_id == IDC_BACK) ||
      (key_code == ui::VKEY_BROWSER_FORWARD && command_id == IDC_FORWARD) ||
      (key_code == ui::VKEY_BROWSER_REFRESH && command_id == IDC_RELOAD)) {
    return true;
  }
#endif

  if (window()->IsFullscreen()) {
    // In fullscreen, all commands except for IDC_FULLSCREEN and IDC_EXIT should
    // be delivered to the web page. The intent to implement and ship can be
    // found in http://crbug.com/680809.
    const bool is_exit_fullscreen =
        (command_id == IDC_EXIT || command_id == IDC_FULLSCREEN);
#if BUILDFLAG(IS_MAC)
    // This behavior is different on Mac OS, which has a unique user-initiated
    // full-screen mode. According to the discussion in http://crbug.com/702251,
    // the commands should be reserved for browser-side handling if the browser
    // window's toolbar is visible.
    if (window()->IsToolbarShowing()) {
      if (command_id == IDC_FULLSCREEN) {
        return true;
      }
    } else {
      return is_exit_fullscreen;
    }
#else
    return is_exit_fullscreen;
#endif
  }

#if BUILDFLAG(IS_LINUX)
  // If this key was registered by the user as a content editing hotkey, then
  // it is not reserved.
  auto* linux_ui = ui::LinuxUi::instance();
  if (linux_ui && event.os_event &&
      linux_ui->GetTextEditCommandForEvent(*event.os_event,
                                           ui::TEXT_INPUT_FLAG_NONE) !=
          ui::TextEditCommand::INVALID_COMMAND) {
    return false;
  }
#endif

  return command_id == IDC_CLOSE_TAB || command_id == IDC_CLOSE_WINDOW ||
         command_id == IDC_NEW_INCOGNITO_WINDOW || command_id == IDC_NEW_TAB ||
         command_id == IDC_NEW_WINDOW || command_id == IDC_RESTORE_TAB ||
         command_id == IDC_SELECT_NEXT_TAB ||
         command_id == IDC_SELECT_PREVIOUS_TAB || command_id == IDC_EXIT;
}

void BrowserCommandController::TabStateChanged() {
  UpdateCommandsForTabState();
  UpdateCommandsForWebContentsFocus();
}

void BrowserCommandController::ZoomStateChanged() {
  UpdateCommandsForZoomState();
}

void BrowserCommandController::ContentRestrictionsChanged() {
  UpdateCommandsForContentRestrictionState();
}

void BrowserCommandController::FullscreenStateChanged() {
  UpdateCommandsForFullscreenMode();
}

#if BUILDFLAG(IS_CHROMEOS)
void BrowserCommandController::LockedFullscreenStateChanged() {
  UpdateCommandsForLockedFullscreenMode();
}
#endif

void BrowserCommandController::PrintingStateChanged() {
  UpdatePrintingState();
}

void BrowserCommandController::LoadingStateChanged(bool is_loading,
                                                   bool force) {
  UpdateReloadStopState(is_loading, force);
}

#if BUILDFLAG(ENABLE_GLIC)
void BrowserCommandController::GlicWindowActivationChanged(bool active) {
  UpdateGlicState();
}

void BrowserCommandController::GlicFreStateChanged(
    glic::mojom::FreWebUiState new_state) {
  UpdateGlicState();
}
#endif

void BrowserCommandController::FindBarVisibilityChanged() {
  // Block find command updates in locked fullscreen mode unless the instance is
  // locked for OnTask (only relevant for non-web browser scenarios).
  // TODO(crbug.com/365146870): Remove once we consolidate locked fullscreen
  // with OnTask.
  bool should_block_command_update = is_locked_fullscreen_;
#if BUILDFLAG(IS_CHROMEOS)
  if (browser_->IsLockedForOnTask()) {
    should_block_command_update = false;
  }
#endif
  if (should_block_command_update) {
    return;
  }
  UpdateCloseFindOrStop();
}

void BrowserCommandController::ExtensionStateChanged() {
  // Extensions may disable the bookmark editing commands.
  UpdateCommandsForBookmarkEditing();
}

void BrowserCommandController::TabKeyboardFocusChangedTo(
    std::optional<int> index) {
  UpdateCommandsForTabKeyboardFocus(index);
}

void BrowserCommandController::WebContentsFocusChanged() {
  UpdateCommandsForWebContentsFocus();
}

void BrowserCommandController::ShowCustomizeChromeSidePanel(
    SidePanelOpenTrigger trigger,
    std::optional<CustomizeChromeSection> section) {
  tabs::TabInterface* tab = browser_->tab_strip_model()->GetActiveTab();
  if (!tab || !tab->GetTabFeatures() ||
      !tab->GetTabFeatures()->customize_chrome_side_panel_controller()) {
    return;
  }

  customize_chrome::SidePanelController* side_panel_controller =
      tab->GetTabFeatures()->customize_chrome_side_panel_controller();

  if (!side_panel_controller ||
      !side_panel_controller->IsCustomizeChromeEntryAvailable()) {
    return;
  }

  side_panel_controller->OpenSidePanel(trigger, section);
}

////////////////////////////////////////////////////////////////////////////////
// BrowserCommandController, CommandUpdater implementation:

bool BrowserCommandController::SupportsCommand(int id) const {
  return command_updater_.SupportsCommand(id);
}

bool BrowserCommandController::IsCommandEnabled(int id) const {
  return command_updater_.IsCommandEnabled(id);
}

bool BrowserCommandController::ExecuteCommand(int id,
                                              base::TimeTicks time_stamp) {
  return ExecuteCommandWithDisposition(id, WindowOpenDisposition::CURRENT_TAB,
                                       time_stamp);
}

bool BrowserCommandController::ExecuteCommandWithDisposition(
    int id,
    WindowOpenDisposition disposition,
    base::TimeTicks time_stamp) {
  // Doesn't go through the command_updater_ to avoid dealing with having a
  // naming collision for ExecuteCommandWithDisposition (both
  // CommandUpdaterDelegate and CommandUpdater declare this function so we
  // choose to not implement CommandUpdaterDelegate inside this class and
  // therefore command_updater_ doesn't have the delegate set).
  if (!SupportsCommand(id) || !IsCommandEnabled(id)) {
    return false;
  }

  // No commands are enabled if there is not yet any selected tab.
  // TODO(pkasting): It seems like we should not need this, because either
  // most/all commands should not have been enabled yet anyway or the ones that
  // are enabled should be global, or safe themselves against having no selected
  // tab.  However, Ben says he tried removing this before and got lots of
  // crashes, e.g. from Windows sending WM_COMMANDs at random times during
  // window construction.  This probably could use closer examination someday.
  if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab) {
    return true;
  }

  DCHECK(command_updater_.IsCommandEnabled(id))
      << "Invalid/disabled command " << id;

  // The order of commands in this switch statement must match the function
  // declaration order in browser.h!
  switch (id) {
    // Navigation commands
    case IDC_BACK:
      GoBack(browser_, disposition);
      break;
    case IDC_FORWARD:
      GoForward(browser_, disposition);
      break;
    case IDC_RELOAD:
      Reload(browser_, disposition);
      break;
    case IDC_RELOAD_CLEARING_CACHE:
      ClearCache(browser_);
      [[fallthrough]];
    case IDC_RELOAD_BYPASSING_CACHE:
      ReloadBypassingCache(browser_, disposition);
      break;
    case IDC_HOME:
      Home(browser_, disposition);
      break;
    case IDC_OPEN_CURRENT_URL:
      OpenCurrentURL(browser_);
      break;
    case IDC_STOP:
      Stop(browser_);
      break;
    case IDC_TAB_SEARCH:
      ShowTabSearch(browser_);
      break;
    case IDC_TAB_SEARCH_CLOSE:
      CloseTabSearch(browser_);
      break;
    case IDC_TOGGLE_VERTICAL_TABS:
      ToggleVerticalTabs(browser_);
      break;

    // Window management commands
    case IDC_NEW_WINDOW:
      NewWindow(browser_);
      break;
    case IDC_NEW_INCOGNITO_WINDOW:
      NewIncognitoWindow(profile());
      break;
    case IDC_CLOSE_WINDOW:
      base::RecordAction(base::UserMetricsAction("CloseWindowByKey"));
      CloseWindow(browser_);
      break;
    case IDC_NEW_TAB: {
      NewTab(browser_);
      break;
    }
    case IDC_NEW_TAB_TO_RIGHT: {
      NewTabToRight(browser_);
      break;
    }
    case IDC_CLOSE_TAB:
      base::RecordAction(base::UserMetricsAction("CloseTabByKey"));
      CloseTab(browser_);
      break;
    case IDC_SELECT_NEXT_TAB:
      base::RecordAction(base::UserMetricsAction("Accel_SelectNextTab"));
      SelectNextTab(
          browser_,
          TabStripUserGestureDetails(
              TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp));
      break;
    case IDC_SELECT_PREVIOUS_TAB:
      base::RecordAction(base::UserMetricsAction("Accel_SelectPreviousTab"));
      SelectPreviousTab(
          browser_,
          TabStripUserGestureDetails(
              TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp));
      break;
    case IDC_MOVE_TAB_NEXT:
      MoveTabNext(browser_);
      break;
    case IDC_MOVE_TAB_PREVIOUS:
      MoveTabPrevious(browser_);
      break;
    case IDC_SELECT_TAB_0:
    case IDC_SELECT_TAB_1:
    case IDC_SELECT_TAB_2:
    case IDC_SELECT_TAB_3:
    case IDC_SELECT_TAB_4:
    case IDC_SELECT_TAB_5:
    case IDC_SELECT_TAB_6:
    case IDC_SELECT_TAB_7:
      base::RecordAction(base::UserMetricsAction("Accel_SelectNumberedTab"));
      SelectNumberedTab(
          browser_, id - IDC_SELECT_TAB_0,
          TabStripUserGestureDetails(
              TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp));
      break;
    case IDC_SELECT_LAST_TAB:
      base::RecordAction(base::UserMetricsAction("Accel_SelectNumberedTab"));
      SelectLastTab(
          browser_,
          TabStripUserGestureDetails(
              TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp));
      break;
    case IDC_DUPLICATE_TAB:
      DuplicateTab(browser_);
      break;
    case IDC_RESTORE_TAB:
      RestoreTab(browser_);
      break;
    case IDC_SHOW_AS_TAB:
      ConvertPopupToTabbedBrowser(browser_);
      break;
    case IDC_FULLSCREEN:
      chrome::ToggleFullscreenMode(browser_, /*user_initiated=*/true);
      break;
    case IDC_OPEN_IN_PWA_WINDOW:
      base::RecordAction(base::UserMetricsAction("OpenActiveTabInPwaWindow"));
      web_app::ReparentWebAppForActiveTab(browser_);
      break;
    case IDC_MOVE_TAB_TO_NEW_WINDOW:
      MoveActiveTabToNewWindow(browser_);
      break;
    case IDC_NEW_SPLIT_TAB:
      if (!browser_->tab_strip_model()->GetActiveTab()->IsSplit()) {
        NewSplitTab(browser_,
                    split_tabs::SplitTabCreatedSource::kKeyboardShortcut);
      }
      break;
    case IDC_NAME_WINDOW:
      PromptToNameWindow(browser_);
      break;

#if BUILDFLAG(IS_CHROMEOS)
    case IDC_TAKE_SCREENSHOT:
      TakeScreenshot();
      break;
    case IDC_TOGGLE_MULTITASK_MENU:
      ToggleMultitaskMenu(browser_);
      break;
    case IDC_VISIT_DESKTOP_OF_LRU_USER_2:
    case IDC_VISIT_DESKTOP_OF_LRU_USER_3:
    case IDC_VISIT_DESKTOP_OF_LRU_USER_4:
    case IDC_VISIT_DESKTOP_OF_LRU_USER_5:
      ExecuteVisitDesktopCommand(id, window()->GetNativeWindow());
      break;
#endif

#if BUILDFLAG(IS_LINUX)
    case IDC_MINIMIZE_WINDOW:
      browser_->window()->Minimize();
      break;
    case IDC_MAXIMIZE_WINDOW:
      browser_->window()->Maximize();
      break;
    case IDC_RESTORE_WINDOW:
      browser_->window()->Restore();
      break;
    case IDC_USE_SYSTEM_TITLE_BAR: {
      PrefService* prefs = profile()->GetPrefs();
      prefs->SetBoolean(prefs::kUseCustomChromeFrame,
                        !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
      break;
    }
#endif

#if BUILDFLAG(IS_MAC)
    case IDC_TOGGLE_FULLSCREEN_TOOLBAR:
      chrome::ToggleAlwaysShowToolbarInFullscreen(browser_);
      break;
    case IDC_TOGGLE_JAVASCRIPT_APPLE_EVENTS: {
      chrome::ToggleJavaScriptFromAppleEventsAllowed(browser_);
      break;
    }
#endif
    case IDC_EXIT:
      Exit();
      break;

    // Page-related commands
    case IDC_SAVE_PAGE:
      SavePage(browser_);
      break;
    case IDC_BOOKMARK_THIS_TAB:
      BookmarkCurrentTab(browser_);
      break;
    case IDC_BOOKMARK_ALL_TABS:
      BookmarkAllTabs(browser_);
      break;
    case IDC_VIEW_SOURCE:
      browser_->tab_strip_model()
          ->GetActiveWebContents()
          ->GetPrimaryMainFrame()
          ->ViewSource();
      break;
    case IDC_PRINT:
      Print(browser_);
      break;

#if BUILDFLAG(ENABLE_PRINTING)
    case IDC_BASIC_PRINT:
      base::RecordAction(base::UserMetricsAction("Accel_Advanced_Print"));
      BasicPrint(browser_);
      break;
#endif  // ENABLE_PRINTING
    case IDC_OFFERS_AND_REWARDS_FOR_PAGE:
      ShowOffersAndRewardsForPage(browser_);
      break;
    case IDC_SAVE_CREDIT_CARD_FOR_PAGE:
      SaveCreditCard(browser_);
      break;
    case IDC_SAVE_IBAN_FOR_PAGE:
      SaveIban(browser_);
      break;
    case IDC_AUTOFILL_MANDATORY_REAUTH:
      ShowMandatoryReauthOptInPrompt(browser_);
      break;
    case IDC_SAVE_AUTOFILL_ADDRESS:
      SaveAutofillAddress(browser_);
      break;
    case IDC_SHOW_SYNC_SETTINGS:
      chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage);
      break;
    case IDC_SHOW_CONTEXTUAL_TASKS_SIDE_PANEL:
      ShowContextualTasksSidePanel(browser_);
      break;
    case IDC_TURN_ON_SYNC:
      signin_ui_util::EnableSyncFromSingleAccountPromo(
          browser_->profile(), GetAccountInfoFromProfile(browser_->profile()),
          signin_metrics::AccessPoint::kMenu);
      break;
    case IDC_SHOW_SIGNIN:
      signin_ui_util::SignInFromSingleAccountPromo(
          browser_->profile(), GetAccountInfoFromProfile(browser_->profile()),
          signin_metrics::AccessPoint::kMenu);
      break;
    case IDC_SHOW_SIGNIN_WHEN_PAUSED:
      signin_ui_util::ShowReauthForPrimaryAccountWithAuthError(
          browser_->profile(), signin_metrics::AccessPoint::kMenu);
      break;
    case IDC_SHOW_PASSWORD_MANAGER:
      ShowPasswordManager(browser_);
      break;
    case IDC_SAFETY_HUB_SHOW_PASSWORD_CHECKUP:
      ShowPasswordCheck(browser_);
      break;
    case IDC_SHOW_PAYMENT_METHODS:
      ShowPaymentMethods(browser_);
      break;
    case IDC_SHOW_ADDRESSES:
      ShowAddresses(browser_);
      break;
    case IDC_FILLED_CARD_INFORMATION:
      ShowFilledCardInformationBubble(browser_);
      break;
    case IDC_VIRTUAL_CARD_ENROLL:
      ShowVirtualCardEnrollBubble(browser_);
      break;
    case IDC_ORGANIZE_TABS:
      StartTabOrganizationRequest(browser_);
      break;
    case IDC_DECLUTTER_TABS:
      ShowTabDeclutter(browser_);
      break;
    case IDC_SEND_SHARED_TAB_GROUP_FEEDBACK:
      OpenFeedbackDialog(browser_, feedback::kFeedbackSourceDesktopTabGroups,
                         /*description_template=*/std::string(),
                         /*category_tag=*/"tab_group_share");
      break;
    case IDC_SHOW_TRANSLATE:
      ShowTranslateBubble(browser_);
      break;
    case IDC_MANAGE_PASSWORDS_FOR_PAGE:
      ManagePasswordsForPage(browser_);
      break;
    case IDC_SEND_TAB_TO_SELF:
      SendTabToSelf(browser_);
      break;
    case IDC_QRCODE_GENERATOR:
      GenerateQRCode(browser_);
      break;
    case IDC_SHARING_HUB:
      SharingHub(browser_);
      break;
    case IDC_SHARING_HUB_SCREENSHOT:
      ScreenshotCapture(browser_);
      break;

    // Clipboard commands
    case IDC_CUT:
      InvokeAction(actions::kActionCut,
                   browser_->GetActions()->root_action_item());
      break;
    case IDC_COPY:
      InvokeAction(actions::kActionCopy,
                   browser_->GetActions()->root_action_item());
      break;
    case IDC_PASTE:
      InvokeAction(actions::kActionPaste,
                   browser_->GetActions()->root_action_item());
      break;

    // Find-in-page
    case IDC_FIND:
      Find(browser_);
      break;
    case IDC_FIND_NEXT:
      FindNext(browser_);
      break;
    case IDC_FIND_PREVIOUS:
      FindPrevious(browser_);
      break;
    case IDC_CLOSE_FIND_OR_STOP:
      if (CanCloseFind(browser_)) {
        CloseFind(browser_);
      } else if (IsCommandEnabled(IDC_STOP)) {
        ExecuteCommand(IDC_STOP);
      }
      break;

    // Zoom
    case IDC_ZOOM_PLUS:
      Zoom(browser_, content::PAGE_ZOOM_IN);
      break;
    case IDC_ZOOM_NORMAL:
      Zoom(browser_, content::PAGE_ZOOM_RESET);
      break;
    case IDC_ZOOM_MINUS:
      Zoom(browser_, content::PAGE_ZOOM_OUT);
      break;

    // Focus various bits of UI
    case IDC_FOCUS_TOOLBAR:
      base::RecordAction(base::UserMetricsAction("Accel_Focus_Toolbar"));
      FocusToolbar(browser_);
      break;
    case IDC_FOCUS_LOCATION:
      if (!window()->IsLocationBarVisible()) {
        break;
      }
      base::RecordAction(base::UserMetricsAction("Accel_Focus_Location"));
      FocusLocationBar(browser_);
      break;
    case IDC_FOCUS_SEARCH:
      base::RecordAction(base::UserMetricsAction("Accel_Focus_Search"));
      FocusSearch(browser_);
      break;
    case IDC_FOCUS_MENU_BAR:
      FocusAppMenu(browser_);
      break;
    case IDC_FOCUS_BOOKMARKS:
      base::RecordAction(base::UserMetricsAction("Accel_Focus_Bookmarks"));
      FocusBookmarksToolbar(browser_);
      break;
    case IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY:
      FocusInactivePopupForAccessibility(browser_);
      break;
    case IDC_FOCUS_NEXT_PANE:
      FocusNextPane(browser_);
      break;
    case IDC_FOCUS_PREVIOUS_PANE:
      FocusPreviousPane(browser_);
      break;
    case IDC_FOCUS_WEB_CONTENTS_PANE:
      FocusWebContentsPane(browser_);
      break;

    // Show various bits of UI
    case IDC_OPEN_FILE:
      browser_->OpenFile();
      break;
    case IDC_CREATE_SHORTCUT:
      base::RecordAction(base::UserMetricsAction("CreateShortcut"));
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
      chrome::CreateDesktopShortcutForActiveWebContents(browser_);
#else
      web_app::CreateWebAppFromCurrentWebContents(
          browser_, web_app::WebAppInstallFlow::kCreateShortcut);
#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
      break;
    case IDC_INSTALL_PWA:
      base::RecordAction(base::UserMetricsAction("InstallWebAppFromMenu"));
      web_app::CreateWebAppFromCurrentWebContents(
          browser_, web_app::WebAppInstallFlow::kInstallSite);
      break;
    case IDC_DEV_TOOLS:
      ToggleDevToolsWindow(browser_, DevToolsToggleAction::Show(),
                           DevToolsOpenedByAction::kMainMenuOrMainShortcut);
      break;
    case IDC_DEV_TOOLS_CONSOLE:
      ToggleDevToolsWindow(browser_, DevToolsToggleAction::ShowConsolePanel(),
                           DevToolsOpenedByAction::kConsoleShortcut);
      break;
    case IDC_DEV_TOOLS_DEVICES:
      InspectUI::InspectDevices(browser_);
      break;
    case IDC_DEV_TOOLS_INSPECT:
      ToggleDevToolsWindow(browser_, DevToolsToggleAction::Inspect(),
                           DevToolsOpenedByAction::kInspectorModeShortcut);
      break;
    case IDC_DEV_TOOLS_TOGGLE:
      ToggleDevToolsWindow(browser_, DevToolsToggleAction::Toggle(),
                           DevToolsOpenedByAction::kToggleShortcut);
      break;
    case IDC_TASK_MANAGER:
      OpenTaskManager(browser_);
      break;
    case IDC_TASK_MANAGER_APP_MENU:
      OpenTaskManager(browser_, task_manager::StartAction::kMoreTools);
      break;
    case IDC_TASK_MANAGER_SHORTCUT:
      OpenTaskManager(browser_, task_manager::StartAction::kShortcut);
      break;
    case IDC_TASK_MANAGER_CONTEXT_MENU:
      OpenTaskManager(browser_, task_manager::StartAction::kContextMenu);
      break;
    case IDC_TASK_MANAGER_MAIN_MENU:
      OpenTaskManager(browser_, task_manager::StartAction::kMainMenu);
      break;
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
    case IDC_FEEDBACK:
      OpenFeedbackDialog(browser_, feedback::kFeedbackSourceBrowserCommand);
      break;
#endif
    case IDC_SHOW_CHROME_LABS:
      window()->ShowChromeLabs();
      break;
    case IDC_SHOW_BOOKMARK_BAR:
      ToggleBookmarkBar(browser_);
      break;
    case IDC_SHOW_ALL_COMPARISON_TABLES:
      ShowAllComparisonTables(browser_);
      break;
    case IDC_SHOW_FULL_URLS:
      ToggleShowFullURLs(browser_);
      break;
    case IDC_SHOW_GOOGLE_LENS_SHORTCUT:
      ToggleShowGoogleLensShortcut(browser_);
      break;
    case IDC_SHOW_AI_MODE_OMNIBOX_BUTTON:
      ToggleShowAiModeOmniboxButton(browser_);
      break;
    case IDC_SHOW_SEARCH_TOOLS:
      ToggleShowSearchTools(browser_);
      break;
    case IDC_PROFILING_ENABLED:
      content::Profiling::Toggle();
      break;
    case IDC_CARET_BROWSING_TOGGLE:
      ToggleCaretBrowsing(browser_);
      break;
    case IDC_RECENT_TABS_LOGIN_FOR_DEVICE_TABS:
      ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(),
                          chrome::kPeopleSubPage);
      break;
    case IDC_RECENT_TABS_SEE_DEVICE_TABS:
      ShowHistorySubPage(browser_->GetBrowserForOpeningWebUi(),
                         kChromeUIHistorySyncedTabs);
      break;
    case IDC_SHOW_BOOKMARK_MANAGER:
      ShowBookmarkManager(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_SHOW_BOOKMARK_SIDE_PANEL:
      browser_->GetFeatures().side_panel_ui()->Show(
          SidePanelEntryId::kBookmarks, SidePanelOpenTrigger::kAppMenu);
      break;
    case IDC_SHOW_APP_MENU:
      base::RecordAction(base::UserMetricsAction("Accel_Show_App_Menu"));
      ShowAppMenu(browser_);
      break;
    case IDC_SHOW_AVATAR_MENU:
      ShowAvatarMenu(browser_);
      break;
    case IDC_SHOW_HISTORY:
      ShowHistory(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_SHOW_HISTORY_CLUSTERS_SIDE_PANEL:
      browser_->GetFeatures().side_panel_ui()->Show(
          SidePanelEntryId::kHistoryClusters, SidePanelOpenTrigger::kAppMenu);
      break;
    case IDC_SHOW_DOWNLOADS:
      ShowDownloads(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_SHOW_COMMENTS_SIDE_PANEL:
      browser_->GetFeatures().side_panel_ui()->Show(
          SidePanelEntryId::kComments, SidePanelOpenTrigger::kAppMenu);
      break;
    case IDC_MANAGE_EXTENSIONS:
    case IDC_SAFETY_HUB_MANAGE_EXTENSIONS:
      ShowExtensions(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_EXTENSIONS_SUBMENU_MANAGE_EXTENSIONS:
      ShowExtensions(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_EXTENSIONS_SUBMENU_VISIT_CHROME_WEB_STORE:
    case IDC_FIND_EXTENSIONS:
      ShowWebStore(browser_, extension_urls::kAppMenuUtmSource);
      break;
    case IDC_PERFORMANCE:
      ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(),
                          chrome::kPerformanceSubPage);
      break;
    case IDC_OPTIONS:
      ShowSettings(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_EDIT_SEARCH_ENGINES:
      ShowSearchEngineSettings(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_VIEW_PASSWORDS:
      NavigateToManagePasswordsPage(
          browser_->GetBrowserForOpeningWebUi(),
          password_manager::ManagePasswordsReferrer::kChromeMenuItem);
      break;
    case IDC_CLEAR_BROWSING_DATA: {
      if (profile()->IsIncognitoProfile()) {
        ShowIncognitoClearBrowsingDataDialog(
            browser_->GetBrowserForOpeningWebUi());
      } else {
        ShowClearBrowsingDataDialog(browser_->GetBrowserForOpeningWebUi());
      }
      break;
    }
    case IDC_IMPORT_SETTINGS:
      ShowImportDialog(browser_);
      break;
    case IDC_TOGGLE_REQUEST_TABLET_SITE:
      ToggleRequestTabletSite(browser_);
      break;
    case IDC_ABOUT:
      ShowAboutChrome(browser_->GetBrowserForOpeningWebUi());
      break;
    case IDC_UPGRADE_DIALOG:
      OpenUpdateChromeDialog(browser_);
      break;
    case IDC_OPEN_SAFETY_HUB:
      ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(),
                          chrome::kSafetyHubSubPage);
      break;
    case IDC_HELP_PAGE_VIA_KEYBOARD:
      ShowHelp(browser_, chrome::HelpSource::kKeyboard);
      break;
    case IDC_HELP_PAGE_VIA_MENU:
      ShowHelp(browser_, chrome::HelpSource::kMenu);
      break;
    case IDC_CHROME_TIPS:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
      ShowChromeTips(browser_);
      break;
#else
      NOTREACHED();
#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
    case IDC_CHROME_WHATS_NEW:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
    (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX))
      ShowChromeWhatsNew(browser_);
      break;
#else
      NOTREACHED();
#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
        // (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX))
    case IDC_SHOW_BETA_FORUM:
      ShowBetaForum(browser_);
      break;
    case IDC_ROUTE_MEDIA:
      RouteMediaInvokedFromAppMenu(browser_);
      break;
    case IDC_WINDOW_MUTE_SITE:
      MuteSite(browser_);
      break;
    case IDC_WINDOW_PIN_TAB:
      PinTab(browser_);
      break;
    case IDC_WINDOW_GROUP_TAB:
      GroupTab(browser_);
      break;

    // Tab group commands.
    case IDC_FOCUS_NEXT_TAB_GROUP:
      if (base::i18n::IsRTL()) {
        FocusPreviousTabGroup(browser_);
      } else {
        FocusNextTabGroup(browser_);
      }
      base::UmaHistogramEnumeration("TabGroups.Shortcuts",
                                    TabGroupShortcut::kFocusNextTabGroup);
      break;
    case IDC_FOCUS_PREV_TAB_GROUP:
      if (base::i18n::IsRTL()) {
        FocusNextTabGroup(browser_);
      } else {
        FocusPreviousTabGroup(browser_);
      }
      base::UmaHistogramEnumeration("TabGroups.Shortcuts",
                                    TabGroupShortcut::kFocusPrevTabGroup);
      break;
    case IDC_CLOSE_TAB_GROUP:
      CloseTabGroup(browser_);
      base::UmaHistogramEnumeration("TabGroups.Shortcuts",
                                    TabGroupShortcut::kCloseTabGroup);
      break;
    case IDC_CREATE_NEW_TAB_GROUP:
      CreateNewTabGroup(browser_);
      base::UmaHistogramEnumeration("TabGroups.Shortcuts",
                                    TabGroupShortcut::kCreateNewTabGroup);
      break;
    case IDC_CREATE_NEW_TAB_GROUP_TOP_LEVEL:
      CreateNewTabGroup(browser_);
      break;
    case IDC_ADD_NEW_TAB_TO_GROUP:
      AddNewTabToGroup(browser_);
      base::UmaHistogramEnumeration("TabGroups.Shortcuts",
                                    TabGroupShortcut::kAddNewTabToGroup);
      break;
    case IDC_GROUP_UNGROUPED_TABS:
      GroupAllUngroupedTabs(browser_);
      base::RecordAction(
          base::UserMetricsAction("TabGroups_GroupAllUngroupedTabs"));
      break;
    case IDC_ADD_NEW_TAB_RECENT_GROUP:
      AddNewTabToRecentGroup(browser_);
      break;
    case IDC_WINDOW_CLOSE_TABS_TO_RIGHT:
      CloseTabsToRight(browser_);
      break;
    case IDC_WINDOW_CLOSE_OTHER_TABS:
      CloseOtherTabs(browser_);
      break;
    case IDC_SHOW_MANAGEMENT_PAGE: {
      ShowSingletonTab(browser_, GetManagedUiUrl(profile()));
      break;
    }
    case IDC_MUTE_TARGET_SITE:
      MuteSiteForKeyboardFocusedTab(browser_);
      break;
    case IDC_PIN_TARGET_TAB:
      PinKeyboardFocusedTab(browser_);
      break;
    case IDC_GROUP_TARGET_TAB:
      GroupKeyboardFocusedTab(browser_);
      break;
    case IDC_DUPLICATE_TARGET_TAB:
      DuplicateKeyboardFocusedTab(browser_);
      break;
    // Hosted App commands
    case IDC_COPY_URL:
      CopyURL(browser_, browser_->tab_strip_model()->GetActiveWebContents());
      break;
    case IDC_OPEN_IN_CHROME:
      OpenInChrome(browser_);
      break;
    case IDC_WEB_APP_SETTINGS:
#if !BUILDFLAG(IS_CHROMEOS)
      CHECK(browser_->app_controller());
      ShowWebAppSettings(browser_, browser_->app_controller()->app_id(),
                         web_app::AppSettingsPageEntryPoint::kBrowserCommand);
#endif
      break;
    case IDC_WEB_APP_MENU_APP_INFO: {
      content::WebContents* const web_contents =
          browser_->tab_strip_model()->GetActiveWebContents();
      if (web_contents) {
        ShowPageInfoDialog(
            web_contents,
            base::BindOnce(&AppInfoDialogClosedCallback,
                           sessions::SessionTabHelper::IdForWindowContainingTab(
                               web_contents)),
            bubble_anchor_util::Anchor::kAppMenuButton);
      }
      break;
    }

    // UI debug commands
    case IDC_DEBUG_TOGGLE_TABLET_MODE:
    case IDC_DEBUG_PRINT_VIEW_TREE:
    case IDC_DEBUG_PRINT_VIEW_TREE_DETAILS:
      ExecuteUIDebugCommand(id, browser_);
      break;

    case IDC_CONTENT_CONTEXT_LENS_OVERLAY:
      ExecLensOverlay(browser_);
      break;

#if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
    case IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH:
      ExecLensRegionSearch(browser_);
      break;
#endif  // BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
    case IDC_READING_LIST_MENU_ADD_TAB:
      chrome::MoveCurrentTabToReadLater(browser_);
      break;

    case IDC_READING_LIST_MENU_SHOW_UI:
      browser_->GetFeatures().side_panel_ui()->Show(
          SidePanelEntryId::kReadingList, SidePanelOpenTrigger::kAppMenu);
      break;

    case IDC_SHOW_READING_MODE_SIDE_PANEL: {
      // Yes. This is a separate feature from the reading list.
      browser_->GetFeatures().side_panel_ui()->Show(
          SidePanelEntryId::kReadAnything, SidePanelOpenTrigger::kAppMenu);
      break;
    }

    case IDC_SHOW_CUSTOMIZE_CHROME_SIDE_PANEL: {
      ShowCustomizeChromeSidePanel(SidePanelOpenTrigger::kAppMenu,
                                   CustomizeChromeSection::kAppearance);
      break;
    }

    case IDC_SHOW_CUSTOMIZE_CHROME_TOOLBAR: {
      ShowCustomizeChromeSidePanel(SidePanelOpenTrigger::kAppMenu,
                                   CustomizeChromeSection::kToolbar);
      break;
    }

#if !BUILDFLAG(IS_CHROMEOS)
    // Profile submenu commands
    // This menu item is not enabled on ChromeOS and certain capabilities such
    // as the profile picker are not available.
    case IDC_CUSTOMIZE_CHROME:
      chrome::ShowSettingsSubPage(browser_, chrome::kManageProfileSubPage);
      break;
    case IDC_CLOSE_PROFILE: {
      if (browser_->profile()->IsIncognitoProfile()) {
        BrowserList::CloseAllBrowsersWithIncognitoProfile(
            browser_->profile(), base::DoNothing(), base::DoNothing(), true);
      } else {
        profiles::CloseProfileWindows(browser_->profile());
      }
      break;
    }
    case IDC_MANAGE_GOOGLE_ACCOUNT: {
      Profile* profile = browser_->profile();
      signin::IdentityManager* identity_manager =
          IdentityManagerFactory::GetForProfile(profile);
      DCHECK(
          identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin));
      NavigateToGoogleAccountPage(
          profile,
          identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
              .email);
      break;
    }
    case IDC_OPEN_GUEST_PROFILE:
      profiles::SwitchToGuestProfile();
      break;
    case IDC_ADD_NEW_PROFILE:
      ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint(
          ProfilePicker::EntryPoint::kAppMenuProfileSubMenuAddNewProfile));
      break;
    case IDC_MANAGE_CHROME_PROFILES:
      ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint(
          ProfilePicker::EntryPoint::kAppMenuProfileSubMenuManageProfiles));
      break;
#endif  // BUILDFLAG(IS_CHROMEOS)
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
    case IDC_SET_BROWSER_AS_DEFAULT:
      base::MakeRefCounted<shell_integration::DefaultBrowserWorker>()
          ->StartSetAsDefault(base::DoNothing());

      // Clear prefs and close prompts.
      chrome::startup::default_prompt::UpdatePrefsForDismissedPrompt(
          browser_->profile());
      DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts(
          DefaultBrowserPromptManager::CloseReason::kAccept);
      break;
#endif
#if BUILDFLAG(ENABLE_GLIC)
    case IDC_GLIC_TOGGLE_PIN: {
      PrefService* profile_prefs = profile()->GetPrefs();
      profile_prefs->SetBoolean(
          glic::prefs::kGlicPinnedToTabstrip,
          !profile_prefs->GetBoolean(glic::prefs::kGlicPinnedToTabstrip));
      break;
    }
    case IDC_OPEN_GLIC: {
      auto* service =
          glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile());
      if (service) {
        glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile())->ToggleUI(
            browser_,
            /*prevent_close=*/true,
            glic::mojom::InvocationSource::kThreeDotsMenu);
      }
      break;
    }
#endif
    default:
      LOG(WARNING) << "Received Unimplemented Command: " << id;
      break;
  }

  return true;
}

void BrowserCommandController::AddCommandObserver(int id,
                                                  CommandObserver* observer) {
  command_updater_.AddCommandObserver(id, observer);
}

void BrowserCommandController::RemoveCommandObserver(
    int id,
    CommandObserver* observer) {
  command_updater_.RemoveCommandObserver(id, observer);
}

void BrowserCommandController::RemoveCommandObserver(
    CommandObserver* observer) {
  command_updater_.RemoveCommandObserver(observer);
}

bool BrowserCommandController::UpdateCommandEnabled(int id, bool state) {
  // Block individual command updates in locked fullscreen mode unless the
  // instance is locked for OnTask (only relevant for non-web browser
  // scenarios).
  // TODO(crbug.com/365146870): Remove once we consolidate locked fullscreen
  // with OnTask.
  bool should_block_command_update = is_locked_fullscreen_;
#if BUILDFLAG(IS_CHROMEOS)
  if (browser_->IsLockedForOnTask()) {
    should_block_command_update = false;
  }
#endif
  if (should_block_command_update) {
    return false;
  }

  return command_updater_.UpdateCommandEnabled(id, state);
}

// BrowserCommandController, TabStripModelObserver implementation:

void BrowserCommandController::OnTabStripModelChanged(
    TabStripModel* tab_strip_model,
    const TabStripModelChange& change,
    const TabStripSelectionChange& selection) {
  UpdateCommandsForTabStripStateChanged();
}

void BrowserCommandController::TabBlockedStateChanged(
    content::WebContents* contents,
    int index) {
  PrintingStateChanged();
  FullscreenStateChanged();
  UpdateCommandsForFind();
  UpdateCommandsForMediaRouter();
}

////////////////////////////////////////////////////////////////////////////////
// BrowserCommandController, TabRestoreServiceObserver implementation:

void BrowserCommandController::TabRestoreServiceChanged(
    sessions::TabRestoreService* service) {
  UpdateTabRestoreCommandState();
}

void BrowserCommandController::TabRestoreServiceDestroyed(
    sessions::TabRestoreService* service) {
  service->RemoveObserver(this);
}

void BrowserCommandController::TabRestoreServiceLoaded(
    sessions::TabRestoreService* service) {
  UpdateTabRestoreCommandState();
}

////////////////////////////////////////////////////////////////////////////////
// BrowserCommandController, private:

bool BrowserCommandController::IsShowingMainUI() {
  return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
}

bool BrowserCommandController::IsShowingLocationBar() {
  return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
}

void BrowserCommandController::InitCommandState() {
  // All browser commands whose state isn't set automagically some other way
  // (like Back & Forward with initial page load) must have their state
  // initialized here, otherwise they will be forever disabled.

  if (is_locked_fullscreen_) {
    return;
  }

  // Navigation commands
  const bool can_reload = CanReload(browser_);
  command_updater_.UpdateCommandEnabled(IDC_RELOAD, can_reload);
  command_updater_.UpdateCommandEnabled(IDC_RELOAD_BYPASSING_CACHE, can_reload);
  command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, can_reload);

  // Tab group commands
  command_updater_.UpdateCommandEnabled(IDC_ADD_NEW_TAB_TO_GROUP, true);
  command_updater_.UpdateCommandEnabled(IDC_CREATE_NEW_TAB_GROUP, true);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_TAB_GROUP, true);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREV_TAB_GROUP, true);
  command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB_GROUP, true);
  command_updater_.UpdateCommandEnabled(IDC_GROUP_UNGROUPED_TABS, true);
  command_updater_.UpdateCommandEnabled(IDC_CREATE_NEW_TAB_GROUP_TOP_LEVEL,
                                        true);
  command_updater_.UpdateCommandEnabled(IDC_ADD_NEW_TAB_RECENT_GROUP, true);

  // Omnibox commands
  command_updater_.UpdateCommandEnabled(IDC_SHOW_FULL_URLS, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_GOOGLE_LENS_SHORTCUT, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_SEARCH_TOOLS, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_AI_MODE_OMNIBOX_BUTTON, true);

  // Window management commands
  command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
  command_updater_.UpdateCommandEnabled(
      IDC_NEW_TAB, !browser_->app_controller() ||
                       !browser_->app_controller()->ShouldHideNewTabButton());
  command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
  command_updater_.UpdateCommandEnabled(
      IDC_DUPLICATE_TAB, !browser_->is_type_picture_in_picture());
  UpdateTabRestoreCommandState();
  command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
  command_updater_.UpdateCommandEnabled(IDC_NAME_WINDOW, true);
  command_updater_.UpdateCommandEnabled(IDC_ORGANIZE_TABS, true);
  command_updater_.UpdateCommandEnabled(IDC_DECLUTTER_TABS, true);
  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
#if BUILDFLAG(IS_CHROMEOS)
  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_MULTITASK_MENU, true);
  command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true);
  // The VisitDesktop command is only supported for up to 5 logged in users
  // because that's the max number of user sessions. If that number is increased
  // the IDC_VISIT_DESKTOP_OF_LRU_USER_ command ids should be updated as well.
  // crbug.com/940461
  static_assert(
      session_manager::kMaximumNumberOfUserSessions <=
          IDC_VISIT_DESKTOP_OF_LRU_USER_LAST -
              IDC_VISIT_DESKTOP_OF_LRU_USER_NEXT + 2,
      "The max number of user sessions exceeds the number of users supported.");
  command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_2, true);
  command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_3, true);
  command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_4, true);
  command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_5, true);
#endif
#if BUILDFLAG(IS_LINUX)
  command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true);
  command_updater_.UpdateCommandEnabled(IDC_MAXIMIZE_WINDOW, true);
  command_updater_.UpdateCommandEnabled(IDC_RESTORE_WINDOW, true);

  bool use_system_title_bar = true;
#if BUILDFLAG(IS_OZONE)
  use_system_title_bar = ui::OzonePlatform::GetInstance()
                             ->GetPlatformRuntimeProperties()
                             .supports_server_side_window_decorations;
#endif
  command_updater_.UpdateCommandEnabled(IDC_USE_SYSTEM_TITLE_BAR,
                                        use_system_title_bar);
#endif  // BUILDFLAG(IS_LINUX)
  command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_PWA_WINDOW,
                                        web_app::CanPopOutWebApp(profile()));

  // Page-related commands
  command_updater_.UpdateCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE, true);

  // Zoom
  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, false);
  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);

  // Show various bits of UI
  DCHECK(!profile()->IsSystemProfile())
      << "Ought to never have browser for the system profile.";
  const bool normal_window = browser_->is_type_normal();
  const bool guest_session = profile()->IsGuestSession();
  command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, CanOpenFile(browser_));
  UpdateCommandsForDevTools();
  command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager());
  command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_APP_MENU,
                                        CanOpenTaskManager());
  command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_SHORTCUT,
                                        CanOpenTaskManager());
  command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_CONTEXT_MENU,
                                        CanOpenTaskManager());
  command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_MAIN_MENU,
                                        CanOpenTaskManager());
  command_updater_.UpdateCommandEnabled(IDC_PROFILE_MENU_IN_APP_MENU, true);
  command_updater_.UpdateCommandEnabled(
      IDC_SHOW_HISTORY, (!guest_session && !profile()->IsSystemProfile()));
  command_updater_.UpdateCommandEnabled(
      IDC_SHOW_HISTORY_CLUSTERS_SIDE_PANEL,
      (!guest_session && !profile()->IsSystemProfile()));
  command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_COMMENTS_SIDE_PANEL, true);
  command_updater_.UpdateCommandEnabled(IDC_FIND_AND_EDIT_MENU, true);
  command_updater_.UpdateCommandEnabled(IDC_SAVE_AND_SHARE_MENU, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_READING_MODE_SIDE_PANEL, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_CUSTOMIZE_CHROME_SIDE_PANEL,
                                        true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_CUSTOMIZE_CHROME_TOOLBAR,
                                        true);
  command_updater_.UpdateCommandEnabled(IDC_SEND_TAB_TO_SELF, false);
  command_updater_.UpdateCommandEnabled(IDC_QRCODE_GENERATOR, false);
  command_updater_.UpdateCommandEnabled(IDC_PASSWORDS_AND_AUTOFILL_MENU,
                                        !guest_session);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_PASSWORD_MANAGER,
                                        !guest_session);
  command_updater_.UpdateCommandEnabled(IDC_SAFETY_HUB_SHOW_PASSWORD_CHECKUP,
                                        !guest_session);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_PAYMENT_METHODS,
                                        !guest_session);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETTINGS, true);
  command_updater_.UpdateCommandEnabled(IDC_TURN_ON_SYNC, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_SIGNIN_WHEN_PAUSED, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_SIGNIN, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_ADDRESSES, !guest_session);
  command_updater_.UpdateCommandEnabled(IDC_HELP_MENU, true);
  command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true);
  command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_BETA_FORUM, true);
  command_updater_.UpdateCommandEnabled(
      IDC_BOOKMARKS_MENU, (!guest_session && !profile()->IsSystemProfile()));
  command_updater_.UpdateCommandEnabled(IDC_SAVED_TAB_GROUPS_MENU, true);
  command_updater_.UpdateCommandEnabled(
      IDC_RECENT_TABS_MENU, (!guest_session && !profile()->IsSystemProfile() &&
                             !profile()->IsIncognitoProfile()));
  command_updater_.UpdateCommandEnabled(
      IDC_RECENT_TABS_LOGIN_FOR_DEVICE_TABS,
      (!guest_session && !profile()->IsSystemProfile() &&
       !profile()->IsIncognitoProfile()));
  command_updater_.UpdateCommandEnabled(
      IDC_RECENT_TABS_SEE_DEVICE_TABS,
      (!guest_session && !profile()->IsSystemProfile() &&
       !profile()->IsIncognitoProfile()));
#if !BUILDFLAG(IS_CHROMEOS)
  command_updater_.UpdateCommandEnabled(IDC_CUSTOMIZE_CHROME, true);
  command_updater_.UpdateCommandEnabled(IDC_CLOSE_PROFILE, true);
  command_updater_.UpdateCommandEnabled(IDC_MANAGE_GOOGLE_ACCOUNT, true);
  command_updater_.UpdateCommandEnabled(IDC_OPEN_GUEST_PROFILE, true);
  command_updater_.UpdateCommandEnabled(IDC_ADD_NEW_PROFILE, true);
  command_updater_.UpdateCommandEnabled(IDC_MANAGE_CHROME_PROFILES, true);
#endif  // BUILDFLAG(IS_CHROMEOS)

  if (profile()->IsIncognitoProfile()) {
    command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, true);
  } else {
    command_updater_.UpdateCommandEnabled(
        IDC_CLEAR_BROWSING_DATA,
        (!guest_session && !profile()->IsSystemProfile()));
  }

#if BUILDFLAG(IS_CHROMEOS)
  command_updater_.UpdateCommandEnabled(IDC_TAKE_SCREENSHOT, true);
  // Chrome OS uses the system tray menu to handle multi-profiles. Avatar menu
  // is only required in incognito mode.
  command_updater_.UpdateCommandEnabled(
      IDC_SHOW_AVATAR_MENU, /*state=*/profile()->IsIncognitoProfile());
#else
  command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU,
                                        /*state=*/normal_window);
#endif
  command_updater_.UpdateCommandEnabled(
      IDC_SHOW_SAVE_LOCAL_CARD_SIGN_IN_PROMO_IF_APPLICABLE, true);
  command_updater_.UpdateCommandEnabled(IDC_CLOSE_SIGN_IN_PROMO, true);
  command_updater_.UpdateCommandEnabled(IDC_CARET_BROWSING_TOGGLE, true);
  // Navigation commands
  command_updater_.UpdateCommandEnabled(
      IDC_HOME, normal_window || browser_->is_type_app() ||
                    browser_->is_type_app_popup());

  // Hosted app browser commands.
  const bool is_web_app_or_custom_tab = IsWebAppOrCustomTab(browser_);
  const bool enable_copy_url =
      is_web_app_or_custom_tab ||
      !sharing_hub::SharingIsDisabledByPolicy(browser_->profile());
  command_updater_.UpdateCommandEnabled(IDC_COPY_URL, enable_copy_url);
  command_updater_.UpdateCommandEnabled(IDC_WEB_APP_SETTINGS,
                                        is_web_app_or_custom_tab);
  command_updater_.UpdateCommandEnabled(IDC_WEB_APP_MENU_APP_INFO,
                                        is_web_app_or_custom_tab);

  // Tab management commands
  const bool supports_tabs =
      browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, supports_tabs);
  command_updater_.UpdateCommandEnabled(IDC_NEW_TAB_TO_RIGHT, supports_tabs);

  // These are always enabled; the menu determines their menu item visibility.
  command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
  command_updater_.UpdateCommandEnabled(IDC_SET_BROWSER_AS_DEFAULT, true);

  // Safety Hub commands.
  command_updater_.UpdateCommandEnabled(IDC_OPEN_SAFETY_HUB, true);

  command_updater_.UpdateCommandEnabled(IDC_WINDOW_MUTE_SITE, normal_window);
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_PIN_TAB, normal_window);
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_GROUP_TAB, normal_window);
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_TABS_TO_RIGHT,
                                        normal_window);
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_OTHER_TABS,
                                        normal_window);

  const bool enable_tab_search_commands = browser_->is_type_normal();
  command_updater_.UpdateCommandEnabled(IDC_TAB_SEARCH,
                                        enable_tab_search_commands);
  command_updater_.UpdateCommandEnabled(IDC_TAB_SEARCH_CLOSE,
                                        enable_tab_search_commands);

  command_updater_.UpdateCommandEnabled(IDC_SHOW_CONTEXTUAL_TASKS_SIDE_PANEL,
                                        true);

  if (base::FeatureList::IsEnabled(features::kUIDebugTools)) {
    command_updater_.UpdateCommandEnabled(IDC_DEBUG_TOGGLE_TABLET_MODE, true);
    command_updater_.UpdateCommandEnabled(IDC_DEBUG_PRINT_VIEW_TREE, true);
    command_updater_.UpdateCommandEnabled(IDC_DEBUG_PRINT_VIEW_TREE_DETAILS,
                                          true);
  }

  command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_SIDE_PANEL, true);

  if (browser_->is_type_normal()) {
    // Reading list commands.
    command_updater_.UpdateCommandEnabled(IDC_READING_LIST_MENU, true);
    command_updater_.UpdateCommandEnabled(IDC_READING_LIST_MENU_ADD_TAB, true);
    command_updater_.UpdateCommandEnabled(IDC_READING_LIST_MENU_SHOW_UI, true);
  }
  if (IsChromeLabsEnabled()) {
    command_updater_.UpdateCommandEnabled(IDC_SHOW_CHROME_LABS, true);
  }

  // Compare commands.
  command_updater_.UpdateCommandEnabled(IDC_COMPARE_MENU, true);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_ALL_COMPARISON_TABLES, true);
  command_updater_.UpdateCommandEnabled(IDC_ADD_TO_COMPARISON_TABLE_MENU, true);
  command_updater_.UpdateCommandEnabled(
      IDC_CREATE_NEW_COMPARISON_TABLE_WITH_TAB, true);

#if BUILDFLAG(ENABLE_GLIC)
  // Glic commands.
  command_updater_.UpdateCommandEnabled(
      IDC_GLIC_TOGGLE_PIN, glic::GlicEnabling::IsProfileEligible(profile()));
  UpdateGlicState();
#endif

  // Initialize other commands whose state changes based on various conditions.
  UpdateCommandsForFullscreenMode();
  UpdateCommandsForContentRestrictionState();
  UpdateCommandsForBookmarkEditing();
  UpdateCommandsForIncognitoAvailability();
  UpdateCommandsForExtensionsMenu();
  UpdateCommandsForTabKeyboardFocus(GetKeyboardFocusedTabIndex(browser_));
  UpdateCommandsForWebContentsFocus();
}

// static
void BrowserCommandController::UpdateSharedCommandsForIncognitoAvailability(
    CommandUpdater* command_updater,
    Profile* profile) {
  policy::IncognitoModeAvailability incognito_availability =
      IncognitoModePrefs::GetAvailability(profile->GetPrefs());
  command_updater->UpdateCommandEnabled(
      IDC_NEW_WINDOW,
      incognito_availability != policy::IncognitoModeAvailability::kForced);
  command_updater->UpdateCommandEnabled(
      IDC_NEW_INCOGNITO_WINDOW,
      incognito_availability != policy::IncognitoModeAvailability::kDisabled &&
          !profile->IsGuestSession());

  const bool forced_incognito =
      incognito_availability == policy::IncognitoModeAvailability::kForced;
  const bool is_guest = profile->IsGuestSession();

  command_updater->UpdateCommandEnabled(
      IDC_SHOW_BOOKMARK_MANAGER,
      browser_defaults::bookmarks_enabled && !forced_incognito && !is_guest);
  extensions::ExtensionRegistrar* extension_registrar =
      extensions::ExtensionRegistrar::Get(profile);
  const bool enable_extensions =
      extension_registrar && extension_registrar->extensions_enabled();

  // Bookmark manager and settings page/subpages are forced to open in normal
  // mode. For this reason we disable these commands when incognito is forced.
  command_updater->UpdateCommandEnabled(
      IDC_MANAGE_EXTENSIONS,
      enable_extensions && !forced_incognito && !is_guest);
  command_updater->UpdateCommandEnabled(
      IDC_SAFETY_HUB_MANAGE_EXTENSIONS,
      enable_extensions && !forced_incognito && !is_guest);

  command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
                                        !forced_incognito && !is_guest);
  command_updater->UpdateCommandEnabled(IDC_OPTIONS,
                                        !forced_incognito || is_guest);
  command_updater->UpdateCommandEnabled(IDC_PERFORMANCE,
                                        !forced_incognito && !is_guest);
}

void BrowserCommandController::UpdateCommandsForIncognitoAvailability() {
  if (is_locked_fullscreen_) {
    return;
  }

  UpdateSharedCommandsForIncognitoAvailability(&command_updater_, profile());
  // Update the new incognito window ActionItem enabled state. Note, this cannot
  // be done in UpdateSharedCommandsForIncognitoAvailability as the method is
  // static to also handle states for NSApplication where no browser window are
  // open.
  if (auto* const incognito_action = FindAction(kActionNewIncognitoWindow)) {
    incognito_action->SetEnabled(
        IncognitoModePrefs::IsIncognitoAllowed(profile()));
  }

  if (!IsShowingMainUI()) {
    command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, false);
    command_updater_.UpdateCommandEnabled(IDC_OPTIONS, false);
  }
}

void BrowserCommandController::UpdateCommandsForExtensionsMenu() {
  // TODO(crbug.com/41124423): Talk with isandrk@chromium.org about whether this
  // is necessary for the experiment or not.
  if (is_locked_fullscreen_) {
    return;
  }

  command_updater_.UpdateCommandEnabled(
      IDC_EXTENSIONS_SUBMENU_MANAGE_EXTENSIONS,
      /*state=*/true);
  command_updater_.UpdateCommandEnabled(
      IDC_EXTENSIONS_SUBMENU_VISIT_CHROME_WEB_STORE, /*state=*/true);
  command_updater_.UpdateCommandEnabled(IDC_FIND_EXTENSIONS,
                                        /*state=*/true);
}

void BrowserCommandController::UpdateCommandsForTabState() {
  // Keep commands disabled when in locked fullscreen so users cannot exit this
  // mode. Only update navigation ones when the webapp is locked for OnTask
  // (only relevant for non-web browser scenarios).
  // TODO(b/365146870): Remove once we consolidate locked fullscreen with
  // OnTask.
  bool skip_all_command_updates = is_locked_fullscreen_;
#if BUILDFLAG(IS_CHROMEOS)
  if (browser_->IsLockedForOnTask()) {
    skip_all_command_updates = false;
  }
#endif  // BUILDFLAG(IS_CHROMEOS)
  if (skip_all_command_updates) {
    return;
  }

  content::WebContents* current_web_contents =
      browser_->tab_strip_model()->GetActiveWebContents();
  if (!current_web_contents) {  // May be NULL during tab restore.
    return;
  }

  // Navigation commands
  command_updater_.UpdateCommandEnabled(IDC_BACK,
                                        ShouldEnableBackButton(browser_));
  command_updater_.UpdateCommandEnabled(IDC_FORWARD,
                                        ShouldEnableForwardButton(browser_));
  const bool can_reload = CanReload(browser_);
  command_updater_.UpdateCommandEnabled(IDC_RELOAD, can_reload);
  command_updater_.UpdateCommandEnabled(IDC_RELOAD_BYPASSING_CACHE, can_reload);
  command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, can_reload);
  if (is_locked_fullscreen_) {
    // Skip other command updates.
    // NOTE: If new commands are being added, please add them after this
    // conditional and notify the ChromeOS team by filing a bug under this
    // component -- b/?q=componentid:1389107.
    return;
  }

  // Window management commands
  bool is_app = browser_->is_type_app() || browser_->is_type_app_popup();
  bool is_normal = browser_->is_type_normal();

  command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
                                        !is_app && CanDuplicateTab(browser_));
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_MUTE_SITE, !is_app);
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_PIN_TAB, is_normal);
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_GROUP_TAB, is_normal);

  // Page-related commands
  window()->SetStarredState(
      BookmarkTabHelper::FromWebContents(current_web_contents)->is_starred());
  window()->ZoomChangedForActiveTab(false);
  command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
                                        CanViewSource(browser_));

  command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, CanOpenFile(browser_));

  bool can_create_web_app = web_app::CanCreateWebApp(browser_);
  command_updater_.UpdateCommandEnabled(IDC_INSTALL_PWA, can_create_web_app);

#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
  command_updater_.UpdateCommandEnabled(
      IDC_CREATE_SHORTCUT,
      shortcuts::CanCreateDesktopShortcut(current_web_contents));
#else
  command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUT,
                                        can_create_web_app);
#endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)

  UpdateCommandAndActionEnabled(IDC_SEND_TAB_TO_SELF, kActionSendTabToSelf,
                                CanSendTabToSelf(browser_));

  UpdateCommandAndActionEnabled(IDC_QRCODE_GENERATOR, kActionQrCodeGenerator,
                                CanGenerateQrCode(browser_));

  ChromeTranslateClient* chrome_translate_client =
      ChromeTranslateClient::FromWebContents(current_web_contents);
  const bool can_translate =
      chrome_translate_client &&
      chrome_translate_client->GetTranslateManager()->CanManuallyTranslate();
  UpdateCommandAndActionEnabled(IDC_SHOW_TRANSLATE, kActionShowTranslate,
                                can_translate);

  bool is_isolated_app = browser_->app_controller() &&
                         browser_->app_controller()->IsIsolatedWebApp();
  bool is_pinned_home_tab = web_app::IsPinnedHomeTab(
      browser_->tab_strip_model(), browser_->tab_strip_model()->active_index());
  command_updater_.UpdateCommandEnabled(
      IDC_OPEN_IN_CHROME,
      IsWebAppOrCustomTab(browser_) && !is_isolated_app && !is_pinned_home_tab);

  command_updater_.UpdateCommandEnabled(
      IDC_READING_LIST_MENU_ADD_TAB,
      browser_->tab_strip_model()->IsReadLaterSupportedForAny(
          {browser_->tab_strip_model()->active_index()}));

  command_updater_.UpdateCommandEnabled(
      IDC_TOGGLE_REQUEST_TABLET_SITE,
      CanRequestTabletSite(current_web_contents));

  UpdateCommandsForContentRestrictionState();
  UpdateCommandsForBookmarkEditing();
  UpdateCommandsForFind();
  UpdateCommandsForMediaRouter();
  // Update the zoom commands when an active tab is selected.
  UpdateCommandsForZoomState();
  UpdateCommandsForTabKeyboardFocus(GetKeyboardFocusedTabIndex(browser_));

  // Disable the add to comparison table menu when the page is not a standard
  // webpage.
  command_updater_.UpdateCommandEnabled(
      IDC_ADD_TO_COMPARISON_TABLE_MENU,
      commerce::IsUrlEligibleForProductSpecs(
          current_web_contents->GetLastCommittedURL()));
}

void BrowserCommandController::UpdateCommandsForZoomState() {
  content::WebContents* contents =
      browser_->tab_strip_model()->GetActiveWebContents();
  if (!contents) {
    return;
  }
  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents));
  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL,
                                        CanResetZoom(contents));
  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents));
}

void BrowserCommandController::UpdateCommandsForContentRestrictionState() {
  int restrictions = GetContentRestrictions(browser_);

  command_updater_.UpdateCommandEnabled(
      IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
  command_updater_.UpdateCommandEnabled(
      IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
  command_updater_.UpdateCommandEnabled(
      IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
  UpdateSaveAsState();
  UpdatePrintingState();
}

void BrowserCommandController::UpdateCommandsForDevTools() {
  if (is_locked_fullscreen_) {
    return;
  }

  bool dev_tools_enabled = DevToolsWindow::AllowDevToolsFor(
      profile(), browser_->tab_strip_model()->GetActiveWebContents());
  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, dev_tools_enabled);
  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
                                        dev_tools_enabled);
  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_DEVICES,
                                        dev_tools_enabled);
  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
                                        dev_tools_enabled);
  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_TOGGLE,
                                        dev_tools_enabled);
  command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE, dev_tools_enabled);
#if BUILDFLAG(IS_MAC)
  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_JAVASCRIPT_APPLE_EVENTS,
                                        dev_tools_enabled);
#endif
}

void BrowserCommandController::UpdateCommandsForBookmarkEditing() {
  if (is_locked_fullscreen_) {
    return;
  }

  command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_THIS_TAB,
                                        CanBookmarkCurrentTab(browser_));
  command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
                                        CanBookmarkAllTabs(browser_));
}

void BrowserCommandController::UpdateCommandsForBookmarkBar() {
  if (is_locked_fullscreen_) {
    return;
  }

  command_updater_.UpdateCommandEnabled(
      IDC_SHOW_BOOKMARK_BAR, browser_defaults::bookmarks_enabled &&
                                 !profile()->IsGuestSession() &&
                                 !profile()->IsSystemProfile() &&
                                 !profile()->GetPrefs()->IsManagedPreference(
                                     bookmarks::prefs::kShowBookmarkBar) &&
                                 IsShowingMainUI());
}

void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() {
  if (is_locked_fullscreen_) {
    return;
  }

  UpdateSaveAsState();
  command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, CanOpenFile(browser_));
}

void BrowserCommandController::UpdateCommandsForFullscreenMode() {
  if (is_locked_fullscreen_) {
    return;
  }

  const bool is_fullscreen = window() && window()->IsFullscreen();
  const bool show_main_ui = IsShowingMainUI();
  const bool show_location_bar = IsShowingLocationBar();

  const bool main_not_fullscreen = show_main_ui && !is_fullscreen;

  // Navigation commands
  command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);

  // Window management commands
  command_updater_.UpdateCommandEnabled(
      IDC_SHOW_AS_TAB, !browser_->is_type_normal() && !is_fullscreen &&
                           !browser_->is_type_devtools() &&
                           !browser_->is_type_picture_in_picture());

  // Focus various bits of UI
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_location_bar);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_MENU_BAR,
                                        main_not_fullscreen);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_PANE,
                                        main_not_fullscreen);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREVIOUS_PANE,
                                        main_not_fullscreen);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_WEB_CONTENTS_PANE,
                                        main_not_fullscreen);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_BOOKMARKS,
                                        main_not_fullscreen);
  command_updater_.UpdateCommandEnabled(
      IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY, main_not_fullscreen);

  // Show various bits of UI
  command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  command_updater_.UpdateCommandEnabled(
      IDC_FEEDBACK, show_main_ui || browser_->is_type_devtools());
#endif

  command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  command_updater_.UpdateCommandEnabled(IDC_CHROME_TIPS, show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_CHROME_WHATS_NEW, show_main_ui);
#endif
  command_updater_.UpdateCommandEnabled(IDC_CONTENT_CONTEXT_SHARING_SUBMENU,
                                        show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_SHARING_HUB, show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_SHARING_HUB_SCREENSHOT,
                                        show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_MANAGEMENT_PAGE, true);

  if (base::debug::IsProfilingSupported()) {
    command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
  }

#if !BUILDFLAG(IS_MAC)
  // Disable toggling into fullscreen mode if disallowed by pref.
  const bool fullscreen_enabled =
      is_fullscreen ||
      profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed);
#else
  const bool fullscreen_enabled = true;
#endif

  command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN, fullscreen_enabled);
  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_FULLSCREEN_TOOLBAR,
                                        fullscreen_enabled);

  UpdateCommandsForBookmarkBar();
  UpdateCommandsForIncognitoAvailability();
  UpdateCommandsForHostedAppAvailability();
}

void BrowserCommandController::UpdateCommandsForHostedAppAvailability() {
  bool has_toolbar = browser_->is_type_normal() ||
                     web_app::AppBrowserController::IsWebApp(browser_);
  if (window() && window()->ShouldHideUIForFullscreen()) {
    has_toolbar = false;
  }
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, has_toolbar);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_PANE, has_toolbar);
  command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREVIOUS_PANE, has_toolbar);
  command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, has_toolbar);
}

#if BUILDFLAG(IS_CHROMEOS)
namespace {

#if DCHECK_IS_ON()
// Makes sure that all commands that are not allowlisted are disabled. DCHECKs
// otherwise. Compiled only in debug mode.
void NonAllowlistedCommandsAreDisabled(CommandUpdaterImpl* command_updater) {
  constexpr int kAllowlistedIds[] = {IDC_CUT, IDC_COPY, IDC_PASTE};

  // Go through all the command ids, skip the allowlisted ones.
  for (int id : command_updater->GetAllIds()) {
    if (base::Contains(kAllowlistedIds, id)) {
      continue;
    }
    DCHECK(!command_updater->IsCommandEnabled(id));
  }
}
#endif

}  // namespace

void BrowserCommandController::UpdateCommandsForLockedFullscreenMode() {
  bool is_locked_fullscreen =
      platform_util::IsBrowserLockedFullscreen(browser_);
  // Sanity check to make sure this function is called only on state change.
  DCHECK_NE(is_locked_fullscreen, is_locked_fullscreen_);
  if (is_locked_fullscreen == is_locked_fullscreen_) {
    return;
  }
  is_locked_fullscreen_ = is_locked_fullscreen;

  if (is_locked_fullscreen_) {
    command_updater_.DisableAllCommands();
    // Update the state of allowlisted commands:
    // IDC_CUT/IDC_COPY/IDC_PASTE,
    UpdateCommandsForContentRestrictionState();
    // TODO(crbug.com/41426009): Re-enable Find and Zoom in locked fullscreen.
    // All other commands will be disabled (there is an early return in their
    // corresponding UpdateCommandsFor* functions).
#if DCHECK_IS_ON()
    NonAllowlistedCommandsAreDisabled(&command_updater_);
#endif
    // Enable commands that allow users to switch between tabs and find content
    // within a webpage if the webapp is locked for OnTask
    // (only relevant for non-web browser scenarios).
    if (browser_->IsLockedForOnTask()) {
      bool supports_tabs =
          browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
      command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, supports_tabs);
      command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
                                            supports_tabs);
      UpdateCommandsForFind();
    }
  } else {
    // Do an init call to re-initialize command state after the
    // DisableAllCommands.
    InitCommandState();
  }
}
#endif  // BUILDFLAG(IS_CHROMEOS)

void BrowserCommandController::UpdatePrintingState() {
  if (is_locked_fullscreen_) {
    return;
  }

  UpdateCommandAndActionEnabled(IDC_PRINT, kActionPrint, CanPrint(browser_));
#if BUILDFLAG(ENABLE_PRINTING)
  command_updater_.UpdateCommandEnabled(IDC_BASIC_PRINT,
                                        CanBasicPrint(browser_));
#endif
}

#if BUILDFLAG(ENABLE_GLIC)
void BrowserCommandController::UpdateGlicState() {
  if (glic::GlicEnabling::IsEnabledByFlags()) {
    auto* service =
        glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile());
    if (service) {
      command_updater_.UpdateCommandEnabled(
          IDC_OPEN_GLIC, glic::GlicEnabling::IsEnabledForProfile(profile()) &&
                             !service->IsWindowOrFreShowing());
    }
  }
}
#endif

void BrowserCommandController::UpdateSaveAsState() {
  if (is_locked_fullscreen_) {
    return;
  }

  command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, CanSavePage(browser_));
}

void BrowserCommandController::UpdateReloadStopState(bool is_loading,
                                                     bool force) {
  // Skip command updates when in locked fullscreen mode unless the instance is
  // locked for OnTask (only relevant for non-web browser scenarios).
  // TODO(crbug.com/365146870): Remove once we consolidate locked fullscreen
  // with OnTask.
  bool should_skip_command_updates = is_locked_fullscreen_;
#if BUILDFLAG(IS_CHROMEOS)
  if (browser_->IsLockedForOnTask()) {
    should_skip_command_updates = false;
  }
#endif
  if (should_skip_command_updates) {
    return;
  }

  window()->UpdateReloadStopState(is_loading, force);
  command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
  UpdateCloseFindOrStop();
}

void BrowserCommandController::UpdateTabRestoreCommandState() {
  if (is_locked_fullscreen_) {
    return;
  }

  sessions::TabRestoreService* tab_restore_service =
      TabRestoreServiceFactory::GetForProfile(profile());
  // The command is enabled if the service hasn't loaded yet to trigger loading.
  // The command is updated once the load completes.
  command_updater_.UpdateCommandEnabled(
      IDC_RESTORE_TAB,
      tab_restore_service && (!tab_restore_service->IsLoaded() ||
                              !tab_restore_service->entries().empty()));
}

void BrowserCommandController::UpdateCommandsForFind() {
  TabStripModel* model = browser_->tab_strip_model();
  int active_index = model->active_index();

  bool enabled = active_index != TabStripModel::kNoTab &&
                 !model->IsTabBlocked(active_index) &&
                 !browser_->is_type_devtools();

  command_updater_.UpdateCommandEnabled(IDC_FIND, enabled);
  command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, enabled);
  command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, enabled);
}

void BrowserCommandController::UpdateCloseFindOrStop() {
  bool enabled = CanCloseFind(browser_) || IsCommandEnabled(IDC_STOP);
  command_updater_.UpdateCommandEnabled(IDC_CLOSE_FIND_OR_STOP, enabled);
}

void BrowserCommandController::UpdateCommandsForMediaRouter() {
  if (is_locked_fullscreen_) {
    return;
  }

  UpdateCommandAndActionEnabled(IDC_ROUTE_MEDIA, kActionRouteMedia,
                                CanRouteMedia(browser_));
}

void BrowserCommandController::UpdateCommandsForTabKeyboardFocus(
    std::optional<int> target_index) {
  command_updater_.UpdateCommandEnabled(
      IDC_DUPLICATE_TARGET_TAB, !browser_->is_type_app() &&
                                    !browser_->is_type_app_popup() &&
                                    target_index.has_value() &&
                                    CanDuplicateTabAt(browser_, *target_index));
  const bool normal_window = browser_->is_type_normal();
  command_updater_.UpdateCommandEnabled(
      IDC_MUTE_TARGET_SITE, normal_window && target_index.has_value());
  command_updater_.UpdateCommandEnabled(
      IDC_PIN_TARGET_TAB, normal_window && target_index.has_value());
  command_updater_.UpdateCommandEnabled(
      IDC_GROUP_TARGET_TAB, normal_window && target_index.has_value());
}

void BrowserCommandController::UpdateCommandsForWebContentsFocus() {
#if BUILDFLAG(IS_MAC)
  // On Mac, toggling caret browsing changes whether it's enabled or not
  // based on web contents focus.
  command_updater_.UpdateCommandEnabled(IDC_CARET_BROWSING_TOGGLE,
                                        CanToggleCaretBrowsing(browser_));
#endif  // BUILDFLAG(IS_MAC)
}

void BrowserCommandController::UpdateCommandsForTabStripStateChanged() {
  if (is_locked_fullscreen_) {
    // Keep tab management commands disabled when in locked fullscreen so users
    // cannot exit this mode. Only relevant for non-web browser scenarios.
    return;
  }

  int tab_index = browser_->tab_strip_model()->active_index();
  // No commands are updated if there is not yet any selected tab.
  if (tab_index == TabStripModel::kNoTab) {
    return;
  }
  command_updater_.UpdateCommandEnabled(
      IDC_CLOSE_TAB,
      web_app::IsTabClosable(browser_->tab_strip_model(), tab_index));
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_TABS_TO_RIGHT,
                                        CanCloseTabsToRight(browser_));
  command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_OTHER_TABS,
                                        CanCloseOtherTabs(browser_));
  command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_TO_NEW_WINDOW,
                                        CanMoveActiveTabToNewWindow(browser_));
  command_updater_.UpdateCommandEnabled(IDC_NEW_SPLIT_TAB,
                                        browser_->is_type_normal());
  UpdateCommandsForBookmarkEditing();
}

actions::ActionItem* BrowserCommandController::FindAction(
    actions::ActionId action_id) {
  actions::ActionItem* const root_action_item =
      browser_->GetActions()->root_action_item();

  // If there is no root action item then ActionManager falls back to the
  // root_action_parent_ which might contain actions from other browser windows.
  if (!root_action_item) {
    return nullptr;
  }

  return actions::ActionManager::Get().FindAction(action_id, root_action_item);
}

void BrowserCommandController::UpdateCommandAndActionEnabled(
    int command_id,
    actions::ActionId action_id,
    bool enabled) {
  command_updater_.UpdateCommandEnabled(command_id, enabled);
  if (auto* const action = FindAction(action_id)) {
    action->SetEnabled(enabled);
  }
}

void BrowserCommandController::UpdateCommandsForEnableGlicChanged() {
#if BUILDFLAG(ENABLE_GLIC)
  command_updater_.UpdateCommandEnabled(
      IDC_OPEN_GLIC, glic::GlicEnabling::IsEnabledForProfile(profile()));
#endif  //  BUILDFLAG(ENABLE_GLIC)
}

BrowserWindow* BrowserCommandController::window() {
  return browser_->window();
}

Profile* BrowserCommandController::profile() {
  return browser_->profile();
}

}  // namespace chrome
