// Copyright 2013 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/extensions/commands/command_service.h"

#include <utility>

#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/api/extension_action/action_info.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/test/test_extension_dir.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/command_constants.h"
#include "ui/events/keycodes/keyboard_codes.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace {
const char kBasicBrowserActionKeybinding[] = "Ctrl+Shift+F";
const char kBasicNamedKeybinding[] = "Ctrl+Shift+Y";
const char kBasicAlternateKeybinding[] = "Ctrl+Shift+G";
const char kBasicNamedCommand[] = "toggle-feature";
constexpr char kAltNKeybinding[] = "Alt+N";
constexpr char kAltZKeybinding[] = "Alt+Z";
constexpr char kExtensionId[] = "pgoakhfeplldmjheffidklpoklkppipp";
constexpr char kManifestTemplate[] = R"({
    "name": "An action to test if upgrading from MV2 to MV3 succeeds.",
    "version": "1.0",
    "manifest_version": %d,
    "commands": {
      "%s": {
        "suggested_key": "%s"
      }
    },
    "%s": {}})";

// Get another command platform, which is used for simulating a command has been
// assigned with a shortcut on another platform.
std::string GetAnotherCommandPlatform() {
#if BUILDFLAG(IS_WIN)
  return ui::kKeybindingPlatformMac;
#elif BUILDFLAG(IS_MAC)
  return ui::kKeybindingPlatformChromeOs;
#elif BUILDFLAG(IS_CHROMEOS)
  return ui::kKeybindingPlatformLinux;
#elif BUILDFLAG(IS_LINUX)
  return ui::kKeybindingPlatformWin;
#else
  return "";
#endif
}

// Parameters passed to CommandServiceMv3UpgradeTest parameterized tests.
struct ManifestCommandTestParameters {
  const char* action_name;          // e.g. "browser_action", "page_action".
  const char* action_command_name;  // e.g. "_execute_browser_action",
                                    // "_execute_page_action".
  // e.g. the associated folder below
  // //chrome/test/data/extensions/api_test/keybinding/update/ that contains the
  // unpacked extension files for webstore and .crx installs.
  const char* action_command_mv2_extension_path;
};

}  // namespace

