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