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

// This file contains UI interactive tests for the extensions commands API.
// For non-UI interactive tests, see extension_keybinding_browsertest.cc.

#include "base/containers/contains.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/commands/command_service.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
#include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/sessions/content/session_tab_helper.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/javascript_test_observer.h"
#include "extensions/browser/extension_action.h"
#include "extensions/browser/extension_action_manager.h"
#include "extensions/browser/test_event_router_observer.h"
#include "extensions/common/api/extension_action/action_info.h"
#include "extensions/common/api/extension_action/action_info_test_util.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/blink/public/common/switches.h"

using content::WebContents;

namespace extensions {

namespace {

// Name of the command for the "basics" test extension.
const char kBasicsShortcutCommandName[] = "toggle-feature";

#if BUILDFLAG(IS_MAC)
const char kBookmarkKeybinding[] = "Command+D";
#else
const char kBookmarkKeybinding[] = "Ctrl+D";
#endif  // BUILDFLAG(IS_MAC)

bool SendBookmarkKeyPressSync(Browser* browser) {
  return ui_test_utils::SendKeyPressSync(browser, ui::VKEY_D,
#if BUILDFLAG(IS_MAC)
                                         false, false, false, true
#else
      true, false, false, false
#endif
  );
}

// A scoped observer that listens for dom automation messages.
class DomMessageListener : public content::TestMessageHandler {
 public:
  explicit DomMessageListener(content::WebContents* web_contents);

  DomMessageListener(const DomMessageListener&) = delete;
  DomMessageListener& operator=(const DomMessageListener&) = delete;

  ~DomMessageListener() override;

  // Wait until a message is received.
  void Wait();

  // Clears and resets the observer.
  void Clear();

  const std::string& message() const { return message_; }

 private:
  // content::TestMessageHandler:
  MessageResponse HandleMessage(const std::string& json) override;
  void Reset() override;

  // The message received. Note that this will be JSON, so if it is a string,
  // it will be wrapped in quotes.
  std::string message_;

  content::JavascriptTestObserver observer_;
};

DomMessageListener::DomMessageListener(content::WebContents* web_contents)
    : observer_(web_contents, this) {
}

DomMessageListener::~DomMessageListener() = default;

void DomMessageListener::Wait() {
  observer_.Run();
}

void DomMessageListener::Clear() {
  // We don't just call this in DomMessageListener::Reset() because the
  // JavascriptTestObserver's Reset() method also resets its handler (this).
  observer_.Reset();
}

content::TestMessageHandler::MessageResponse DomMessageListener::HandleMessage(
    const std::string& json) {
  message_ = json;
  return DONE;
}

void DomMessageListener::Reset() {
  TestMessageHandler::Reset();
  message_.clear();
}

// Programmatically (from the extension) disables the action globally.
void DisableActionGlobally(Profile* profile, const Extension& extension) {
  // Omitting the tab_id parameter disables the action globally.
  static constexpr char kScriptTemplate[] =
      R"(chrome.action.disable(() => {
             chrome.test.sendScriptResult(
                 chrome.runtime.lastError ?
                     chrome.runtime.lastError.message :
                     'success');
           });)";

  base::Value set_result = browsertest_util::ExecuteScriptInBackgroundPage(
      profile, extension.id(), kScriptTemplate);
  EXPECT_EQ("success", set_result);
}