namespace extensions {

using CommandServiceTest = ExtensionApiTest;
// Test class for testing keybinding changes across MV2->MV3 reloads/updates.
class CommandServiceMv3UpgradeTest
    : public ExtensionApiTest,
      public testing::WithParamInterface<ManifestCommandTestParameters> {
 protected:
  // Create a new extension from a manifest for MV2 and verify its command
  // shortcuts are setup correctly.
  std::string LoadExtensionMv2(const char* suggested_keybinding);
  // Reload the extension from a manifest for MV3 and verify its command
  // shortcut has the new suggested keybinding.
  void ReloadExtensionMv3(const std::string& id,
                          const char* new_suggested_keybinding);
  // Install an extension with `id`. `install_from_crx` = false means it will
  // install from webstore.
  void InstallExtensionMv2(const std::string& id,
                           bool install_from_crx = false);
  // Update the extension with `id` (from webstore or via crx) from the
  // `mv3_extension_upgrade_folder`.
  void UpdateExtensionMv3(const std::string& id,
                          const char* mv3_extension_upgrade_folder);
  // Modify the browser action keybinding as if it was modified by the user.
  void ChangeMv2CommandKeybinding(const std::string& id,
                                  const char* new_keybinding);
  bool CommandHasAltPlusKeybinding(const std::string& id,
                                   const char* action_command_name,
                                   const ui::KeyboardCode key);
  bool CommandHasNoKeybinding(const std::string& id,
                              const char* action_command_name);
  // Checks that extension with `id` no longer has MV2 command action
  // keybindings and now has an MV3 keybinding of Alt + `keyboard_code`.
  void CheckMv3UpgradeHasExpectedKeybindings(
      const std::string& id,
      const ui::KeyboardCode keyboard_code);

  TestExtensionDir& test_dir() { return test_dir_; }
  CommandService* command_service() { return CommandService::Get(profile()); }

 private:
  TestExtensionDir test_dir_;
  base::FilePath test_path_;
};

std::string CommandServiceMv3UpgradeTest::LoadExtensionMv2(
    const char* suggested_keybinding) {
  ManifestCommandTestParameters test_params = GetParam();
  test_dir().WriteManifest(
      base::StringPrintf(kManifestTemplate, 2, test_params.action_command_name,
                         suggested_keybinding, test_params.action_name));

  // Install MV2 of the extension.
  const Extension* extension = LoadExtension(
      test_dir().UnpackedPath(), {.wait_for_registration_stored = true});
  if (!extension) {
    ADD_FAILURE() << "Couldn't load extension successfully for test setup.";
  }
  const std::string unpacked_extension_id = extension->id();
  EXPECT_TRUE(extension_registry()->enabled_extensions().Contains(
      unpacked_extension_id));

  // Verify it has an MV2 action command of Alt+N.
  EXPECT_TRUE(CommandHasAltPlusKeybinding(unpacked_extension_id.c_str(),
                                          test_params.action_command_name,
                                          ui::VKEY_N));
  // Verify MV3 action command is set to nothing before we upgrade.
  EXPECT_TRUE(CommandHasNoKeybinding(unpacked_extension_id.c_str(),
                                     manifest_values::kActionCommandEvent));
  return unpacked_extension_id;
}

void CommandServiceMv3UpgradeTest::ReloadExtensionMv3(
    const std::string& id,
    const char* new_suggested_keybinding) {
  test_dir().WriteManifest(base::StringPrintf(
      kManifestTemplate, 3, manifest_values::kActionCommandEvent,
      new_suggested_keybinding, manifest_keys::kAction));
  ReloadExtension(id);
  EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(id));
}

void CommandServiceMv3UpgradeTest::InstallExtensionMv2(const std::string& id,
                                                       bool install_from_crx) {
  // TODO(jlulejian): Try to make these test class members for less repetition.
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir scoped_temp_dir;
  base::FilePath pem_path =
      test_data_dir_.AppendASCII("keybinding").AppendASCII("keybinding.pem");
  ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());

  ManifestCommandTestParameters test_params = GetParam();
  base::FilePath path_mv2 = PackExtensionWithOptions(
      test_data_dir_.AppendASCII("keybinding")
          .AppendASCII("update")
          .AppendASCII(test_params.action_command_mv2_extension_path),
      scoped_temp_dir.GetPath().AppendASCII("v1.crx"), pem_path,
      base::FilePath());
  ASSERT_FALSE(path_mv2.empty());

  // Install MV2 of the extension.
  if (install_from_crx) {
    ASSERT_TRUE(InstallExtension(path_mv2, 1));
  } else {
    ASSERT_TRUE(InstallExtensionFromWebstore(path_mv2, 1));
  }
  EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(id));

  // Verify it has an MV2 action command of Alt+N.
  EXPECT_TRUE(CommandHasAltPlusKeybinding(id, test_params.action_command_name,
                                          ui::VKEY_N));
  // Verify MV3 action command is set to nothing before we upgrade.
  EXPECT_TRUE(CommandHasNoKeybinding(id, manifest_values::kActionCommandEvent));
}

void CommandServiceMv3UpgradeTest::UpdateExtensionMv3(
    const std::string& id,
    const char* mv3_extension_upgrade_folder) {
  // TODO(jlulejian): Try to make these test class members for less repetition.
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir scoped_temp_dir;
  base::FilePath pem_path =
      test_data_dir_.AppendASCII("keybinding").AppendASCII("keybinding.pem");
  ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());

  base::FilePath path_mv3 =
      PackExtensionWithOptions(test_data_dir_.AppendASCII("keybinding")
                                   .AppendASCII("update")
                                   .AppendASCII(mv3_extension_upgrade_folder),
                               scoped_temp_dir.GetPath().AppendASCII("v2.crx"),
                               pem_path, base::FilePath());
  ASSERT_FALSE(path_mv3.empty());

  // Update to MV3 with an action command instead of a browser action.
  ASSERT_TRUE(UpdateExtension(id, path_mv3, 0));
  EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(id));
}

