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 "base/bind.h" 6 #include "base/compiler_specific.h" 7 #include "base/macros.h" 8 #include "base/run_loop.h" 9 #include "chrome/browser/chromeos/device/input_service_proxy.h" 10 #include "chrome/test/base/in_process_browser_test.h" 11 #include "content/public/browser/browser_thread.h" 12 #include "device/hid/input_service_linux.h" 13 14 using content::BrowserThread; 15 using device::InputServiceLinux; 16 17 typedef InputServiceLinux::InputDeviceInfo InputDeviceInfo; 18 19 namespace chromeos { 20 21 namespace { 22 23 const char kKeyboardId[] = "keyboard"; 24 const char kMouseId[] = "mouse"; 25 26 class InputServiceLinuxTestImpl : public InputServiceLinux { 27 public: 28 InputServiceLinuxTestImpl() {} 29 virtual ~InputServiceLinuxTestImpl() {} 30 31 void AddDeviceForTesting(const InputDeviceInfo& info) { AddDevice(info); } 32 void RemoveDeviceForTesting(const std::string& id) { RemoveDevice(id); } 33 34 private: 35 DISALLOW_COPY_AND_ASSIGN(InputServiceLinuxTestImpl); 36 }; 37 38 class TestObserver : public InputServiceProxy::Observer { 39 public: 40 TestObserver() 41 : wait_for_device_addition_(false), wait_for_device_removal_(false) {} 42 virtual ~TestObserver() {} 43 44 virtual void OnInputDeviceAdded(const InputDeviceInfo& info) OVERRIDE { 45 if (!wait_for_device_addition_) 46 return; 47 EXPECT_TRUE(Equals(expected_info_, info)); 48 done_.Run(); 49 } 50 51 virtual void OnInputDeviceRemoved(const std::string& id) OVERRIDE { 52 if (!wait_for_device_removal_) 53 return; 54 EXPECT_EQ(expected_id_, id); 55 done_.Run(); 56 } 57 58 void WaitForDeviceAddition(const InputDeviceInfo& info) { 59 base::RunLoop run; 60 expected_info_ = info; 61 wait_for_device_addition_ = true; 62 done_ = run.QuitClosure(); 63 64 run.Run(); 65 66 done_.Reset(); 67 wait_for_device_addition_ = false; 68 } 69 70 void WaitForDeviceRemoval(const std::string& id) { 71 base::RunLoop run; 72 expected_id_ = id; 73 wait_for_device_removal_ = true; 74 done_ = run.QuitClosure(); 75 76 run.Run(); 77 78 done_.Reset(); 79 wait_for_device_removal_ = false; 80 } 81 82 private: 83 static bool Equals(const InputDeviceInfo& lhs, const InputDeviceInfo& rhs) { 84 return lhs.id == rhs.id && lhs.name == rhs.name && 85 lhs.subsystem == rhs.subsystem && 86 lhs.type == rhs.type && 87 lhs.is_accelerometer == rhs.is_accelerometer && 88 lhs.is_joystick == rhs.is_joystick && lhs.is_key == rhs.is_key && 89 lhs.is_keyboard == rhs.is_keyboard && lhs.is_mouse == rhs.is_mouse && 90 lhs.is_tablet == rhs.is_tablet && 91 lhs.is_touchpad == rhs.is_touchpad && 92 lhs.is_touchscreen == rhs.is_touchscreen; 93 } 94 95 InputDeviceInfo expected_info_; 96 std::string expected_id_; 97 98 bool wait_for_device_addition_; 99 bool wait_for_device_removal_; 100 101 base::Closure done_; 102 103 DISALLOW_COPY_AND_ASSIGN(TestObserver); 104 }; 105 106 void InitInputService() { 107 InputServiceLinux::SetForTesting(new InputServiceLinuxTestImpl()); 108 } 109 110 void AddDevice(const InputDeviceInfo& device) { 111 InputServiceLinuxTestImpl* service = 112 static_cast<InputServiceLinuxTestImpl*>(InputServiceLinux::GetInstance()); 113 service->AddDeviceForTesting(device); 114 } 115 116 void RemoveDevice(const std::string& id) { 117 InputServiceLinuxTestImpl* service = 118 static_cast<InputServiceLinuxTestImpl*>(InputServiceLinux::GetInstance()); 119 service->RemoveDeviceForTesting(id); 120 } 121 122 void OnGetDevices(const base::Closure& done, 123 const std::vector<InputDeviceInfo>& devices) { 124 EXPECT_EQ(2, static_cast<int>(devices.size())); 125 done.Run(); 126 } 127 128 void OnGetKeyboard(const base::Closure& done, 129 bool success, 130 const InputDeviceInfo& info) { 131 EXPECT_TRUE(success); 132 EXPECT_EQ("keyboard", info.id); 133 EXPECT_TRUE(info.is_keyboard); 134 done.Run(); 135 } 136 137 void OnGetMouse(const base::Closure& done, 138 bool success, 139 const InputDeviceInfo& /* info */) { 140 EXPECT_FALSE(success); 141 done.Run(); 142 } 143 144 } // namespace 145 146 class InputServiceProxyTest : public InProcessBrowserTest { 147 public: 148 InputServiceProxyTest() {} 149 virtual ~InputServiceProxyTest() {} 150 151 private: 152 DISALLOW_COPY_AND_ASSIGN(InputServiceProxyTest); 153 }; 154 155 IN_PROC_BROWSER_TEST_F(InputServiceProxyTest, Simple) { 156 BrowserThread::PostTask( 157 BrowserThread::FILE, FROM_HERE, base::Bind(&InitInputService)); 158 InputServiceProxy proxy; 159 TestObserver observer; 160 proxy.AddObserver(&observer); 161 162 InputDeviceInfo keyboard; 163 keyboard.id = kKeyboardId; 164 keyboard.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; 165 keyboard.type = InputServiceLinux::InputDeviceInfo::TYPE_USB; 166 keyboard.is_keyboard = true; 167 BrowserThread::PostTask( 168 BrowserThread::FILE, FROM_HERE, base::Bind(&AddDevice, keyboard)); 169 observer.WaitForDeviceAddition(keyboard); 170 171 InputDeviceInfo mouse; 172 mouse.id = kMouseId; 173 mouse.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; 174 mouse.type = InputServiceLinux::InputDeviceInfo::TYPE_BLUETOOTH; 175 mouse.is_mouse = true; 176 BrowserThread::PostTask( 177 BrowserThread::FILE, FROM_HERE, base::Bind(&AddDevice, mouse)); 178 observer.WaitForDeviceAddition(mouse); 179 180 { 181 base::RunLoop run; 182 proxy.GetDevices(base::Bind(&OnGetDevices, run.QuitClosure())); 183 run.Run(); 184 } 185 186 BrowserThread::PostTask( 187 BrowserThread::FILE, FROM_HERE, base::Bind(&RemoveDevice, kMouseId)); 188 observer.WaitForDeviceRemoval(kMouseId); 189 190 { 191 base::RunLoop run; 192 proxy.GetDeviceInfo(kKeyboardId, 193 base::Bind(&OnGetKeyboard, run.QuitClosure())); 194 run.Run(); 195 } 196 197 { 198 base::RunLoop run; 199 proxy.GetDeviceInfo(kMouseId, base::Bind(&OnGetMouse, run.QuitClosure())); 200 run.Run(); 201 } 202 203 proxy.RemoveObserver(&observer); 204 } 205 206 } // namespace chromeos 207