OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/hid/input_service_linux.h" | 5 #include "device/hid/input_service_linux.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | |
11 #include "base/logging.h" | 10 #include "base/logging.h" |
12 #include "base/macros.h" | 11 #include "base/macros.h" |
13 #include "base/scoped_observer.h" | 12 #include "base/scoped_observer.h" |
14 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
16 #include "base/threading/thread_restrictions.h" | 15 #include "base/threading/thread_restrictions.h" |
17 #include "device/base/device_monitor_linux.h" | 16 #include "device/base/device_monitor_linux.h" |
18 #include "device/udev_linux/udev.h" | 17 #include "device/udev_linux/udev.h" |
19 | 18 |
20 namespace device { | 19 namespace device { |
21 | 20 |
22 namespace { | 21 namespace { |
23 | 22 |
24 const char kSubsystemHid[] = "hid"; | 23 const char kSubsystemHid[] = "hid"; |
25 const char kSubsystemInput[] = "input"; | 24 const char kSubsystemInput[] = "input"; |
26 const char kSubsystemMisc[] = "misc"; | 25 const char kSubsystemMisc[] = "misc"; |
27 const char kTypeBluetooth[] = "bluetooth"; | 26 const char kTypeBluetooth[] = "bluetooth"; |
28 const char kTypeUsb[] = "usb"; | 27 const char kTypeUsb[] = "usb"; |
29 const char kTypeSerio[] = "serio"; | 28 const char kTypeSerio[] = "serio"; |
30 const char kIdInputAccelerometer[] = "ID_INPUT_ACCELEROMETER"; | 29 const char kIdInputAccelerometer[] = "ID_INPUT_ACCELEROMETER"; |
31 const char kIdInputJoystick[] = "ID_INPUT_JOYSTICK"; | 30 const char kIdInputJoystick[] = "ID_INPUT_JOYSTICK"; |
32 const char kIdInputKey[] = "ID_INPUT_KEY"; | 31 const char kIdInputKey[] = "ID_INPUT_KEY"; |
33 const char kIdInputKeyboard[] = "ID_INPUT_KEYBOARD"; | 32 const char kIdInputKeyboard[] = "ID_INPUT_KEYBOARD"; |
34 const char kIdInputMouse[] = "ID_INPUT_MOUSE"; | 33 const char kIdInputMouse[] = "ID_INPUT_MOUSE"; |
35 const char kIdInputTablet[] = "ID_INPUT_TABLET"; | 34 const char kIdInputTablet[] = "ID_INPUT_TABLET"; |
36 const char kIdInputTouchpad[] = "ID_INPUT_TOUCHPAD"; | 35 const char kIdInputTouchpad[] = "ID_INPUT_TOUCHPAD"; |
37 const char kIdInputTouchscreen[] = "ID_INPUT_TOUCHSCREEN"; | 36 const char kIdInputTouchscreen[] = "ID_INPUT_TOUCHSCREEN"; |
38 | 37 |
39 // The instance will be reset when message loop destroys. | 38 InputServiceLinux* g_input_service_linux = nullptr; |
40 base::LazyInstance<std::unique_ptr<InputServiceLinux>>::Leaky | |
41 g_input_service_linux_ptr = LAZY_INSTANCE_INITIALIZER; | |
42 | 39 |
43 bool GetBoolProperty(udev_device* device, const char* key) { | 40 bool GetBoolProperty(udev_device* device, const char* key) { |
44 CHECK(device); | 41 CHECK(device); |
45 CHECK(key); | 42 CHECK(key); |
46 const char* property = udev_device_get_property_value(device, key); | 43 const char* property = udev_device_get_property_value(device, key); |
47 if (!property) | 44 if (!property) |
48 return false; | 45 return false; |
49 int value; | 46 int value; |
50 if (!base::StringToInt(property, &value)) { | 47 if (!base::StringToInt(property, &value)) { |
51 LOG(ERROR) << "Not an integer value for " << key << " property"; | 48 LOG(ERROR) << "Not an integer value for " << key << " property"; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 base::TrimString(name, "\"", &result); | 81 base::TrimString(name, "\"", &result); |
85 return result; | 82 return result; |
86 } | 83 } |
87 | 84 |
88 class InputServiceLinuxImpl : public InputServiceLinux, | 85 class InputServiceLinuxImpl : public InputServiceLinux, |
89 public DeviceMonitorLinux::Observer { | 86 public DeviceMonitorLinux::Observer { |
90 public: | 87 public: |
91 // Implements DeviceMonitorLinux::Observer: | 88 // Implements DeviceMonitorLinux::Observer: |
92 void OnDeviceAdded(udev_device* device) override; | 89 void OnDeviceAdded(udev_device* device) override; |
93 void OnDeviceRemoved(udev_device* device) override; | 90 void OnDeviceRemoved(udev_device* device) override; |
94 void WillDestroyMonitorMessageLoop() override; | |
95 | 91 |
96 private: | 92 private: |
97 friend class InputServiceLinux; | 93 friend class InputServiceLinux; |
98 | 94 |
99 InputServiceLinuxImpl(); | 95 InputServiceLinuxImpl(); |
100 ~InputServiceLinuxImpl() override; | 96 ~InputServiceLinuxImpl() override; |
101 | 97 |
102 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_; | 98 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_; |
103 | 99 |
104 DISALLOW_COPY_AND_ASSIGN(InputServiceLinuxImpl); | 100 DISALLOW_COPY_AND_ASSIGN(InputServiceLinuxImpl); |
105 }; | 101 }; |
106 | 102 |
107 InputServiceLinuxImpl::InputServiceLinuxImpl() : observer_(this) { | 103 InputServiceLinuxImpl::InputServiceLinuxImpl() : observer_(this) { |
108 base::ThreadRestrictions::AssertIOAllowed(); | 104 base::ThreadRestrictions::AssertIOAllowed(); |
109 | 105 |
110 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); | 106 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); |
111 observer_.Add(monitor); | 107 observer_.Add(monitor); |
112 monitor->Enumerate(base::Bind(&InputServiceLinuxImpl::OnDeviceAdded, | 108 monitor->Enumerate(base::Bind(&InputServiceLinuxImpl::OnDeviceAdded, |
113 base::Unretained(this))); | 109 base::Unretained(this))); |
114 } | 110 } |
115 | 111 |
116 InputServiceLinuxImpl::~InputServiceLinuxImpl() { | 112 InputServiceLinuxImpl::~InputServiceLinuxImpl() { |
| 113 // Never destroyed. |
| 114 NOTREACHED(); |
117 } | 115 } |
118 | 116 |
119 void InputServiceLinuxImpl::OnDeviceAdded(udev_device* device) { | 117 void InputServiceLinuxImpl::OnDeviceAdded(udev_device* device) { |
120 DCHECK(CalledOnValidThread()); | 118 DCHECK(CalledOnValidThread()); |
121 if (!device) | 119 if (!device) |
122 return; | 120 return; |
123 const char* devnode = udev_device_get_devnode(device); | 121 const char* devnode = udev_device_get_devnode(device); |
124 if (!devnode) | 122 if (!devnode) |
125 return; | 123 return; |
126 | 124 |
(...skipping 29 matching lines...) Expand all Loading... |
156 | 154 |
157 void InputServiceLinuxImpl::OnDeviceRemoved(udev_device* device) { | 155 void InputServiceLinuxImpl::OnDeviceRemoved(udev_device* device) { |
158 DCHECK(CalledOnValidThread()); | 156 DCHECK(CalledOnValidThread()); |
159 if (!device) | 157 if (!device) |
160 return; | 158 return; |
161 const char* devnode = udev_device_get_devnode(device); | 159 const char* devnode = udev_device_get_devnode(device); |
162 if (devnode) | 160 if (devnode) |
163 RemoveDevice(devnode); | 161 RemoveDevice(devnode); |
164 } | 162 } |
165 | 163 |
166 void InputServiceLinuxImpl::WillDestroyMonitorMessageLoop() { | |
167 DCHECK(CalledOnValidThread()); | |
168 g_input_service_linux_ptr.Get().reset(nullptr); | |
169 } | |
170 | |
171 } // namespace | 164 } // namespace |
172 | 165 |
173 InputServiceLinux::InputDeviceInfo::InputDeviceInfo() | 166 InputServiceLinux::InputDeviceInfo::InputDeviceInfo() |
174 : subsystem(SUBSYSTEM_UNKNOWN), | 167 : subsystem(SUBSYSTEM_UNKNOWN), |
175 type(TYPE_UNKNOWN), | 168 type(TYPE_UNKNOWN), |
176 is_accelerometer(false), | 169 is_accelerometer(false), |
177 is_joystick(false), | 170 is_joystick(false), |
178 is_key(false), | 171 is_key(false), |
179 is_keyboard(false), | 172 is_keyboard(false), |
180 is_mouse(false), | 173 is_mouse(false), |
181 is_tablet(false), | 174 is_tablet(false), |
182 is_touchpad(false), | 175 is_touchpad(false), |
183 is_touchscreen(false) {} | 176 is_touchscreen(false) {} |
184 | 177 |
185 InputServiceLinux::InputDeviceInfo::InputDeviceInfo( | 178 InputServiceLinux::InputDeviceInfo::InputDeviceInfo( |
186 const InputDeviceInfo& other) = default; | 179 const InputDeviceInfo& other) = default; |
187 | 180 |
188 InputServiceLinux::InputServiceLinux() { | 181 InputServiceLinux::InputServiceLinux() { |
189 } | 182 } |
190 | 183 |
191 InputServiceLinux::~InputServiceLinux() { | 184 InputServiceLinux::~InputServiceLinux() { |
192 DCHECK(CalledOnValidThread()); | 185 DCHECK(CalledOnValidThread()); |
193 } | 186 } |
194 | 187 |
195 // static | 188 // static |
196 InputServiceLinux* InputServiceLinux::GetInstance() { | 189 InputServiceLinux* InputServiceLinux::GetInstance() { |
197 if (!HasInstance()) | 190 if (!HasInstance()) |
198 g_input_service_linux_ptr.Get().reset(new InputServiceLinuxImpl()); | 191 g_input_service_linux = new InputServiceLinuxImpl(); |
199 return g_input_service_linux_ptr.Get().get(); | 192 return g_input_service_linux; |
200 } | 193 } |
201 | 194 |
202 // static | 195 // static |
203 bool InputServiceLinux::HasInstance() { | 196 bool InputServiceLinux::HasInstance() { |
204 return g_input_service_linux_ptr.Get().get(); | 197 return !!g_input_service_linux; |
205 } | 198 } |
206 | 199 |
207 // static | 200 // static |
208 void InputServiceLinux::SetForTesting(InputServiceLinux* service) { | 201 void InputServiceLinux::SetForTesting( |
209 g_input_service_linux_ptr.Get().reset(service); | 202 std::unique_ptr<InputServiceLinux> service) { |
| 203 DCHECK(!HasInstance()); |
| 204 DCHECK(service); |
| 205 // |service| will never be destroyed. |
| 206 g_input_service_linux = service.release(); |
210 } | 207 } |
211 | 208 |
212 void InputServiceLinux::AddObserver(Observer* observer) { | 209 void InputServiceLinux::AddObserver(Observer* observer) { |
213 DCHECK(CalledOnValidThread()); | 210 DCHECK(CalledOnValidThread()); |
214 if (observer) | 211 if (observer) |
215 observers_.AddObserver(observer); | 212 observers_.AddObserver(observer); |
216 } | 213 } |
217 | 214 |
218 void InputServiceLinux::RemoveObserver(Observer* observer) { | 215 void InputServiceLinux::RemoveObserver(Observer* observer) { |
219 DCHECK(CalledOnValidThread()); | 216 DCHECK(CalledOnValidThread()); |
(...skipping 29 matching lines...) Expand all Loading... |
249 devices_.erase(id); | 246 devices_.erase(id); |
250 for (auto& observer : observers_) | 247 for (auto& observer : observers_) |
251 observer.OnInputDeviceRemoved(id); | 248 observer.OnInputDeviceRemoved(id); |
252 } | 249 } |
253 | 250 |
254 bool InputServiceLinux::CalledOnValidThread() const { | 251 bool InputServiceLinux::CalledOnValidThread() const { |
255 return thread_checker_.CalledOnValidThread(); | 252 return thread_checker_.CalledOnValidThread(); |
256 } | 253 } |
257 | 254 |
258 } // namespace device | 255 } // namespace device |
OLD | NEW |