Chromium Code Reviews| Index: ui/events/ozone/evdev/event_factory.cc |
| diff --git a/ui/events/ozone/evdev/event_factory.cc b/ui/events/ozone/evdev/event_factory.cc |
| index cc928197d7eaec071d270182d7a3c9efffb3d2ac..f7145d0d2f694e2dd859c6ff6dd7267e74397c92 100644 |
| --- a/ui/events/ozone/evdev/event_factory.cc |
| +++ b/ui/events/ozone/evdev/event_factory.cc |
| @@ -4,26 +4,19 @@ |
| #include "ui/events/ozone/evdev/event_factory.h" |
| -#include <errno.h> |
| #include <fcntl.h> |
| #include <linux/input.h> |
| -#include <poll.h> |
| -#include <unistd.h> |
| -#if defined(USE_UDEV) |
| -#include <libudev.h> |
| -#endif |
| - |
| -#include "base/callback.h" |
| #include "base/debug/trace_event.h" |
| #include "base/files/file_enumerator.h" |
| #include "base/stl_util.h" |
| -#include "base/strings/stringprintf.h" |
| -#include "base/threading/thread_restrictions.h" |
| #include "ui/events/ozone/evdev/event_device_info.h" |
| #include "ui/events/ozone/evdev/key_event_converter.h" |
| #include "ui/events/ozone/evdev/touch_event_converter.h" |
| -#include "ui/events/ozone/event_factory_ozone.h" |
| + |
| +#if defined(USE_UDEV) |
| +#include "ui/events/ozone/evdev/device_manager_udev.h" |
| +#endif |
| namespace ui { |
| @@ -41,86 +34,29 @@ bool IsTouchScreen(const EventDeviceInfo& devinfo) { |
| return devinfo.HasEventType(EV_ABS) && !IsTouchPad(devinfo); |
| } |
| -#if defined(USE_UDEV) |
| - |
| -// Severity levels from syslog.h. We can't include it directly as it |
| -// conflicts with base/logging.h |
| -enum { |
| - SYS_LOG_EMERG = 0, |
| - SYS_LOG_ALERT = 1, |
| - SYS_LOG_CRIT = 2, |
| - SYS_LOG_ERR = 3, |
| - SYS_LOG_WARNING = 4, |
| - SYS_LOG_NOTICE = 5, |
| - SYS_LOG_INFO = 6, |
| - SYS_LOG_DEBUG = 7, |
| -}; |
| - |
| -// Log handler for messages generated from libudev. |
| -void UdevLog(struct udev* udev, |
| - int priority, |
| - const char* file, |
| - int line, |
| - const char* fn, |
| - const char* format, |
| - va_list args) { |
| - std::string message = base::StringPrintf("libudev: %s: ", fn); |
| - base::StringAppendV(&message, format, args); |
| - if (priority <= SYS_LOG_ERR) |
| - LOG(ERROR) << message; |
| - else if (priority <= SYS_LOG_INFO) |
| - VLOG(1) << message; |
| - else // SYS_LOG_DEBUG |
| - VLOG(2) << message; |
| -} |
| - |
| -// Connect to the udev daemon. |
| -scoped_udev UdevConnect() { |
| - struct udev* udev = udev_new(); |
| - if (udev) { |
| - udev_set_log_fn(udev, UdevLog); |
| - udev_set_log_priority(udev, SYS_LOG_DEBUG); |
| +class DeviceManagerManual : public DeviceManagerEvdev { |
| + public: |
| + DeviceManagerManual() {} |
| + ~DeviceManagerManual() {} |
|
sadrul
2014/01/31 21:00:59
virtual here too, I think?
spang
2014/01/31 22:02:07
Done.
|
| + |
| + // Enumerate existing devices & start watching for device changes. |
| + void ScanAndStartMonitoring(const EvdevDeviceCallback& device_added, |
|
sadrul
2014/01/31 21:00:59
virtual
spang
2014/01/31 22:02:07
Done.
|
| + const EvdevDeviceCallback& device_removed) |
| + OVERRIDE { |
| + base::FileEnumerator file_enum(base::FilePath("/dev/input"), |
| + false, |
| + base::FileEnumerator::FILES, |
| + "event*[0-9]"); |
| + for (base::FilePath path = file_enum.Next(); !path.empty(); |
| + path = file_enum.Next()) |
| + device_added.Run(path); |
| } |
| - return scoped_udev(udev); |
| -} |
| - |
| -// Enumerate all input devices using udev. Calls device_callback per device. |
| -bool UdevEnumerateInputDevices( |
| - struct udev* udev, |
| - base::Callback<void(const base::FilePath&)> device_callback) { |
| - scoped_udev_enumerate enumerate(udev_enumerate_new(udev)); |
| - if (!enumerate) |
| - return false; |
| - |
| - udev_enumerate_add_match_subsystem(enumerate.get(), "input"); |
| - udev_enumerate_scan_devices(enumerate.get()); |
| - |
| - struct udev_list_entry* devices = |
| - udev_enumerate_get_list_entry(enumerate.get()); |
| - struct udev_list_entry* entry; |
| - |
| - udev_list_entry_foreach(entry, devices) { |
| - const char* name = udev_list_entry_get_name(entry); |
| - |
| - scoped_udev_device device(udev_device_new_from_syspath(udev, name)); |
| - if (!device) |
| - continue; |
| - |
| - const char* path = udev_device_get_devnode(device.get()); |
| - if (!path) |
| - continue; |
| - |
| - // Found input device node; attach. |
| - device_callback.Run(base::FilePath(path)); |
| - } |
| - |
| - return true; |
| -} |
| - |
| -#endif // defined(USE_UDEV) |
| +}; |
| } // namespace |
| +DeviceManagerEvdev::~DeviceManagerEvdev() {} |
| + |
| EventFactoryEvdev::EventFactoryEvdev() {} |
| EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } |
| @@ -147,7 +83,7 @@ void EventFactoryEvdev::AttachInputDevice(const base::FilePath& path) { |
| return; |
| } |
| - // TODO(spang) Add more device types. Support hot-plugging. |
| + // TODO(spang) Add more device types. |
| scoped_ptr<EventConverterEvdev> converter; |
| if (IsTouchScreen(devinfo)) |
| converter.reset(new TouchEventConverterEvdev(fd, path)); |
| @@ -155,47 +91,32 @@ void EventFactoryEvdev::AttachInputDevice(const base::FilePath& path) { |
| converter.reset(new KeyEventConverterEvdev(fd, path, &modifiers_)); |
| if (converter) { |
| + delete converters_[path]; |
| converters_[path] = converter.release(); |
| } else { |
| close(fd); |
| } |
| } |
| -void EventFactoryEvdev::StartProcessingEvents() { |
| - base::ThreadRestrictions::AssertIOAllowed(); |
| +void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) { |
| + TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value()); |
| + delete converters_[path]; |
| + converters_.erase(path); |
| +} |
| +void EventFactoryEvdev::StartProcessingEvents() { |
| #if defined(USE_UDEV) |
| // Scan for input devices using udev. |
| - StartProcessingEventsUdev(); |
| + device_manager_ = CreateDeviceManagerUdev(); |
| #else |
| // No udev support. Scan devices manually in /dev/input. |
| - StartProcessingEventsManual(); |
| + device_manager_.reset(new DeviceManagerManual); |
| #endif |
| -} |
| -void EventFactoryEvdev::StartProcessingEventsManual() { |
| - base::FileEnumerator file_enum(base::FilePath("/dev/input"), |
| - false, |
| - base::FileEnumerator::FILES, |
| - "event*[0-9]"); |
| - for (base::FilePath path = file_enum.Next(); !path.empty(); |
| - path = file_enum.Next()) |
| - AttachInputDevice(path); |
| + device_manager_->ScanAndStartMonitoring( |
| + base::Bind(&EventFactoryEvdev::AttachInputDevice, base::Unretained(this)), |
| + base::Bind(&EventFactoryEvdev::DetachInputDevice, |
| + base::Unretained(this))); |
| } |
| -#if defined(USE_UDEV) |
| -void EventFactoryEvdev::StartProcessingEventsUdev() { |
| - udev_ = UdevConnect(); |
| - if (!udev_) { |
| - LOG(ERROR) << "failed to connect to udev"; |
| - return; |
| - } |
| - if (!UdevEnumerateInputDevices( |
| - udev_.get(), |
| - base::Bind(&EventFactoryEvdev::AttachInputDevice, |
| - base::Unretained(this)))) |
| - LOG(ERROR) << "failed to enumerate input devices via udev"; |
| -} |
| -#endif |
| - |
| } // namespace ui |