void CommandServiceMv3UpgradeTest::ChangeMv2CommandKeybinding(
    const std::string& id,
    const char* new_keybinding) {
  const char* action_command_name = GetParam().action_command_name;
  Command action_command =
      command_service()->FindCommandByName(id, action_command_name);
  command_service()->UpdateKeybindingPrefs(id, action_command_name,
                                           new_keybinding);
}

void CommandServiceMv3UpgradeTest::CheckMv3UpgradeHasExpectedKeybindings(
    const std::string& id,
    const ui::KeyboardCode keyboard_code) {
  // Verify both MV2 commands are set to nothing.
  EXPECT_TRUE(
      CommandHasNoKeybinding(id, manifest_values::kBrowserActionCommandEvent));
  EXPECT_TRUE(
      CommandHasNoKeybinding(id, manifest_values::kPageActionCommandEvent));

  // Verify extension now has an MV3 action command of Alt+<keyboard_code>.
  EXPECT_TRUE(CommandHasAltPlusKeybinding(
      id, manifest_values::kActionCommandEvent, keyboard_code));
}

bool CommandServiceMv3UpgradeTest::CommandHasAltPlusKeybinding(
    const std::string& id,
    const char* action_command_name,
    const ui::KeyboardCode key) {
  ui::Accelerator accelerator = command_service()
                                    ->FindCommandByName(id, action_command_name)
                                    .accelerator();
  return key == accelerator.key_code() && accelerator.IsAltDown() &&
         !accelerator.IsShiftDown() && !accelerator.IsCtrlDown();
}
bool CommandServiceMv3UpgradeTest::CommandHasNoKeybinding(
    const std::string& id,
    const char* action_command_name) {
  ui::Accelerator accelerator = command_service()
                                    ->FindCommandByName(id, action_command_name)
                                    .accelerator();
  return ui::VKEY_UNKNOWN == accelerator.key_code();
}

// Tests that a suggested keybinding for an action command in MV2 persists when
// the extension is reloaded (unpacked) and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       ActionCommandUpgradesDuringReload) {
  const std::string unpacked_extension_id = LoadExtensionMv2(
      /*suggested_keybinding=*/kAltNKeybinding);
  ReloadExtensionMv3(unpacked_extension_id,
                     /*new_suggested_keybinding=*/kAltNKeybinding);
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(unpacked_extension_id,
                                        /*keyboard_code=*/ui::VKEY_N);
}

// Tests that a suggested keybinding for an action command in MV2 persists when
// the extension is updated from the webstore and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       ActionCommandUpgradesDuringWebstoreUpdate) {
  InstallExtensionMv2(kExtensionId);
  UpdateExtensionMv3(kExtensionId,
                     /*mv3_extension_upgrade_folder=*/"v2_upgrade");
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(kExtensionId,
                                        /*keyboard_code=*/ui::VKEY_N);
}

// Tests that a suggested keybinding for an action command in MV2 persists when
// the extension is updated (via .crx) and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       ActionCommandUpgradesDuringCrxUpdate) {
  InstallExtensionMv2(kExtensionId, /*install_from_crx=*/true);
  UpdateExtensionMv3(kExtensionId,
                     /*mv3_extension_upgrade_folder=*/"v2_upgrade");
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(kExtensionId,
                                        /*keyboard_code=*/ui::VKEY_N);
}

// Tests that a user modified keybinding for an action command in MV2 persists
// when the extension is reloaded (unpacked) and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       UserModifiedActionCommandSurvivesReload) {
  const std::string unpacked_extension_id = LoadExtensionMv2(
      /*suggested_keybinding=*/kAltNKeybinding);
  ChangeMv2CommandKeybinding(unpacked_extension_id,
                             /*new_keybinding=*/kAltZKeybinding);
  ReloadExtensionMv3(unpacked_extension_id,
                     /*new_suggested_keybinding=*/kAltNKeybinding);
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(unpacked_extension_id,
                                        /*keyboard_code=*/ui::VKEY_Z);
}