// Programmatically (from the extension) sets the action of |extension| to be
// enabled on the tab with the given |tab_id|.
//
// In Manifest V3, the chrome.pageAction and chrome.browserAction APIs are
// unified into chrome.action. This method simulates the old 'pageAction'
// behavior of a button becoming clickable/colored on a specific tab, which
// is achieved by calling chrome.action.enable(tabId).
void SetActionEnabledOnTab(Profile* profile,
                           const Extension& extension,
                           int tab_id) {
  ExtensionActionManager* action_manager = ExtensionActionManager::Get(profile);
  const ExtensionAction* extension_action =
      action_manager->GetExtensionAction(extension);
  ASSERT_TRUE(extension_action);

  // In MV3, the old concept of 'visibility' is replaced by 'enabled state'.
  // This initial check verifies the action is currently disabled (grayed out).
  EXPECT_FALSE(extension_action->GetIsVisible(tab_id));

  const ActionInfo* action_info =
      ActionInfo::GetExtensionActionInfo(&extension);
  ASSERT_TRUE(action_info);

  std::string script;
  if (action_info->type == ActionInfo::Type::kPage) {
    script = base::StringPrintf(
        R"(chrome.pageAction.show(%d, () => {
           chrome.test.sendScriptResult(
               chrome.runtime.lastError ?
                   chrome.runtime.lastError.message :
                   'success');
         });)",
        tab_id);
  } else {
    script = base::StringPrintf(
        R"(chrome.action.enable(%d, () => {
                 chrome.test.sendScriptResult(
                     chrome.runtime.lastError ?
                         chrome.runtime.lastError.message :
                         'success');
               });)",
        tab_id);
  }

  base::Value set_result = browsertest_util::ExecuteScriptInBackgroundPage(
      profile, extension.id(), script);

  EXPECT_EQ("success", set_result);

  // After enabling, the internal state (GetIsVisible) should reflect that
  // the action is now active (clickable/colored) for the specified tab.
  EXPECT_TRUE(extension_action->GetIsVisible(tab_id));
}

// Sends a keypress with the given |keyboard_code| to the specified |extension|.
// If |expect_dispatch| is true, expects pageAction.onClicked to be dispatched
// to the extension. Otherwise, expects it is not sent.
void SendKeyPressToAction(Browser* browser,
                          const Extension& extension,
                          ui::KeyboardCode keyboard_code,
                          const char* event_name,
                          bool expect_dispatch) {
  ExtensionTestMessageListener click_listener("clicked");
  click_listener.set_extension_id(extension.id());

  Profile* profile = browser->profile();
  EventRouter* event_router = EventRouter::Get(profile);
  TestEventRouterObserver event_tracker(event_router);
  // Activate the shortcut (Alt+Shift+F).
  if (!ui_test_utils::SendKeyPressSync(browser, keyboard_code, false, true,
                                       true, false)) {
    ADD_FAILURE() << "Could not send key press!";
    return;
  }
  base::RunLoop().RunUntilIdle();
  // Check that the event was dispatched if and only if we expected it to be.
  EXPECT_EQ(expect_dispatch,
            base::Contains(event_tracker.dispatched_events(), event_name));

  // Do a round-trip to the extension renderer. This serves as a pseudo-
  // RunUntilIdle()-type of method for the extension renderer itself, since
  // test.sendMessage() is FIFO.
  // This allows us to return the result of click_listener.was_satisfied(),
  // rather than using WaitUntilSatisfied(), which in turn allows this method
  // to exercise both the case of expecting dispatch and expecting *not* to
  // dispatch.
  static constexpr char kScript[] =
      R"(chrome.test.sendMessage(
             'run loop hack',
             () => {
               chrome.test.sendScriptResult('success');
             });)";
  base::Value set_result = browsertest_util::ExecuteScriptInBackgroundPage(
      profile, extension.id(), kScript);
  EXPECT_EQ("success", set_result);
  EXPECT_EQ(expect_dispatch, click_listener.was_satisfied());
}

// Given an |action_type|, returns the corresponding command key.
const char* GetCommandKeyForActionType(ActionInfo::Type action_type) {
  const char* command_key = nullptr;
  switch (action_type) {
    case ActionInfo::Type::kBrowser:
      command_key = manifest_values::kBrowserActionCommandEvent;
      break;
    case ActionInfo::Type::kPage:
      command_key = manifest_values::kPageActionCommandEvent;
      break;
    case ActionInfo::Type::kAction:
      command_key = manifest_values::kActionCommandEvent;
      break;
  }

  return command_key;
}

}  // namespace

class CommandsApiTest : public ExtensionApiTest {
 public:
  CommandsApiTest() = default;
  ~CommandsApiTest() override = default;

