chromium/ui/base/accelerators/accelerator_manager_unittest.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "ui/base/accelerators/accelerator_manager.h"

#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/test_accelerator_target.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/keyboard_codes.h"

namespace ui {
namespace test {
namespace {

Accelerator GetAccelerator(KeyboardCode code, int mask) {}

// Possible flags used for accelerators.
const int kAcceleratorModifiers[] =;

// Returns a set of flags from id, where id is a bitmask into
// kAcceleratorModifiers used to determine which flags are set.
int BuildAcceleratorModifier(int id) {}

class AcceleratorManagerTest : public testing::Test {};

TEST_F(AcceleratorManagerTest, Register) {}

TEST_F(AcceleratorManagerTest, RegisterMultipleTarget) {}

TEST_F(AcceleratorManagerTest, Unregister) {}

TEST_F(AcceleratorManagerTest, UnregisterAll) {}

TEST_F(AcceleratorManagerTest, Process) {}

#if BUILDFLAG(IS_CHROMEOS)

TEST_F(AcceleratorManagerTest, PositionalShortcuts_AllEqual) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      features::kImprovedKeyboardShortcuts);

  // Use a local instance so that the feature is enabled during construction.
  AcceleratorManager manager;
  manager.SetUsePositionalLookup(true);

  // Test what would be ctrl + ']' (VKEY_OEM_6) on a US keyboard. This
  // should match.
  TestAcceleratorTarget target;
  const Accelerator accelerator(VKEY_OEM_6, EF_CONTROL_DOWN);
  manager.Register({accelerator}, AcceleratorManager::kNormalPriority, &target);
  KeyEvent event(ui::EventType::kKeyPressed, VKEY_OEM_6,
                 ui::DomCode::BRACKET_RIGHT, ui::EF_CONTROL_DOWN,
                 ui::DomKey::FromCharacter(']'), base::TimeTicks());
  const Accelerator trigger(event);
  EXPECT_TRUE(manager.IsRegistered(trigger));
  EXPECT_TRUE(manager.Process(trigger));
}

TEST_F(AcceleratorManagerTest, PositionalShortcuts_MatchingDomCode) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      features::kImprovedKeyboardShortcuts);

  // Use a local instance so that the feature is enabled during construction.
  AcceleratorManager manager;
  manager.SetUsePositionalLookup(true);

  // Test what would be ctrl + ']' on a US keyboard with matching DomCode
  // and different VKEY (eg. '+'). This is the use case of a positional key
  // on the German keyboard. Since the DomCode matches, this should match.
  TestAcceleratorTarget target;
  const Accelerator accelerator(VKEY_OEM_6, EF_CONTROL_DOWN);
  manager.Register({accelerator}, AcceleratorManager::kNormalPriority, &target);
  KeyEvent event(ui::EventType::kKeyPressed, VKEY_OEM_PLUS,
                 ui::DomCode::BRACKET_RIGHT, ui::EF_CONTROL_DOWN,
                 ui::DomKey::FromCharacter(']'), base::TimeTicks());
  const Accelerator trigger(event);
  EXPECT_TRUE(manager.IsRegistered(trigger));
  EXPECT_TRUE(manager.Process(trigger));
}

TEST_F(AcceleratorManagerTest, PositionalShortcuts_NotMatchingDomCode) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      features::kImprovedKeyboardShortcuts);

  // Use a local instance so that the feature is enabled during construction.
  AcceleratorManager manager;
  manager.SetUsePositionalLookup(true);

  // Test what would be ctrl + ']' on a US keyboard using positional mapping
  // for a German layout. The accelerator is registered using the US VKEY and
  // triggered with a KeyEvent with the US VKEY but a mismatched DomCode. This
  // should not match. This prevents ghost shortcuts on non-US layouts.
  TestAcceleratorTarget target;
  const Accelerator accelerator(VKEY_OEM_6, EF_CONTROL_DOWN);
  manager.Register({accelerator}, AcceleratorManager::kNormalPriority, &target);
  KeyEvent event(ui::EventType::kKeyPressed, VKEY_OEM_6,
                 ui::DomCode::BRACKET_LEFT, ui::EF_CONTROL_DOWN,
                 ui::DomKey::FromCharacter(']'), base::TimeTicks());
  const Accelerator trigger(event);
  EXPECT_FALSE(manager.IsRegistered(trigger));
  EXPECT_FALSE(manager.Process(trigger));
}

TEST_F(AcceleratorManagerTest, PositionalShortcuts_NonPositionalMatch) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      features::kImprovedKeyboardShortcuts);

  // Use a local instance so that the feature is enabled during construction.
  AcceleratorManager manager;
  manager.SetUsePositionalLookup(true);

  // Test ctrl + 'Z' for the German layout. Since 'Z' is not a positional
  // key it should match based on the VKEY, regardless of the DomCode. In this
  // case the 'Z' has DomCode US_Y (ie. QWERTZ keyboard), but it should still
  // match.
  TestAcceleratorTarget target;
  const Accelerator accelerator(VKEY_Z, EF_CONTROL_DOWN);
  manager.Register({accelerator}, AcceleratorManager::kNormalPriority, &target);
  KeyEvent event(ui::EventType::kKeyPressed, VKEY_Z, ui::DomCode::US_Y,
                 ui::EF_CONTROL_DOWN, ui::DomKey::FromCharacter(']'),
                 base::TimeTicks());
  const Accelerator trigger(event);
  EXPECT_TRUE(manager.IsRegistered(trigger));
  EXPECT_TRUE(manager.Process(trigger));
}

TEST_F(AcceleratorManagerTest, PositionalShortcuts_NonPositionalNonMatch) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      features::kImprovedKeyboardShortcuts);

  // Use a local instance so that the feature is enabled during construction.
  AcceleratorManager manager;
  manager.SetUsePositionalLookup(true);

  // Test ctrl + 'Z' for the German layout. The 'Y' key (in the US_Z position),
  // should not match. Alphanumeric keys are not positional, and pressing the
  // key with DomCode::US_Z should not match when it's mapped to VKEY_Y.
  TestAcceleratorTarget target;
  const Accelerator accelerator(VKEY_Z, EF_CONTROL_DOWN);
  manager.Register({accelerator}, AcceleratorManager::kNormalPriority, &target);
  KeyEvent event(ui::EventType::kKeyPressed, VKEY_Y, ui::DomCode::US_Z,
                 ui::EF_CONTROL_DOWN, ui::DomKey::FromCharacter(']'),
                 base::TimeTicks());
  const Accelerator trigger(event);
  EXPECT_FALSE(manager.IsRegistered(trigger));
  EXPECT_FALSE(manager.Process(trigger));
}

#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace
}  // namespace test
}  // namespace ui