// Tests that a user-modified keybinding for an action command in MV2 persists
// when the extension is updated from the webstore and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       UserModifiedCommandSurvivesWebstoreUpdate) {
  InstallExtensionMv2(kExtensionId);
  ChangeMv2CommandKeybinding(kExtensionId,
                             /*new_keybinding=*/kAltZKeybinding);
  UpdateExtensionMv3(kExtensionId,
                     /*mv3_extension_upgrade_folder=*/"v2_upgrade");
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(kExtensionId,
                                        /*keyboard_code=*/ui::VKEY_Z);
}

// Tests that a user modified keybinding for an action command in MV2 persists
// when the extension is updated (via .crx) and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       UserModifiedCommandSurvivesCrxUpdate) {
  InstallExtensionMv2(kExtensionId, /*install_from_crx=*/true);
  ChangeMv2CommandKeybinding(kExtensionId,
                             /*new_keybinding=*/kAltZKeybinding);
  UpdateExtensionMv3(kExtensionId,
                     /*mv3_extension_upgrade_folder=*/"v2_upgrade");
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(kExtensionId,
                                        /*keyboard_code=*/ui::VKEY_Z);
}

// Tests that a modified suggested keybinding for an action command in MV2
// persists when the extension is reloaded (unpacked) and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       SuggestedKeyModifiedActionCommandSurvivesReload) {
  const std::string unpacked_extension_id = LoadExtensionMv2(
      /*suggested_keybinding=*/kAltNKeybinding);
  ReloadExtensionMv3(unpacked_extension_id,
                     /*new_suggested_keybinding=*/"Alt+U");
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(unpacked_extension_id,
                                        /*keyboard_code=*/ui::VKEY_U);
}

// Tests that a modified suggested keybinding for an action command in MV2
// persists when the extension is updated (via webstore) and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       SuggestedKeyModifiedActionCommandSurvivesWebstore) {
  InstallExtensionMv2(kExtensionId);
  UpdateExtensionMv3(kExtensionId, "v2_upgrade_reassign");
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(kExtensionId,
                                        /*keyboard_code=*/ui::VKEY_U);
}

// Tests that a modified suggested keybinding for an action command in MV2
// persists when the extension is updated (via .crx) and upgraded to MV3
// (_execute_action_command).
IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest,
                       SuggestedKeyModifiedActionCommandSurvivesCrx) {
  InstallExtensionMv2(kExtensionId, /*install_from_crx=*/true);
  UpdateExtensionMv3(kExtensionId,
                     /*mv3_extension_upgrade_folder=*/"v2_upgrade_reassign");
  ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure());

  CheckMv3UpgradeHasExpectedKeybindings(kExtensionId,
                                        /*keyboard_code=*/ui::VKEY_U);
}

