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 <libudev.h> | 5 #include <libudev.h> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "base/threading/thread_restrictions.h" | 11 #include "base/threading/thread_restrictions.h" |
12 #include "device/hid/input_service_linux.h" | 12 #include "device/hid/input_service_linux.h" |
13 | 13 |
14 namespace device { | 14 namespace device { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 const char kHidSubsystem[] = "hid"; | 18 const char kSubsystemHid[] = "hid"; |
19 const char kInputSubsystem[] = "input"; | 19 const char kSubsystemInput[] = "input"; |
| 20 const char kTypeBluetooth[] = "bluetooth"; |
| 21 const char kTypeUsb[] = "usb"; |
| 22 const char kTypeSerio[] = "serio"; |
20 const char kIdInputAccelerometer[] = "ID_INPUT_ACCELEROMETER"; | 23 const char kIdInputAccelerometer[] = "ID_INPUT_ACCELEROMETER"; |
21 const char kIdInputJoystick[] = "ID_INPUT_JOYSTICK"; | 24 const char kIdInputJoystick[] = "ID_INPUT_JOYSTICK"; |
22 const char kIdInputKey[] = "ID_INPUT_KEY"; | 25 const char kIdInputKey[] = "ID_INPUT_KEY"; |
23 const char kIdInputKeyboard[] = "ID_INPUT_KEYBOARD"; | 26 const char kIdInputKeyboard[] = "ID_INPUT_KEYBOARD"; |
24 const char kIdInputMouse[] = "ID_INPUT_MOUSE"; | 27 const char kIdInputMouse[] = "ID_INPUT_MOUSE"; |
25 const char kIdInputTablet[] = "ID_INPUT_TABLET"; | 28 const char kIdInputTablet[] = "ID_INPUT_TABLET"; |
26 const char kIdInputTouchpad[] = "ID_INPUT_TOUCHPAD"; | 29 const char kIdInputTouchpad[] = "ID_INPUT_TOUCHPAD"; |
27 const char kIdInputTouchscreen[] = "ID_INPUT_TOUCHSCREEN"; | 30 const char kIdInputTouchscreen[] = "ID_INPUT_TOUCHSCREEN"; |
28 | 31 |
29 // The instance will be reset when message loop destroys. | 32 // The instance will be reset when message loop destroys. |
30 base::LazyInstance<scoped_ptr<InputServiceLinux> >::Leaky | 33 base::LazyInstance<scoped_ptr<InputServiceLinux> >::Leaky |
31 g_input_service_linux_ptr = LAZY_INSTANCE_INITIALIZER; | 34 g_input_service_linux_ptr = LAZY_INSTANCE_INITIALIZER; |
32 | 35 |
33 bool GetBoolProperty(udev_device* device, const char* key) { | 36 bool GetBoolProperty(udev_device* device, const char* key) { |
34 CHECK(device); | 37 CHECK(device); |
35 CHECK(key); | 38 CHECK(key); |
36 const char* property = udev_device_get_property_value(device, key); | 39 const char* property = udev_device_get_property_value(device, key); |
37 if (!property) | 40 if (!property) |
38 return false; | 41 return false; |
39 int value; | 42 int value; |
40 if (!base::StringToInt(property, &value)) { | 43 if (!base::StringToInt(property, &value)) { |
41 LOG(ERROR) << "Not an integer value for " << key << " property"; | 44 LOG(ERROR) << "Not an integer value for " << key << " property"; |
42 return false; | 45 return false; |
43 } | 46 } |
44 return (value != 0); | 47 return (value != 0); |
45 } | 48 } |
46 | 49 |
| 50 InputServiceLinux::InputDeviceInfo::Type GetDeviceType(udev_device* device) { |
| 51 if (udev_device_get_parent_with_subsystem_devtype( |
| 52 device, kTypeBluetooth, NULL)) { |
| 53 return InputServiceLinux::InputDeviceInfo::TYPE_BLUETOOTH; |
| 54 } |
| 55 if (udev_device_get_parent_with_subsystem_devtype(device, kTypeUsb, NULL)) |
| 56 return InputServiceLinux::InputDeviceInfo::TYPE_USB; |
| 57 if (udev_device_get_parent_with_subsystem_devtype(device, kTypeSerio, NULL)) |
| 58 return InputServiceLinux::InputDeviceInfo::TYPE_SERIO; |
| 59 return InputServiceLinux::InputDeviceInfo::TYPE_UNKNOWN; |
| 60 } |
| 61 |
47 class InputServiceLinuxImpl : public InputServiceLinux, | 62 class InputServiceLinuxImpl : public InputServiceLinux, |
48 public DeviceMonitorLinux::Observer { | 63 public DeviceMonitorLinux::Observer { |
49 public: | 64 public: |
50 // Implements DeviceMonitorLinux::Observer: | 65 // Implements DeviceMonitorLinux::Observer: |
51 virtual void OnDeviceAdded(udev_device* device) OVERRIDE; | 66 virtual void OnDeviceAdded(udev_device* device) OVERRIDE; |
52 virtual void OnDeviceRemoved(udev_device* device) OVERRIDE; | 67 virtual void OnDeviceRemoved(udev_device* device) OVERRIDE; |
53 | 68 |
54 private: | 69 private: |
55 friend class InputServiceLinux; | 70 friend class InputServiceLinux; |
56 | 71 |
(...skipping 25 matching lines...) Expand all Loading... |
82 InputDeviceInfo info; | 97 InputDeviceInfo info; |
83 info.id = path; | 98 info.id = path; |
84 | 99 |
85 const char* name = udev_device_get_property_value(device, "NAME"); | 100 const char* name = udev_device_get_property_value(device, "NAME"); |
86 if (name) | 101 if (name) |
87 info.name = name; | 102 info.name = name; |
88 | 103 |
89 const char* subsystem = udev_device_get_subsystem(device); | 104 const char* subsystem = udev_device_get_subsystem(device); |
90 if (!subsystem) | 105 if (!subsystem) |
91 return; | 106 return; |
92 else if (strcmp(subsystem, kHidSubsystem) == 0) | 107 else if (strcmp(subsystem, kSubsystemHid) == 0) |
93 info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_HID; | 108 info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_HID; |
94 else if (strcmp(subsystem, kInputSubsystem) == 0) | 109 else if (strcmp(subsystem, kSubsystemInput) == 0) |
95 info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; | 110 info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; |
96 else | 111 else |
97 return; | 112 return; |
98 | 113 |
| 114 info.type = GetDeviceType(device); |
| 115 |
99 info.is_accelerometer = GetBoolProperty(device, kIdInputAccelerometer); | 116 info.is_accelerometer = GetBoolProperty(device, kIdInputAccelerometer); |
100 info.is_joystick = GetBoolProperty(device, kIdInputJoystick); | 117 info.is_joystick = GetBoolProperty(device, kIdInputJoystick); |
101 info.is_key = GetBoolProperty(device, kIdInputKey); | 118 info.is_key = GetBoolProperty(device, kIdInputKey); |
102 info.is_keyboard = GetBoolProperty(device, kIdInputKeyboard); | 119 info.is_keyboard = GetBoolProperty(device, kIdInputKeyboard); |
103 info.is_mouse = GetBoolProperty(device, kIdInputMouse); | 120 info.is_mouse = GetBoolProperty(device, kIdInputMouse); |
104 info.is_tablet = GetBoolProperty(device, kIdInputTablet); | 121 info.is_tablet = GetBoolProperty(device, kIdInputTablet); |
105 info.is_touchpad = GetBoolProperty(device, kIdInputTouchpad); | 122 info.is_touchpad = GetBoolProperty(device, kIdInputTouchpad); |
106 info.is_touchscreen = GetBoolProperty(device, kIdInputTouchscreen); | 123 info.is_touchscreen = GetBoolProperty(device, kIdInputTouchscreen); |
107 | 124 |
108 AddDevice(info); | 125 AddDevice(info); |
109 } | 126 } |
110 | 127 |
111 void InputServiceLinuxImpl::OnDeviceRemoved(udev_device* device) { | 128 void InputServiceLinuxImpl::OnDeviceRemoved(udev_device* device) { |
112 DCHECK(CalledOnValidThread()); | 129 DCHECK(CalledOnValidThread()); |
113 if (!device) | 130 if (!device) |
114 return; | 131 return; |
115 const char* path = udev_device_get_syspath(device); | 132 const char* path = udev_device_get_syspath(device); |
116 if (!path) | 133 if (!path) |
117 return; | 134 return; |
118 RemoveDevice(path); | 135 RemoveDevice(path); |
119 } | 136 } |
120 | 137 |
121 } // namespace | 138 } // namespace |
122 | 139 |
123 InputServiceLinux::InputDeviceInfo::InputDeviceInfo() | 140 InputServiceLinux::InputDeviceInfo::InputDeviceInfo() |
124 : subsystem(SUBSYSTEM_UNKNOWN), | 141 : subsystem(SUBSYSTEM_UNKNOWN), |
| 142 type(TYPE_UNKNOWN), |
125 is_accelerometer(false), | 143 is_accelerometer(false), |
126 is_joystick(false), | 144 is_joystick(false), |
127 is_key(false), | 145 is_key(false), |
128 is_keyboard(false), | 146 is_keyboard(false), |
129 is_mouse(false), | 147 is_mouse(false), |
130 is_tablet(false), | 148 is_tablet(false), |
131 is_touchpad(false), | 149 is_touchpad(false), |
132 is_touchscreen(false) {} | 150 is_touchscreen(false) {} |
133 | 151 |
134 InputServiceLinux::InputServiceLinux() { | 152 InputServiceLinux::InputServiceLinux() { |
135 base::ThreadRestrictions::AssertIOAllowed(); | 153 base::ThreadRestrictions::AssertIOAllowed(); |
136 base::MessageLoop::current()->AddDestructionObserver(this); | 154 base::MessageLoop::current()->AddDestructionObserver(this); |
137 } | 155 } |
138 | 156 |
139 InputServiceLinux::~InputServiceLinux() { | 157 InputServiceLinux::~InputServiceLinux() { |
140 DCHECK(CalledOnValidThread()); | 158 DCHECK(CalledOnValidThread()); |
141 base::MessageLoop::current()->RemoveDestructionObserver(this); | 159 base::MessageLoop::current()->RemoveDestructionObserver(this); |
142 } | 160 } |
143 | 161 |
144 // static | 162 // static |
145 InputServiceLinux* InputServiceLinux::GetInstance() { | 163 InputServiceLinux* InputServiceLinux::GetInstance() { |
146 if (!HasInstance()) | 164 if (!HasInstance()) |
147 g_input_service_linux_ptr.Get().reset(new InputServiceLinux()); | 165 g_input_service_linux_ptr.Get().reset(new InputServiceLinuxImpl()); |
148 return g_input_service_linux_ptr.Get().get(); | 166 return g_input_service_linux_ptr.Get().get(); |
149 } | 167 } |
150 | 168 |
151 // static | 169 // static |
152 bool InputServiceLinux::HasInstance() { | 170 bool InputServiceLinux::HasInstance() { |
153 return g_input_service_linux_ptr.Get().get(); | 171 return g_input_service_linux_ptr.Get().get(); |
154 } | 172 } |
155 | 173 |
156 // static | 174 // static |
157 void InputServiceLinux::SetForTesting(InputServiceLinux* service) { | 175 void InputServiceLinux::SetForTesting(InputServiceLinux* service) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 void InputServiceLinux::RemoveDevice(const std::string& id) { | 219 void InputServiceLinux::RemoveDevice(const std::string& id) { |
202 devices_.erase(id); | 220 devices_.erase(id); |
203 FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceRemoved(id)); | 221 FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceRemoved(id)); |
204 } | 222 } |
205 | 223 |
206 bool InputServiceLinux::CalledOnValidThread() const { | 224 bool InputServiceLinux::CalledOnValidThread() const { |
207 return thread_checker_.CalledOnValidThread(); | 225 return thread_checker_.CalledOnValidThread(); |
208 } | 226 } |
209 | 227 |
210 } // namespace device | 228 } // namespace device |
OLD | NEW |