Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: device/hid/hid_service_linux.cc

Issue 230503003: Udev-related methods are extracted from HidServiceLinux into individual service. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « device/hid/hid_service_linux.h ('k') | device/hid/udev_common.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/platform_file.h" 13 #include "base/platform_file.h"
13 #include "base/stl_util.h" 14 #include "base/stl_util.h"
14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h" 16 #include "base/strings/string_piece.h"
16 #include "base/strings/string_split.h" 17 #include "base/strings/string_split.h"
17 #include "device/hid/hid_connection_linux.h" 18 #include "device/hid/hid_connection_linux.h"
18 #include "device/hid/hid_device_info.h" 19 #include "device/hid/hid_device_info.h"
19 #include "device/hid/hid_service_linux.h" 20 #include "device/hid/hid_service_linux.h"
21 #include "device/hid/udev_common.h"
20 22
21 namespace device { 23 namespace device {
22 24
23 namespace { 25 namespace {
24 26
25 const char kUdevName[] = "udev";
26 const char kUdevActionAdd[] = "add";
27 const char kUdevActionRemove[] = "remove";
28 const char kHIDSubSystem[] = "hid"; 27 const char kHIDSubSystem[] = "hid";
29 28
30 const char kHIDID[] = "HID_ID"; 29 const char kHIDID[] = "HID_ID";
31 const char kHIDName[] = "HID_NAME"; 30 const char kHIDName[] = "HID_NAME";
32 const char kHIDUnique[] = "HID_UNIQ"; 31 const char kHIDUnique[] = "HID_UNIQ";
33 32
34 } // namespace 33 } // namespace
35 34
36 HidServiceLinux::HidServiceLinux() { 35 HidServiceLinux::HidServiceLinux() {
37 udev_.reset(udev_new()); 36 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance();
38 if (!udev_) { 37 monitor->AddObserver(this);
39 LOG(ERROR) << "Failed to create udev."; 38 monitor->Enumerate(
40 return; 39 base::Bind(&HidServiceLinux::OnDeviceAdded, base::Unretained(this)));
41 }
42 monitor_.reset(udev_monitor_new_from_netlink(udev_.get(), kUdevName));
43 if (!monitor_) {
44 LOG(ERROR) << "Failed to create udev monitor.";
45 return;
46 }
47 int ret = udev_monitor_filter_add_match_subsystem_devtype(
48 monitor_.get(),
49 kHIDSubSystem,
50 NULL);
51 if (ret != 0) {
52 LOG(ERROR) << "Failed to add udev monitor filter.";
53 return;
54 }
55
56 ret = udev_monitor_enable_receiving(monitor_.get());
57 if (ret != 0) {
58 LOG(ERROR) << "Failed to start udev monitoring.";
59 return;
60 }
61
62 monitor_fd_ = udev_monitor_get_fd(monitor_.get());
63 if (monitor_fd_ <= 0) {
64 LOG(ERROR) << "Failed to start udev monitoring.";
65 return;
66 }
67
68 if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
69 monitor_fd_,
70 true,
71 base::MessageLoopForIO::WATCH_READ,
72 &monitor_watcher_,
73 this))
74 return;
75
76 Enumerate();
77 } 40 }
78 41
79 scoped_refptr<HidConnection> HidServiceLinux::Connect( 42 scoped_refptr<HidConnection> HidServiceLinux::Connect(
80 const HidDeviceId& device_id) { 43 const HidDeviceId& device_id) {
81 HidDeviceInfo device_info; 44 HidDeviceInfo device_info;
82 if (!GetDeviceInfo(device_id, &device_info)) 45 if (!GetDeviceInfo(device_id, &device_info))
83 return NULL; 46 return NULL;
84 47
85 ScopedUdevDevicePtr hid_device( 48 ScopedUdevDevicePtr device =
86 udev_device_new_from_syspath(udev_.get(), device_info.device_id.c_str())); 49 DeviceMonitorLinux::GetInstance()->GetDeviceFromPath(
87 if (hid_device) { 50 device_info.device_id);
88 return new HidConnectionLinux(device_info, hid_device.Pass()); 51 if (device)
89 } 52 return new HidConnectionLinux(device_info, device.Pass());
90 return NULL; 53 return NULL;
91 } 54 }
92 55
93 void HidServiceLinux::OnFileCanReadWithoutBlocking(int fd) { 56 HidServiceLinux::~HidServiceLinux() {
94 DCHECK_EQ(monitor_fd_, fd); 57 if (DeviceMonitorLinux::HasInstance())
95 58 DeviceMonitorLinux::GetInstance()->RemoveObserver(this);
96 ScopedUdevDevicePtr dev(udev_monitor_receive_device(monitor_.get()));
97 if (!dev)
98 return;
99
100 std::string action(udev_device_get_action(dev.get()));
101 if (action == kUdevActionAdd) {
102 PlatformAddDevice(dev.get());
103 } else if (action == kUdevActionRemove) {
104 PlatformRemoveDevice(dev.get());
105 }
106 } 59 }
107 60
108 void HidServiceLinux::OnFileCanWriteWithoutBlocking(int fd) {} 61 void HidServiceLinux::OnDeviceAdded(udev_device* device) {
109
110 HidServiceLinux::~HidServiceLinux() {
111 monitor_watcher_.StopWatchingFileDescriptor();
112 close(monitor_fd_);
113 }
114
115 void HidServiceLinux::Enumerate() {
116 scoped_ptr<udev_enumerate, UdevEnumerateDeleter> enumerate(
117 udev_enumerate_new(udev_.get()));
118
119 if (!enumerate) {
120 LOG(ERROR) << "Failed to enumerate devices.";
121 return;
122 }
123
124 if (udev_enumerate_add_match_subsystem(enumerate.get(), kHIDSubSystem)) {
125 LOG(ERROR) << "Failed to enumerate devices.";
126 return;
127 }
128
129 if (udev_enumerate_scan_devices(enumerate.get()) != 0) {
130 LOG(ERROR) << "Failed to enumerate devices.";
131 return;
132 }
133
134 // This list is managed by |enumerate|.
135 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get());
136 for (udev_list_entry* i = devices; i != NULL;
137 i = udev_list_entry_get_next(i)) {
138 ScopedUdevDevicePtr hid_dev(
139 udev_device_new_from_syspath(udev_.get(), udev_list_entry_get_name(i)));
140 if (hid_dev) {
141 PlatformAddDevice(hid_dev.get());
142 }
143 }
144 }
145
146 void HidServiceLinux::PlatformAddDevice(udev_device* device) {
147 if (!device) 62 if (!device)
148 return; 63 return;
149 64
150 const char* device_path = udev_device_get_syspath(device); 65 const char* device_path = udev_device_get_syspath(device);
151 if (!device_path) 66 if (!device_path)
152 return; 67 return;
68 const char* subsystem = udev_device_get_subsystem(device);
69 if (!subsystem || strcmp(subsystem, kHIDSubSystem) != 0)
70 return;
153 71
154 HidDeviceInfo device_info; 72 HidDeviceInfo device_info;
155 device_info.device_id = device_path; 73 device_info.device_id = device_path;
156 74
157 uint32_t int_property = 0; 75 uint32_t int_property = 0;
158 const char* str_property = NULL; 76 const char* str_property = NULL;
159 77
160 const char* hid_id = udev_device_get_property_value(device, kHIDID); 78 const char* hid_id = udev_device_get_property_value(device, kHIDID);
161 if (!hid_id) 79 if (!hid_id)
162 return; 80 return;
(...skipping 16 matching lines...) Expand all
179 if (str_property != NULL) 97 if (str_property != NULL)
180 device_info.serial_number = str_property; 98 device_info.serial_number = str_property;
181 99
182 str_property = udev_device_get_property_value(device, kHIDName); 100 str_property = udev_device_get_property_value(device, kHIDName);
183 if (str_property != NULL) 101 if (str_property != NULL)
184 device_info.product_name = str_property; 102 device_info.product_name = str_property;
185 103
186 AddDevice(device_info); 104 AddDevice(device_info);
187 } 105 }
188 106
189 void HidServiceLinux::PlatformRemoveDevice(udev_device* raw_dev) { 107 void HidServiceLinux::OnDeviceRemoved(udev_device* device) {
190 const char* device_path = NULL; 108 const char* device_path = udev_device_get_syspath(device);;
191 device_path = udev_device_get_syspath(raw_dev); 109 if (device_path)
192 if (device_path == NULL) 110 RemoveDevice(device_path);
193 return;
194 RemoveDevice(device_path);
195 } 111 }
196 112
197 } // namespace dev 113 } // namespace dev
OLDNEW
« no previous file with comments | « device/hid/hid_service_linux.h ('k') | device/hid/udev_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698