IN_PROC_BROWSER_TEST_F(CommandServiceTest, RemoveShortcutSurvivesUpdate) {
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir scoped_temp_dir;
  EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
  base::FilePath pem_path = test_data_dir_.
      AppendASCII("keybinding").AppendASCII("keybinding.pem");
  base::FilePath path_v1 =
      PackExtensionWithOptions(test_data_dir_.AppendASCII("keybinding")
                                   .AppendASCII("update")
                                   .AppendASCII("v1"),
                               scoped_temp_dir.GetPath().AppendASCII("v1.crx"),
                               pem_path, base::FilePath());
  base::FilePath path_v2 =
      PackExtensionWithOptions(test_data_dir_.AppendASCII("keybinding")
                                   .AppendASCII("update")
                                   .AppendASCII("v2"),
                               scoped_temp_dir.GetPath().AppendASCII("v2.crx"),
                               pem_path, base::FilePath());

  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  CommandService* command_service = CommandService::Get(profile());

  // Install v1 of the extension.
  ASSERT_TRUE(InstallExtension(path_v1, 1));
  EXPECT_TRUE(registry->enabled_extensions().GetByID(kExtensionId));

  // Verify it has a command of Alt+Shift+F.
  ui::Accelerator accelerator =
      command_service
          ->FindCommandByName(kExtensionId,
                              manifest_values::kActionCommandEvent)
          .accelerator();
  EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
  EXPECT_FALSE(accelerator.IsCtrlDown());
  EXPECT_TRUE(accelerator.IsShiftDown());
  EXPECT_TRUE(accelerator.IsAltDown());

  // Remove the keybinding.
  command_service->UpdateKeybindingPrefs(kExtensionId,
                                         manifest_values::kActionCommandEvent,
                                         /*keystroke=*/"");

  // Verify it got removed.
  accelerator = command_service
                    ->FindCommandByName(kExtensionId,
                                        manifest_values::kActionCommandEvent)
                    .accelerator();
  EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());

  // Update to version 2.
  EXPECT_TRUE(UpdateExtension(kExtensionId, path_v2, 0));
  EXPECT_TRUE(registry->enabled_extensions().GetByID(kExtensionId));

  // Verify it is still set to nothing.
  accelerator = command_service
                    ->FindCommandByName(kExtensionId,
                                        manifest_values::kActionCommandEvent)
                    .accelerator();
  EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
}

IN_PROC_BROWSER_TEST_F(CommandServiceTest,
                       RemoveKeybindingPrefsShouldBePlatformSpecific) {
  base::FilePath extension_dir =
      test_data_dir_.AppendASCII("keybinding").AppendASCII("basics");
  const Extension* extension = InstallExtension(extension_dir, 1);
  ASSERT_TRUE(extension);

  ScopedDictPrefUpdate updater(profile()->GetPrefs(),
                               prefs::kExtensionCommands);
  base::Value::Dict& bindings = updater.Get();

  // Simulate command |toggle-feature| has been assigned with a shortcut on
  // another platform.
  std::string anotherPlatformKey = GetAnotherCommandPlatform() + ":Alt+G";
  const char kNamedCommandName[] = "toggle-feature";
  base::Value::Dict keybinding;
  keybinding.Set("extension", extension->id());
  keybinding.Set("command_name", kNamedCommandName);
  keybinding.Set("global", false);
  bindings.Set(anotherPlatformKey, std::move(keybinding));

  CommandService* command_service = CommandService::Get(profile());
  command_service->RemoveKeybindingPrefs(extension->id(), kNamedCommandName);

  // Removal of keybinding preference should be platform-specific, so the key on
  // another platform should always remained.
  EXPECT_TRUE(bindings.Find(anotherPlatformKey));
}

IN_PROC_BROWSER_TEST_F(CommandServiceTest,
                       GetExtensionActionCommandQueryAll) {
  base::FilePath extension_dir =
      test_data_dir_.AppendASCII("keybinding").AppendASCII("basics");
  const Extension* extension = InstallExtension(extension_dir, 1);
  ASSERT_TRUE(extension);

  CommandService* command_service = CommandService::Get(profile());

  {
    Command command;
    bool active = false;
    EXPECT_TRUE(command_service->GetExtensionActionCommand(
        extension->id(), ActionInfo::Type::kAction, CommandService::ALL,
        &command, &active));

    EXPECT_EQ(kBasicBrowserActionKeybinding,
              Command::AcceleratorToString(command.accelerator()));
    EXPECT_TRUE(active);
  }

  command_service->UpdateKeybindingPrefs(extension->id(),
                                         manifest_values::kActionCommandEvent,
                                         kBasicAlternateKeybinding);

  {
    Command command;
    bool active = false;
    EXPECT_TRUE(command_service->GetExtensionActionCommand(
        extension->id(), ActionInfo::Type::kAction, CommandService::ALL,
        &command, &active));

    EXPECT_EQ(kBasicAlternateKeybinding,
              Command::AcceleratorToString(command.accelerator()));
    EXPECT_TRUE(active);
  }

  command_service->RemoveKeybindingPrefs(extension->id(),
                                         manifest_values::kActionCommandEvent);

  {
    Command command;
    bool active = true;
    EXPECT_TRUE(command_service->GetExtensionActionCommand(
        extension->id(), ActionInfo::Type::kAction, CommandService::ALL,
        &command, &active));

    EXPECT_EQ(kBasicBrowserActionKeybinding,
              Command::AcceleratorToString(command.accelerator()));
    EXPECT_FALSE(active);
  }

  command_service->UpdateKeybindingPrefs(extension->id(),
                                         manifest_values::kActionCommandEvent,
                                         /*keystroke=*/"");

  {
    Command command;
    bool active = true;
    EXPECT_TRUE(command_service->GetExtensionActionCommand(
        extension->id(), ActionInfo::Type::kAction, CommandService::ALL,
        &command, &active));

    EXPECT_EQ(ui::VKEY_UNKNOWN, command.accelerator().key_code());
    EXPECT_FALSE(active);
  }
}

