15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accelerators/accelerator_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_constants.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestTarget : public AcceleratorTarget { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget() : accelerator_pressed_count_(0) {} 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestTarget() {} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int accelerator_pressed_count() const { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return accelerator_pressed_count_; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_accelerator_pressed_count(int accelerator_pressed_count) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accelerator_pressed_count_ = accelerator_pressed_count; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overridden from AcceleratorTarget: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool AcceleratorPressed(const Accelerator& accelerator) OVERRIDE; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool CanHandleAccelerators() const OVERRIDE; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int accelerator_pressed_count_; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestTarget); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestTarget::AcceleratorPressed(const Accelerator& accelerator) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++accelerator_pressed_count_; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestTarget::CanHandleAccelerators() const { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Accelerator GetAccelerator(KeyboardCode code, int mask) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Accelerator(code, mask); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AcceleratorManagerTest : public testing::Test { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AcceleratorManagerTest() {} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AcceleratorManagerTest() {} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AcceleratorManager manager_; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorManagerTest, Register) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator accelerator_a(VKEY_A, EF_NONE); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget target; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The registered accelerator is processed. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manager_.Process(accelerator_a)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, target.accelerator_pressed_count()); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorManagerTest, RegisterMultipleTarget) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator accelerator_a(VKEY_A, EF_NONE); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget target1; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target1); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget target2; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target2); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If multiple targets are registered with the same accelerator, the target 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registered later processes the accelerator. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manager_.Process(accelerator_a)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, target1.accelerator_pressed_count()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, target2.accelerator_pressed_count()); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorManagerTest, Unregister) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator accelerator_a(VKEY_A, EF_NONE); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget target; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator accelerator_b(VKEY_B, EF_NONE); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_b, AcceleratorManager::kNormalPriority, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unregistering a different accelerator does not affect the other 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // accelerator. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Unregister(accelerator_b, &target); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manager_.Process(accelerator_a)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, target.accelerator_pressed_count()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The unregistered accelerator is no longer processed. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target.set_accelerator_pressed_count(0); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Unregister(accelerator_a, &target); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(accelerator_a)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, target.accelerator_pressed_count()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorManagerTest, UnregisterAll) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator accelerator_a(VKEY_A, EF_NONE); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget target1; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target1); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator accelerator_b(VKEY_B, EF_NONE); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_b, AcceleratorManager::kNormalPriority, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target1); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator accelerator_c(VKEY_C, EF_NONE); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget target2; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator_c, AcceleratorManager::kNormalPriority, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target2); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.UnregisterAll(&target1); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All the accelerators registered for |target1| are no longer processed. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(accelerator_a)); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(accelerator_b)); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, target1.accelerator_pressed_count()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UnregisterAll with a different target does not affect the other target. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manager_.Process(accelerator_c)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, target2.accelerator_pressed_count()); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorManagerTest, Process) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestTarget target; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test all 2*2*2 cases (shift/control/alt = on/off). 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int mask = 0; mask < 2 * 2 * 2; ++mask) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Accelerator accelerator(GetAccelerator(VKEY_A, mask)); 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::string16 text = accelerator.GetShortcutText(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.Register(accelerator, AcceleratorManager::kNormalPriority, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The registered accelerator is processed. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int last_count = target.accelerator_pressed_count(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(manager_.Process(accelerator)) << text; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << text; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The non-registered accelerators are not processed. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accelerator.set_type(ET_UNKNOWN); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accelerator.set_type(ET_TRANSLATED_KEY_PRESS); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accelerator.set_type(ET_KEY_RELEASED); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accelerator.set_type(ET_TRANSLATED_KEY_RELEASE); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_UNKNOWN, mask))) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << text; // different vkey 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_B, mask))) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << text; // different vkey 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_SHIFT, mask))) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << text; // different vkey 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int test_mask = 0; test_mask < 2 * 2 * 2; ++test_mask) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (test_mask == mask) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Accelerator test_accelerator(GetAccelerator(VKEY_A, test_mask)); 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::string16 test_text = test_accelerator.GetShortcutText(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(manager_.Process(test_accelerator)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << text << ", " << test_text; // different modifiers 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << text; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_.UnregisterAll(&target); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace test 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 184