  void SetUpOnMainThread() override {
    ExtensionApiTest::SetUpOnMainThread();
#if BUILDFLAG(IS_MAC)
    // ExtensionKeybindingRegistryViews doesn't get registered until BrowserView
    // is activated at least once.
    // TODO(crbug.com/41386956): Registry creation should happen independent of
    // activation. Focus manager lifetime may make this tricky to untangle.
    // TODO(crbug.com/40486728): Reassess after activation is restored in the
    // focus manager.
    ui_test_utils::BrowserActivationWaiter waiter(browser());
    ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
    waiter.WaitForActivation();
    ASSERT_TRUE(browser()->window()->IsActive());
#endif
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionApiTest::SetUpCommandLine(command_line);
    // Some builders are flaky due to slower loading interacting with
    // deferred commits. This primarily impacts chromeos for the test
    // CommandsApiTest.ContinuePropagation.
    command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
  }

 protected:
  bool IsGrantedForTab(const Extension* extension,
                       const content::WebContents* web_contents) {
    return extension->permissions_data()->HasAPIPermissionForTab(
        sessions::SessionTabHelper::IdForTab(web_contents).id(),
        mojom::APIPermissionID::kTab);
  }

  // Returns true if the extension with the given |extension_id| has an active
  // command associated with an action of the given |action_type|.
  bool HasActiveActionCommand(const ExtensionId& extension_id,
                              ActionInfo::Type action_type) {
    bool active = false;
    Command command;
    CommandService* const command_service = CommandService::Get(profile());
    bool found_command = command_service->GetExtensionActionCommand(
        extension_id, action_type, CommandService::ALL, &command, &active);
    return found_command && active;
  }

  // Navigates to a test URL and return the ID of the navigated tab.
  int NavigateToTestURLAndReturnTabId() {
    EXPECT_TRUE(ui_test_utils::NavigateToURL(
        browser(),
        embedded_test_server()->GetURL("/extensions/test_file.txt")));
    return sessions::SessionTabHelper::FromWebContents(GetActiveWebContents())
        ->session_id()
        .id();
  }
};

class IncognitoCommandsApiTest : public CommandsApiTest,
                                 public testing::WithParamInterface<bool> {};

// A parameterized version to allow testing with different action types.
class ActionCommandsApiTest
    : public CommandsApiTest,
      public testing::WithParamInterface<ActionInfo::Type> {};

// Test the basic functionality of the Keybinding API:
// - That pressing the shortcut keys should perform actions (activate the
//   browser action or send an event).
// - Note: Page action keybindings are tested in PageAction test below.
// - The shortcut keys taken by one extension are not overwritten by the last
//   installed extension.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_;
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;

  // Load this extension, which uses the same keybindings but sets the page
  // to different colors. This is so we can see that it doesn't interfere. We
  // don't test this extension in any other way (it should otherwise be
  // immaterial to this test).
  ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_;

  // Test that there are two browser actions in the toolbar.
  ExtensionsToolbarContainer* extensions_container =
      browser()->GetBrowserView().toolbar()->extensions_container();
  ASSERT_EQ(2, extensions_container->GetNumberOfActionsForTesting());

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/extensions/test_file.txt")));

  // activeTab shouldn't have been granted yet.
  WebContents* tab = GetActiveWebContents();
  ASSERT_TRUE(tab);

  EXPECT_FALSE(IsGrantedForTab(extension, tab));

  ExtensionTestMessageListener test_listener;  // Won't reply.
  // Activate the browser action shortcut (Ctrl+Shift+F).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, true, false, false));
  EXPECT_TRUE(test_listener.WaitUntilSatisfied());
  // activeTab should now be granted.
  EXPECT_TRUE(IsGrantedForTab(extension, tab));
  // Verify the command worked.
  EXPECT_EQ(std::string("basics browser action"), test_listener.message());

  test_listener.Reset();
  // Activate the command shortcut (Ctrl+Shift+Y).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_Y, true, true, false, false));
  EXPECT_TRUE(test_listener.WaitUntilSatisfied());
  EXPECT_EQ(std::string(kBasicsShortcutCommandName), test_listener.message());
}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, InactivePageActionDoesntTrigger) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;

  const int tab_id = NavigateToTestURLAndReturnTabId();

  ExtensionActionManager* action_manager =
      ExtensionActionManager::Get(profile());
  const ExtensionAction* extension_action =
      action_manager->GetExtensionAction(*extension);
  ASSERT_TRUE(extension_action);

  // Explicitly disable the action globally to mimic the MV2 page_action's
  // initial hidden/disabled state.
  DisableActionGlobally(profile(), *extension);
  EXPECT_FALSE(extension_action->GetIsVisible(tab_id));

  // If the page action is disabled, the event shouldn't be dispatched.
  bool expect_dispatch = false;
  SendKeyPressToAction(browser(), *extension, ui::VKEY_F, "action.onClicked",
                       expect_dispatch);
}

