Index: device/hid/hid_service_linux.cc |
diff --git a/device/hid/hid_service_linux.cc b/device/hid/hid_service_linux.cc |
index 04a3c160664468d68db60c74e28f4925e52ec63f..aeaeb19aeae31a0f8957b46afdf9a10accccde45 100644 |
--- a/device/hid/hid_service_linux.cc |
+++ b/device/hid/hid_service_linux.cc |
@@ -8,6 +8,7 @@ |
#include <string> |
#include <vector> |
+#include "base/bind.h" |
#include "base/logging.h" |
#include "base/platform_file.h" |
#include "base/stl_util.h" |
@@ -17,14 +18,12 @@ |
#include "device/hid/hid_connection_linux.h" |
#include "device/hid/hid_device_info.h" |
#include "device/hid/hid_service_linux.h" |
+#include "device/hid/udev_common.h" |
namespace device { |
namespace { |
-const char kUdevName[] = "udev"; |
-const char kUdevActionAdd[] = "add"; |
-const char kUdevActionRemove[] = "remove"; |
const char kHIDSubSystem[] = "hid"; |
const char kHIDID[] = "HID_ID"; |
@@ -34,46 +33,10 @@ const char kHIDUnique[] = "HID_UNIQ"; |
} // namespace |
HidServiceLinux::HidServiceLinux() { |
- udev_.reset(udev_new()); |
- if (!udev_) { |
- LOG(ERROR) << "Failed to create udev."; |
- return; |
- } |
- monitor_.reset(udev_monitor_new_from_netlink(udev_.get(), kUdevName)); |
- if (!monitor_) { |
- LOG(ERROR) << "Failed to create udev monitor."; |
- return; |
- } |
- int ret = udev_monitor_filter_add_match_subsystem_devtype( |
- monitor_.get(), |
- kHIDSubSystem, |
- NULL); |
- if (ret != 0) { |
- LOG(ERROR) << "Failed to add udev monitor filter."; |
- return; |
- } |
- |
- ret = udev_monitor_enable_receiving(monitor_.get()); |
- if (ret != 0) { |
- LOG(ERROR) << "Failed to start udev monitoring."; |
- return; |
- } |
- |
- monitor_fd_ = udev_monitor_get_fd(monitor_.get()); |
- if (monitor_fd_ <= 0) { |
- LOG(ERROR) << "Failed to start udev monitoring."; |
- return; |
- } |
- |
- if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
- monitor_fd_, |
- true, |
- base::MessageLoopForIO::WATCH_READ, |
- &monitor_watcher_, |
- this)) |
- return; |
- |
- Enumerate(); |
+ DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); |
+ monitor->AddObserver(this); |
+ monitor->Enumerate( |
+ base::Bind(&HidServiceLinux::OnDeviceAdded, base::Unretained(this))); |
} |
scoped_refptr<HidConnection> HidServiceLinux::Connect( |
@@ -82,74 +45,29 @@ scoped_refptr<HidConnection> HidServiceLinux::Connect( |
if (!GetDeviceInfo(device_id, &device_info)) |
return NULL; |
- ScopedUdevDevicePtr hid_device( |
- udev_device_new_from_syspath(udev_.get(), device_info.device_id.c_str())); |
- if (hid_device) { |
- return new HidConnectionLinux(device_info, hid_device.Pass()); |
- } |
+ ScopedUdevDevicePtr device = |
+ DeviceMonitorLinux::GetInstance()->GetDeviceFromPath( |
+ device_info.device_id); |
+ if (device) |
+ return new HidConnectionLinux(device_info, device.Pass()); |
return NULL; |
} |
-void HidServiceLinux::OnFileCanReadWithoutBlocking(int fd) { |
- DCHECK_EQ(monitor_fd_, fd); |
- |
- ScopedUdevDevicePtr dev(udev_monitor_receive_device(monitor_.get())); |
- if (!dev) |
- return; |
- |
- std::string action(udev_device_get_action(dev.get())); |
- if (action == kUdevActionAdd) { |
- PlatformAddDevice(dev.get()); |
- } else if (action == kUdevActionRemove) { |
- PlatformRemoveDevice(dev.get()); |
- } |
-} |
- |
-void HidServiceLinux::OnFileCanWriteWithoutBlocking(int fd) {} |
- |
HidServiceLinux::~HidServiceLinux() { |
- monitor_watcher_.StopWatchingFileDescriptor(); |
- close(monitor_fd_); |
+ if (DeviceMonitorLinux::HasInstance()) |
+ DeviceMonitorLinux::GetInstance()->RemoveObserver(this); |
} |
-void HidServiceLinux::Enumerate() { |
- scoped_ptr<udev_enumerate, UdevEnumerateDeleter> enumerate( |
- udev_enumerate_new(udev_.get())); |
- |
- if (!enumerate) { |
- LOG(ERROR) << "Failed to enumerate devices."; |
- return; |
- } |
- |
- if (udev_enumerate_add_match_subsystem(enumerate.get(), kHIDSubSystem)) { |
- LOG(ERROR) << "Failed to enumerate devices."; |
- return; |
- } |
- |
- if (udev_enumerate_scan_devices(enumerate.get()) != 0) { |
- LOG(ERROR) << "Failed to enumerate devices."; |
- return; |
- } |
- |
- // This list is managed by |enumerate|. |
- udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get()); |
- for (udev_list_entry* i = devices; i != NULL; |
- i = udev_list_entry_get_next(i)) { |
- ScopedUdevDevicePtr hid_dev( |
- udev_device_new_from_syspath(udev_.get(), udev_list_entry_get_name(i))); |
- if (hid_dev) { |
- PlatformAddDevice(hid_dev.get()); |
- } |
- } |
-} |
- |
-void HidServiceLinux::PlatformAddDevice(udev_device* device) { |
+void HidServiceLinux::OnDeviceAdded(udev_device* device) { |
if (!device) |
return; |
const char* device_path = udev_device_get_syspath(device); |
if (!device_path) |
return; |
+ const char* subsystem = udev_device_get_subsystem(device); |
+ if (!subsystem || strcmp(subsystem, kHIDSubSystem) != 0) |
+ return; |
HidDeviceInfo device_info; |
device_info.device_id = device_path; |
@@ -186,12 +104,10 @@ void HidServiceLinux::PlatformAddDevice(udev_device* device) { |
AddDevice(device_info); |
} |
-void HidServiceLinux::PlatformRemoveDevice(udev_device* raw_dev) { |
- const char* device_path = NULL; |
- device_path = udev_device_get_syspath(raw_dev); |
- if (device_path == NULL) |
- return; |
- RemoveDevice(device_path); |
+void HidServiceLinux::OnDeviceRemoved(udev_device* device) { |
+ const char* device_path = udev_device_get_syspath(device);; |
+ if (device_path) |
+ RemoveDevice(device_path); |
} |
} // namespace dev |