IN_PROC_BROWSER_TEST_F(CommandServiceTest,
                       GetExtensionActionCommandQueryActive) {
  base::FilePath extension_dir =
      test_data_dir_.AppendASCII("keybinding").AppendASCII("basics");
  const Extension* extension = InstallExtension(extension_dir, 1);
  ASSERT_TRUE(extension);

  CommandService* command_service = CommandService::Get(profile());

  {
    Command command;
    bool active = false;
    EXPECT_TRUE(command_service->GetExtensionActionCommand(
        extension->id(), ActionInfo::Type::kAction, CommandService::ACTIVE,
        &command, &active));

    EXPECT_EQ(kBasicBrowserActionKeybinding,
              Command::AcceleratorToString(command.accelerator()));
    EXPECT_TRUE(active);
  }

  command_service->UpdateKeybindingPrefs(extension->id(),
                                         manifest_values::kActionCommandEvent,
                                         kBasicAlternateKeybinding);

  {
    Command command;
    bool active = false;
    EXPECT_TRUE(command_service->GetExtensionActionCommand(
        extension->id(), ActionInfo::Type::kAction, CommandService::ACTIVE,
        &command, &active));

    EXPECT_EQ(kBasicAlternateKeybinding,
              Command::AcceleratorToString(command.accelerator()));
    EXPECT_TRUE(active);
  }

  command_service->RemoveKeybindingPrefs(extension->id(),
                                         manifest_values::kActionCommandEvent);

  {
    Command command;
    bool active = false;
    EXPECT_FALSE(command_service->GetExtensionActionCommand(
        extension->id(), ActionInfo::Type::kAction, CommandService::ACTIVE,
        &command, &active));
  }
}