// Tests that a page action that is unpinned and only shown within the
// extensions menu will still properly trigger when the keybinding is used.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, UnpinnedPageActionTriggers) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;

  // Explicitly disable the action globally to mimic the MV2 page_action's
  // initial hidden/disabled state.
  DisableActionGlobally(profile(), *extension);

  ExtensionsToolbarContainer* extensions_container =
      browser()->GetBrowserView().toolbar()->extensions_container();
  RunScheduledLayouts();
  EXPECT_FALSE(extensions_container->IsActionVisibleOnToolbar(extension->id()));

  const int tab_id = NavigateToTestURLAndReturnTabId();
  SetActionEnabledOnTab(profile(), *extension, tab_id);

  constexpr bool kExpectDispatch = true;
  SendKeyPressToAction(browser(), *extension, ui::VKEY_F, "action.onClicked",
                       kExpectDispatch);
}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, ActionOverrideChromeShortcut) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;

  // Explicitly disable the action globally to mimic the MV2 page_action's
  // initial hidden state.
  DisableActionGlobally(profile(), *extension);

  CommandService* command_service = CommandService::Get(profile());
// Simulate the user setting the keybinding to override the print shortcut.
#if BUILDFLAG(IS_MAC)
  std::string print_shortcut = "Command+P";
#else
  std::string print_shortcut = "Ctrl+P";
#endif
  command_service->UpdateKeybindingPrefs(
      extension->id(), manifest_values::kActionCommandEvent, print_shortcut);

  const int tab_id = NavigateToTestURLAndReturnTabId();

  SetActionEnabledOnTab(profile(), *extension, tab_id);

  ExtensionTestMessageListener test_listener;  // Won't reply.
  test_listener.set_extension_id(extension->id());

  // Note: The following incantation uses too many custom bits to comfortably
  // fit into SendKeyPressToAction(); do it manually.
  bool control_is_modifier = false;
  bool command_is_modifier = false;
#if BUILDFLAG(IS_MAC)
  command_is_modifier = true;
#else
  control_is_modifier = true;
#endif

  // Activate the omnibox. This checks to ensure that the extension shortcut
  // still works even if the WebContents isn't focused.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_L,
                                              control_is_modifier, false, false,
                                              command_is_modifier));

  // Activate the shortcut.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_P,
                                              control_is_modifier, false, false,
                                              command_is_modifier));

  EXPECT_TRUE(test_listener.WaitUntilSatisfied());
  EXPECT_EQ("clicked", test_listener.message());
}

