1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/events/devices/x11/device_data_manager_x11.h"
6 
7 #include <vector>
8 
9 #include "base/macros.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/events/devices/device_hotplug_event_observer.h"
12 #include "ui/events/devices/input_device.h"
13 #include "ui/events/devices/input_device_event_observer.h"
14 #include "ui/events/devices/touchscreen_device.h"
15 
16 namespace ui {
17 namespace test {
18 namespace {
19 
20 class TestInputDeviceObserver : public InputDeviceEventObserver {
21  public:
TestInputDeviceObserver(DeviceDataManagerX11 * manager)22   explicit TestInputDeviceObserver(DeviceDataManagerX11* manager)
23       : manager_(manager), change_notified_(false) {
24     if (manager_)
25       manager_->AddObserver(this);
26   }
27 
~TestInputDeviceObserver()28   ~TestInputDeviceObserver() override {
29     if (manager_)
30       manager_->RemoveObserver(this);
31   }
32 
33   // InputDeviceEventObserver implementation.
OnInputDeviceConfigurationChanged(uint8_t)34   void OnInputDeviceConfigurationChanged(uint8_t) override {
35     change_notified_ = true;
36   }
37 
change_notified() const38   int change_notified() const { return change_notified_; }
Reset()39   void Reset() { change_notified_ = false; }
40 
41  private:
42   DeviceDataManager* manager_;
43   bool change_notified_;
44 
45   DISALLOW_COPY_AND_ASSIGN(TestInputDeviceObserver);
46 };
47 
48 }  //  namespace
49 
50 class DeviceDataManagerX11Test : public testing::Test {
51  public:
52   DeviceDataManagerX11Test() = default;
53   ~DeviceDataManagerX11Test() override = default;
54 
SetUp()55   void SetUp() override { DeviceDataManagerX11::CreateInstance(); }
56 
TearDown()57   void TearDown() override { SetKeyboardDevices(std::vector<InputDevice>()); }
58 
SetKeyboardDevices(const std::vector<InputDevice> & devices)59   virtual void SetKeyboardDevices(const std::vector<InputDevice>& devices) {
60     DeviceHotplugEventObserver* manager = DeviceDataManagerX11::GetInstance();
61     manager->OnKeyboardDevicesUpdated(devices);
62   }
63 
64  private:
65   DISALLOW_COPY_AND_ASSIGN(DeviceDataManagerX11Test);
66 };
67 
68 // Tests that the the device data manager notifies observers when a device is
69 // disabled and re-enabled.
TEST_F(DeviceDataManagerX11Test,NotifyOnDisable)70 TEST_F(DeviceDataManagerX11Test, NotifyOnDisable) {
71   DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
72   TestInputDeviceObserver observer(manager);
73   std::vector<ui::InputDevice> keyboards;
74   keyboards.emplace_back(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
75                          "Keyboard");
76   keyboards.emplace_back(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
77                          "Keyboard");
78   SetKeyboardDevices(keyboards);
79   EXPECT_TRUE(observer.change_notified());
80   std::vector<InputDevice> devices = manager->GetKeyboardDevices();
81   EXPECT_EQ(keyboards.size(), devices.size());
82   observer.Reset();
83   // Disable the device, should be notified that the device list contains one
84   // less device.
85   manager->DisableDevice(static_cast<x11::Input::DeviceId>(2));
86   EXPECT_TRUE(observer.change_notified());
87   devices = manager->GetKeyboardDevices();
88   EXPECT_EQ(1u, devices.size());
89   InputDevice device = devices.front();
90   EXPECT_EQ(1, device.id);
91   observer.Reset();
92   // Reenable the device, should be notified that the device list contains one
93   // more device.
94   manager->EnableDevice(static_cast<x11::Input::DeviceId>(2));
95   EXPECT_TRUE(observer.change_notified());
96   devices = manager->GetKeyboardDevices();
97   EXPECT_EQ(keyboards.size(), devices.size());
98 }
99 
100 // Tests blocking multiple devices.
TEST_F(DeviceDataManagerX11Test,TestMultipleDisable)101 TEST_F(DeviceDataManagerX11Test, TestMultipleDisable) {
102   DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
103   TestInputDeviceObserver observer(manager);
104   std::vector<ui::InputDevice> keyboards;
105   keyboards.emplace_back(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
106                          "Keyboard");
107   keyboards.emplace_back(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
108                          "Keyboard");
109   SetKeyboardDevices(keyboards);
110   EXPECT_TRUE(observer.change_notified());
111   std::vector<InputDevice> devices = manager->GetKeyboardDevices();
112   EXPECT_EQ(keyboards.size(), devices.size());
113   observer.Reset();
114   // Disable the device, should be notified that the device list contains one
115   // less device.
116   manager->DisableDevice(static_cast<x11::Input::DeviceId>(1));
117   EXPECT_TRUE(observer.change_notified());
118   devices = manager->GetKeyboardDevices();
119   EXPECT_EQ(1u, devices.size());
120   observer.Reset();
121   // Disable the second device, should be notified that the device list empty.
122   manager->DisableDevice(static_cast<x11::Input::DeviceId>(2));
123   EXPECT_TRUE(observer.change_notified());
124   devices = manager->GetKeyboardDevices();
125   EXPECT_EQ(0u, devices.size());
126   observer.Reset();
127   // Enable the first device, should be notified that one device present.
128   manager->EnableDevice(static_cast<x11::Input::DeviceId>(1));
129   EXPECT_TRUE(observer.change_notified());
130   devices = manager->GetKeyboardDevices();
131   EXPECT_EQ(1u, devices.size());
132   observer.Reset();
133   // Enable the second device, should be notified that both devices present.
134   manager->EnableDevice(static_cast<x11::Input::DeviceId>(2));
135   EXPECT_TRUE(observer.change_notified());
136   devices = manager->GetKeyboardDevices();
137   EXPECT_EQ(2u, devices.size());
138 }
139 
TEST_F(DeviceDataManagerX11Test,UnblockOnDeviceUnplugged)140 TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) {
141   DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
142   TestInputDeviceObserver observer(manager);
143   std::vector<ui::InputDevice> all_keyboards;
144   all_keyboards.emplace_back(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
145                              "Keyboard");
146   all_keyboards.emplace_back(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
147                              "Keyboard");
148   SetKeyboardDevices(all_keyboards);
149   EXPECT_TRUE(observer.change_notified());
150   std::vector<InputDevice> devices = manager->GetKeyboardDevices();
151   EXPECT_EQ(all_keyboards.size(), devices.size());
152   observer.Reset();
153   // Expect to be notified that the device is no longer available.
154   manager->DisableDevice(static_cast<x11::Input::DeviceId>(2));
155   EXPECT_TRUE(observer.change_notified());
156   devices = manager->GetKeyboardDevices();
157   EXPECT_EQ(1u, devices.size());
158   observer.Reset();
159   // Unplug the disabled device. Should not be notified, since the active list
160   // did not change.
161   std::vector<ui::InputDevice> subset_keyboards;
162   subset_keyboards.emplace_back(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
163                                 "Keyboard");
164   SetKeyboardDevices(subset_keyboards);
165   EXPECT_FALSE(observer.change_notified());
166   // Replug in the first device. Should be notified of the new device.
167   SetKeyboardDevices(all_keyboards);
168   EXPECT_TRUE(observer.change_notified());
169   devices = manager->GetKeyboardDevices();
170   // Both devices now present.
171   EXPECT_EQ(2u, devices.size());
172 }
173 
174 }  // namespace test
175 }  // namespace ui
176