IN_PROC_BROWSER_TEST_F(CommandServiceTest,
                       GetNamedCommandsQueryAll) {
  base::FilePath extension_dir =
      test_data_dir_.AppendASCII("keybinding").AppendASCII("basics");
  const Extension* extension = InstallExtension(extension_dir, 1);
  ASSERT_TRUE(extension);

  CommandService* command_service = CommandService::Get(profile());

  {
    ui::CommandMap command_map;
    EXPECT_TRUE(command_service->GetNamedCommands(
        extension->id(), CommandService::ALL, CommandService::ANY_SCOPE,
        &command_map));

    ASSERT_EQ(1u, command_map.count(kBasicNamedCommand));
    ui::Command command = command_map[kBasicNamedCommand];
    EXPECT_EQ(kBasicNamedKeybinding,
              Command::AcceleratorToString(command.accelerator()));
  }

  command_service->UpdateKeybindingPrefs(
      extension->id(), kBasicNamedCommand, kBasicAlternateKeybinding);

  {
    ui::CommandMap command_map;
    EXPECT_TRUE(command_service->GetNamedCommands(
        extension->id(), CommandService::ALL, CommandService::ANY_SCOPE,
        &command_map));

    ASSERT_EQ(1u, command_map.count(kBasicNamedCommand));
    ui::Command command = command_map[kBasicNamedCommand];
    EXPECT_EQ(kBasicAlternateKeybinding,
              Command::AcceleratorToString(command.accelerator()));
  }

  // Tests that removing the keybinding pref restores the default binding.
  command_service->RemoveKeybindingPrefs(extension->id(), kBasicNamedCommand);

  {
    ui::CommandMap command_map;
    EXPECT_TRUE(command_service->GetNamedCommands(
        extension->id(), CommandService::ALL, CommandService::ANY_SCOPE,
        &command_map));

    ASSERT_EQ(1u, command_map.count(kBasicNamedCommand));
    ui::Command command = command_map[kBasicNamedCommand];
    EXPECT_EQ(kBasicNamedKeybinding,
              Command::AcceleratorToString(command.accelerator()));
  }

  // Tests that setting an empty keybinding string unsets the binding.
  command_service->UpdateKeybindingPrefs(extension->id(), kBasicNamedCommand,
                                         /*keystroke=*/"");
  {
    ui::CommandMap command_map;
    EXPECT_TRUE(command_service->GetNamedCommands(
        extension->id(), CommandService::ALL, CommandService::ANY_SCOPE,
        &command_map));

    ASSERT_EQ(1u, command_map.count(kBasicNamedCommand));
    ui::Command command = command_map[kBasicNamedCommand];
    EXPECT_EQ(ui::VKEY_UNKNOWN, command.accelerator().key_code());
  }
}

IN_PROC_BROWSER_TEST_F(CommandServiceTest, GetNamedCommandsQueryActive) {
  base::FilePath extension_dir =
      test_data_dir_.AppendASCII("keybinding").AppendASCII("basics");
  const Extension* extension = InstallExtension(extension_dir, 1);
  ASSERT_TRUE(extension);

  CommandService* command_service = CommandService::Get(profile());

  {
    ui::CommandMap command_map;
    EXPECT_TRUE(command_service->GetNamedCommands(
        extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE,
        &command_map));

    ASSERT_EQ(1u, command_map.count(kBasicNamedCommand));
    ui::Command command = command_map[kBasicNamedCommand];
    EXPECT_EQ(kBasicNamedKeybinding,
              Command::AcceleratorToString(command.accelerator()));
  }

  command_service->UpdateKeybindingPrefs(
      extension->id(), kBasicNamedCommand, kBasicAlternateKeybinding);

  {
    ui::CommandMap command_map;
    EXPECT_TRUE(command_service->GetNamedCommands(
        extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE,
        &command_map));

    ASSERT_EQ(1u, command_map.count(kBasicNamedCommand));
    ui::Command command = command_map[kBasicNamedCommand];
    EXPECT_EQ(kBasicAlternateKeybinding,
              Command::AcceleratorToString(command.accelerator()));
  }

  command_service->RemoveKeybindingPrefs(extension->id(), kBasicNamedCommand);

  {
    ui::CommandMap command_map;
    command_service->GetNamedCommands(
        extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE,
        &command_map);
    EXPECT_EQ(0u, command_map.count(kBasicNamedCommand));
  }
}

// Test both browser and page actions for these tests.
INSTANTIATE_TEST_SUITE_P(BrowserAction,
                         CommandServiceMv3UpgradeTest,
                         testing::Values(ManifestCommandTestParameters{
                             manifest_keys::kBrowserAction,
                             manifest_values::kBrowserActionCommandEvent,
                             "v1_upgrade_browser_action"}));

INSTANTIATE_TEST_SUITE_P(PageAction,
                         CommandServiceMv3UpgradeTest,
                         testing::Values(ManifestCommandTestParameters{
                             manifest_keys::kPageAction,
                             manifest_values::kPageActionCommandEvent,
                             "v1_upgrade_page_action"}));

}  // namespace extensions