// This test validates that an extension cannot request a shortcut that is
// already in use by Chrome.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) {
  ASSERT_TRUE(embedded_test_server()->Start());

  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  ASSERT_TRUE(RunExtensionTest("keybinding/dont_overwrite_system")) << message_;

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/extensions/test_file.txt")));

  // Activate the regular shortcut (Alt+Shift+F).
  ExtensionTestMessageListener alt_shift_f_listener("alt_shift_f");
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, false, true, true, false));
  EXPECT_TRUE(alt_shift_f_listener.WaitUntilSatisfied());

  // Try to activate the Ctrl+F shortcut (shouldn't work).
  // Since keypresses are sent synchronously, we can check this by first sending
  // Ctrl+F (which shouldn't work), followed by Alt+Shift+F (which should work),
  // and listening for both. If, by the time we receive the Alt+Shift+F
  // response, we haven't received a response for Ctrl+F, it is safe to say we
  // won't receive one.
  ExtensionTestMessageListener ctrl_f_listener("ctrl_f");
  alt_shift_f_listener.Reset();
  // Send Ctrl+F.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_F, true,
                                              false, false, false));
  // Send Alt+Shift+F.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_F, false,
                                              true, true, false));
  EXPECT_TRUE(alt_shift_f_listener.WaitUntilSatisfied());
  EXPECT_FALSE(ctrl_f_listener.was_satisfied());
}

// This test validates that user-set override of the Chrome bookmark shortcut in
// an extension that does not request it does supersede the same keybinding by
// web pages.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,
                       OverwriteBookmarkShortcutByUserOverridesWebKeybinding) {
  ASSERT_TRUE(embedded_test_server()->Start());

  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_;

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

  const Extension* extension = GetSingleLoadedExtension();
  // Simulate the user setting the keybinding to Ctrl+D.
  command_service->UpdateKeybindingPrefs(extension->id(),
                                         manifest_values::kActionCommandEvent,
                                         kBookmarkKeybinding);

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(
                     "/extensions/test_file_with_ctrl-d_keybinding.html")));

  ExtensionTestMessageListener test_listener;
  // Activate the shortcut (Ctrl+D) which should be handled by the extension.
  ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
  EXPECT_TRUE(test_listener.WaitUntilSatisfied());
  EXPECT_EQ(std::string("basics browser action"), test_listener.message());
}

#if BUILDFLAG(IS_WIN)
// Currently this feature is implemented on Windows only.
#define MAYBE_AllowDuplicatedMediaKeys AllowDuplicatedMediaKeys
#else
#define MAYBE_AllowDuplicatedMediaKeys DISABLED_AllowDuplicatedMediaKeys
#endif

// Test that media keys go to all extensions that register for them.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_AllowDuplicatedMediaKeys) {
  ResultCatcher catcher;
  ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_0"))
      << message_;
  ASSERT_TRUE(catcher.GetNextResult());
  ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_1"))
      << message_;
  ASSERT_TRUE(catcher.GetNextResult());

  // Activate the Media Stop key.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_MEDIA_STOP, false, false, false, false));

  // We should get two success result.
  ASSERT_TRUE(catcher.GetNextResult());
  ASSERT_TRUE(catcher.GetNextResult());
}

#if BUILDFLAG(IS_CHROMEOS) && !defined(NDEBUG)
// TODO(dtseng): Test times out on Chrome OS debug. See http://crbug.com/412456.
#define MAYBE_ContinuePropagation DISABLED_ContinuePropagation
#else
#define MAYBE_ContinuePropagation ContinuePropagation
#endif

IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_ContinuePropagation) {
  // Setup the environment.
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(RunExtensionTest("keybinding/continue_propagation")) << message_;
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/extensions/test_file.txt")));

  ResultCatcher catcher;

  // Activate the shortcut (Ctrl+Shift+F). The page should capture the
  // keystroke and not the extension since |onCommand| has no event listener
  // initially.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, true, false, false));
  ASSERT_TRUE(catcher.GetNextResult());

  // Now, the extension should have added an |onCommand| event listener.
  // Send the same key, but the |onCommand| listener should now receive it.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, true, false, false));
  ASSERT_TRUE(catcher.GetNextResult());

  // The extension should now have removed its |onCommand| event listener.
  // Finally, the page should again receive the key.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, true, false, false));
  ASSERT_TRUE(catcher.GetNextResult());
}

// Test is only applicable on Chrome OS.
#if BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(CommandsApiTest, ChromeOSConversions) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(RunExtensionTest("keybinding/chromeos_conversions")) << message_;
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/extensions/test_file.txt")));

  ResultCatcher catcher;

  // Send all expected keys (Search+Shift+{Left, Up, Right, Down}).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_LEFT, false,
                                              true, false, true));
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_UP, false,
                                              true, false, true));
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_RIGHT, false,
                                              true, false, true));
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_DOWN, false,
                                              true, false, true));

  ASSERT_TRUE(catcher.GetNextResult());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

// Validate parameters sent along with an extension event, in response to
// command being triggered.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, TabParameter) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/tab_parameter")) << message_;
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/extensions/test_file.txt")));
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;
  ResultCatcher catcher;
  EXPECT_TRUE(content::WaitForLoadStop(GetActiveWebContents()));
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_Y, true, true,
                                              false, false));  // Ctrl+Shift+Y
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}

// Test Keybinding in incognito mode.
IN_PROC_BROWSER_TEST_P(IncognitoCommandsApiTest, IncognitoMode) {
  ASSERT_TRUE(embedded_test_server()->Start());

  bool is_incognito_enabled = GetParam();

  ASSERT_TRUE(RunExtensionTest("keybinding/basics", {},
                               {.allow_in_incognito = is_incognito_enabled}))
      << message_;

  // Open incognito window and navigate to test page.
  Browser* incognito_browser = OpenURLOffTheRecord(
      profile(), embedded_test_server()->GetURL("/extensions/test_file.html"));

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      incognito_browser,
      embedded_test_server()->GetURL("/extensions/test_file.txt")));

  TestEventRouterObserver test_observer(
      EventRouter::Get(incognito_browser->profile()));

  // Activate the browser action shortcut (Ctrl+Shift+F).
  ExtensionTestMessageListener action_listener("basics browser action");
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(incognito_browser, ui::VKEY_F,
                                              true, true, false, false));
  if (is_incognito_enabled) {
    EXPECT_TRUE(action_listener.WaitUntilSatisfied());
  } else {
    base::RunLoop().RunUntilIdle();
  }
  EXPECT_EQ(
      is_incognito_enabled,
      base::Contains(test_observer.dispatched_events(), "action.onClicked"));

  test_observer.ClearEvents();

  // Activate the command shortcut (Ctrl+Shift+Y).
  ExtensionTestMessageListener command_listener("toggle-feature");
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(incognito_browser, ui::VKEY_Y,
                                              true, true, false, false));
  if (is_incognito_enabled) {
    EXPECT_TRUE(action_listener.WaitUntilSatisfied());
  } else {
    base::RunLoop().RunUntilIdle();
  }
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(
      is_incognito_enabled,
      base::Contains(test_observer.dispatched_events(), "commands.onCommand"));
}

IN_PROC_BROWSER_TEST_P(ActionCommandsApiTest,
                       TriggeringCommandTriggersListener) {
  ASSERT_TRUE(embedded_test_server()->Start());

  const ActionInfo::Type action_type = GetParam();

  // Load a test extension that has a command that invokes the action, and sends
  // a message when the action is invoked.
  constexpr char kManifestTemplate[] = R"(
    {
      "name": "Extension Action Listener Test",
      "manifest_version": %d,
      "version": "0.1",
      "commands": {
        "%s": {
          "suggested_key": {
            "default": "Alt+Shift+U"
          }
        }
      },
      "%s": {},
      "background": { %s }
    }
  )";
  constexpr char kBackgroundScriptTemplate[] = R"(
      chrome.%s.onClicked.addListener(() => {
        chrome.test.sendMessage('clicked');
      });
      chrome.test.sendMessage('ready');
  )";
  const char* background_specification =
      action_type == ActionInfo::Type::kAction
          ? R"("service_worker": "background.js")"
          : R"("scripts": ["background.js"])";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(base::StringPrintf(
      kManifestTemplate, GetManifestVersionForActionType(action_type),
      GetCommandKeyForActionType(action_type),
      ActionInfo::GetManifestKeyForActionType(action_type),
      background_specification));
  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
                     base::StringPrintf(kBackgroundScriptTemplate,
                                        GetAPINameForActionType(action_type)));

  ExtensionTestMessageListener listener("ready");
  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);
  ASSERT_TRUE(listener.WaitUntilSatisfied());
  ASSERT_TRUE(HasActiveActionCommand(extension->id(), action_type));

  const int tab_id = NavigateToTestURLAndReturnTabId();

  // If the action is a page action, it's disabled by default. Show it.
  // NOTE: This block only runs for MV2 kPage and kBrowser types, or if you
  // explicitly use chrome.action.disable() for MV3 kAction type.
  if (action_type == ActionInfo::Type::kPage) {
    SetActionEnabledOnTab(profile(), *extension, tab_id);
    ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
  }

  ExtensionTestMessageListener click_listener("clicked");
  // Execute a trivial command in the service worker to ensure it's alive right
  // before sending the key press. This is critical for MV3 tests. This step is
  // only required for the MV3 'kAction' parameter.
  if (action_type == ActionInfo::Type::kAction) {
    base::Value result = browsertest_util::ExecuteScriptInBackgroundPage(
        profile(), extension->id(),
        "chrome.runtime.getPlatformInfo(() => "
        "chrome.test.sendScriptResult('success'));");
    EXPECT_EQ("success", result);
  }

  // Send the key press to trigger the command.
  EXPECT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_U, false,
                                              true, true, false));

  // The listener should now successfully receive the 'clicked' message.
  EXPECT_TRUE(click_listener.WaitUntilSatisfied());
}

// Tests that triggering a command associated with an action opens an
// extension's popup.
IN_PROC_BROWSER_TEST_P(ActionCommandsApiTest, TriggeringCommandTriggersPopup) {
  ASSERT_TRUE(embedded_test_server()->Start());

  const ActionInfo::Type action_type = GetParam();

  // Load an extension that specifies a command to invoke the action, and has
  // a default popup.
  constexpr char kManifestTemplate[] = R"(
    {
      "name": "Extension Action Listener Test",
      "manifest_version": %d,
      "version": "0.1",
      "commands": {
        "%s": {
          "suggested_key": {
            "default": "Alt+Shift+U"
          }
        }
      },
      "%s": {"default_popup": "popup.html"}
    }
  )";
  constexpr char kPopupHtml[] = R"(
      <!doctype html>
      <html>
        <script src="popup.js"></script>
      </html>
  )";
  constexpr char kPopupJs[] = "chrome.test.notifyPass();";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(base::StringPrintf(
      kManifestTemplate, GetManifestVersionForActionType(action_type),
      GetCommandKeyForActionType(action_type),
      ActionInfo::GetManifestKeyForActionType(action_type)));
  test_dir.WriteFile(FILE_PATH_LITERAL("popup.html"), kPopupHtml);
  test_dir.WriteFile(FILE_PATH_LITERAL("popup.js"), kPopupJs);

  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);
  ASSERT_TRUE(HasActiveActionCommand(extension->id(), action_type));

  const int tab_id = NavigateToTestURLAndReturnTabId();

  if (action_type == ActionInfo::Type::kPage) {
    // Note: We don't use SetActionEnabledOnTab() here because it relies on a
    // background page, which this extension doesn't have.
    ExtensionActionManager::Get(profile())
        ->GetExtensionAction(*extension)
        ->SetIsVisible(tab_id, true);
    ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
  }

  // Invoke the action, and wait for the popup to show.
  ResultCatcher catcher;
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_U, false,
                                              true, true, false));
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();

  // Verify popup is shown.
  ExtensionsToolbarContainer* extensions_container =
      browser()->GetBrowserView().toolbar()->extensions_container();
  ToolbarActionViewController* popup_owner =
      extensions_container->popup_owner_for_testing();
  EXPECT_TRUE(popup_owner);
  EXPECT_TRUE(popup_owner->GetPopupNativeView());
}

INSTANTIATE_TEST_SUITE_P(All,
                         ActionCommandsApiTest,
                         testing::Values(ActionInfo::Type::kBrowser,
                                         ActionInfo::Type::kPage,
                                         ActionInfo::Type::kAction));

INSTANTIATE_TEST_SUITE_P(All, IncognitoCommandsApiTest, testing::Bool());

}  // namespace extensions
