Index: ui/events/ozone/evdev/event_factory_evdev.cc |
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc |
index 63508d35c85dca789007f2a4f7a2986818264895..78d54daaae32f2d3a1889cbdd9318ca553e242e1 100644 |
--- a/ui/events/ozone/evdev/event_factory_evdev.cc |
+++ b/ui/events/ozone/evdev/event_factory_evdev.cc |
@@ -4,165 +4,27 @@ |
#include "ui/events/ozone/evdev/event_factory_evdev.h" |
-#include <fcntl.h> |
-#include <linux/input.h> |
- |
#include "base/bind.h" |
-#include "base/stl_util.h" |
+#include "base/debug/trace_event.h" |
#include "base/task_runner.h" |
#include "base/thread_task_runner_handle.h" |
#include "base/threading/worker_pool.h" |
#include "base/time/time.h" |
-#include "base/trace_event/trace_event.h" |
#include "ui/events/devices/device_data_manager.h" |
-#include "ui/events/devices/device_util_linux.h" |
#include "ui/events/devices/input_device.h" |
#include "ui/events/ozone/device/device_event.h" |
#include "ui/events/ozone/device/device_manager.h" |
#include "ui/events/ozone/evdev/cursor_delegate_evdev.h" |
-#include "ui/events/ozone/evdev/event_converter_evdev_impl.h" |
+#include "ui/events/ozone/evdev/input_controller_evdev.h" |
+#include "ui/events/ozone/evdev/input_device_factory_evdev.h" |
#include "ui/events/ozone/evdev/input_injector_evdev.h" |
-#include "ui/events/ozone/evdev/tablet_event_converter_evdev.h" |
-#include "ui/events/ozone/evdev/touch_event_converter_evdev.h" |
#if defined(USE_EVDEV_GESTURES) |
-#include "ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h" |
-#include "ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h" |
#include "ui/events/ozone/evdev/libgestures_glue/gesture_property_provider.h" |
#endif |
-#ifndef EVIOCSCLOCKID |
-#define EVIOCSCLOCKID _IOW('E', 0xa0, int) |
-#endif |
- |
namespace ui { |
-namespace { |
- |
-typedef base::Callback<void(scoped_ptr<EventConverterEvdev>)> |
- OpenInputDeviceReplyCallback; |
- |
-struct OpenInputDeviceParams { |
- // Unique identifier for the new device. |
- int id; |
- |
- // Device path to open. |
- base::FilePath path; |
- |
- // Dispatcher for events. Call on UI thread only. |
- DeviceEventDispatcherEvdev* dispatcher; |
- |
- // State shared between devices. Must not be dereferenced on worker thread. |
- CursorDelegateEvdev* cursor; |
-#if defined(USE_EVDEV_GESTURES) |
- GesturePropertyProvider* gesture_property_provider; |
-#endif |
-}; |
- |
-#if defined(USE_EVDEV_GESTURES) |
-bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { |
- if (devinfo.HasTouchpad()) |
- return true; |
- |
- if (devinfo.HasRelXY()) |
- return true; // mouse |
- |
- return false; |
-} |
-#endif |
- |
-scoped_ptr<EventConverterEvdev> CreateConverter( |
- const OpenInputDeviceParams& params, |
- int fd, |
- InputDeviceType type, |
- const EventDeviceInfo& devinfo) { |
-#if defined(USE_EVDEV_GESTURES) |
- // Touchpad or mouse: use gestures library. |
- // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent |
- if (UseGesturesLibraryForDevice(devinfo)) { |
- scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = |
- make_scoped_ptr(new GestureInterpreterLibevdevCros( |
- params.id, params.cursor, params.gesture_property_provider, |
- params.dispatcher)); |
- return make_scoped_ptr(new EventReaderLibevdevCros( |
- fd, params.path, params.id, type, devinfo, gesture_interp.Pass())); |
- } |
-#endif |
- |
- // Touchscreen: use TouchEventConverterEvdev. |
- if (devinfo.HasMTAbsXY()) { |
- scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( |
- fd, params.path, params.id, type, params.dispatcher)); |
- converter->Initialize(devinfo); |
- return converter.Pass(); |
- } |
- |
- // Graphics tablet |
- if (devinfo.HasAbsXY()) |
- return make_scoped_ptr<EventConverterEvdev>(new TabletEventConverterEvdev( |
- fd, params.path, params.id, type, params.cursor, devinfo, |
- params.dispatcher)); |
- |
- // Everything else: use EventConverterEvdevImpl. |
- return make_scoped_ptr<EventConverterEvdevImpl>( |
- new EventConverterEvdevImpl(fd, params.path, params.id, type, devinfo, |
- params.cursor, params.dispatcher)); |
-} |
- |
-// Open an input device. Opening may put the calling thread to sleep, and |
-// therefore should be run on a thread where latency is not critical. We |
-// run it on a thread from the worker pool. |
-// |
-// This takes a TaskRunner and runs the reply on that thread, so that we |
-// can hop threads if necessary (back to the UI thread). |
-void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params, |
- scoped_refptr<base::TaskRunner> reply_runner, |
- const OpenInputDeviceReplyCallback& reply_callback) { |
- const base::FilePath& path = params->path; |
- |
- TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value()); |
- |
- int fd = open(path.value().c_str(), O_RDONLY | O_NONBLOCK); |
- if (fd < 0) { |
- PLOG(ERROR) << "Cannot open '" << path.value(); |
- return; |
- } |
- |
- // Use monotonic timestamps for events. The touch code in particular |
- // expects event timestamps to correlate to the monotonic clock |
- // (base::TimeTicks). |
- unsigned int clk = CLOCK_MONOTONIC; |
- if (ioctl(fd, EVIOCSCLOCKID, &clk)) |
- PLOG(ERROR) << "failed to set CLOCK_MONOTONIC"; |
- |
- EventDeviceInfo devinfo; |
- if (!devinfo.Initialize(fd)) { |
- LOG(ERROR) << "failed to get device information for " << path.value(); |
- close(fd); |
- return; |
- } |
- |
- InputDeviceType type = GetInputDeviceTypeFromPath(path); |
- |
- scoped_ptr<EventConverterEvdev> converter = |
- CreateConverter(*params, fd, type, devinfo); |
- |
- // Reply with the constructed converter. |
- reply_runner->PostTask(FROM_HERE, |
- base::Bind(reply_callback, base::Passed(&converter))); |
-} |
- |
-// Close an input device. Closing may put the calling thread to sleep, and |
-// therefore should be run on a thread where latency is not critical. We |
-// run it on the FILE thread. |
-void CloseInputDevice(const base::FilePath& path, |
- scoped_ptr<EventConverterEvdev> converter) { |
- TRACE_EVENT1("ozone", "CloseInputDevice", "path", path.value()); |
- converter.reset(); |
-} |
- |
-} // namespace |
- |
EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor, |
DeviceManager* device_manager, |
KeyboardLayoutEngine* keyboard_layout) |
@@ -175,8 +37,7 @@ EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor, |
#if defined(USE_EVDEV_GESTURES) |
gesture_property_provider_(new GesturePropertyProvider), |
#endif |
- input_controller_(this, |
- &keyboard_, |
+ input_controller_(&keyboard_, |
&button_map_ |
#if defined(USE_EVDEV_GESTURES) |
, |
@@ -188,11 +49,21 @@ EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor, |
DCHECK(device_manager_); |
} |
-EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } |
+EventFactoryEvdev::~EventFactoryEvdev() { |
+} |
void EventFactoryEvdev::Init() { |
DCHECK(!initialized_); |
- ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
+ |
+ // Set up device factory. |
+ input_device_factory_.reset( |
+ new InputDeviceFactoryEvdev(this, base::ThreadTaskRunnerHandle::Get(), |
+#if defined(USE_EVDEV_GESTURES) |
+ gesture_property_provider_.get(), |
+#endif |
+ cursor_)); |
+ // TODO(spang): This settings interface is really broken. crbug.com/450899 |
+ input_controller_.SetInputDeviceFactory(input_device_factory_.get()); |
// Scan & monitor devices. |
device_manager_->AddObserver(this); |
@@ -305,25 +176,6 @@ void EventFactoryEvdev::DispatchUiEventTask(scoped_ptr<Event> event) { |
DispatchEvent(event.get()); |
} |
-void EventFactoryEvdev::AttachInputDevice( |
- scoped_ptr<EventConverterEvdev> converter) { |
- const base::FilePath& path = converter->path(); |
- |
- TRACE_EVENT1("ozone", "AttachInputDevice", "path", path.value()); |
- DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
- |
- // If we have an existing device, detach it. We don't want two |
- // devices with the same name open at the same time. |
- if (converters_[path]) |
- DetachInputDevice(path); |
- |
- // Add initialized device to map. |
- converters_[path] = converter.release(); |
- converters_[path]->Start(); |
- |
- NotifyDeviceChange(*converters_[path]); |
-} |
- |
void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) { |
if (event.device_type() != DeviceEvent::INPUT) |
return; |
@@ -332,35 +184,14 @@ void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) { |
case DeviceEvent::ADD: |
case DeviceEvent::CHANGE: { |
TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); |
- |
- scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); |
- params->id = NextDeviceId(); |
- params->path = event.path(); |
- params->cursor = cursor_; |
- params->dispatcher = this; |
- |
-#if defined(USE_EVDEV_GESTURES) |
- params->gesture_property_provider = gesture_property_provider_.get(); |
-#endif |
- |
- OpenInputDeviceReplyCallback reply_callback = |
- base::Bind(&EventFactoryEvdev::AttachInputDevice, |
- weak_ptr_factory_.GetWeakPtr()); |
- |
- // Dispatch task to open from the worker pool, since open may block. |
- base::WorkerPool::PostTask(FROM_HERE, |
- base::Bind(&OpenInputDevice, |
- base::Passed(¶ms), |
- ui_task_runner_, |
- reply_callback), |
- true /* task_is_slow */); |
- } |
+ input_device_factory_->AddInputDevice(NextDeviceId(), event.path()); |
break; |
+ } |
case DeviceEvent::REMOVE: { |
TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); |
- DetachInputDevice(event.path()); |
- } |
+ input_device_factory_->RemoveInputDevice(event.path()); |
break; |
+ } |
} |
} |
@@ -369,29 +200,6 @@ void EventFactoryEvdev::OnDispatcherListChanged() { |
Init(); |
} |
-void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) { |
- TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value()); |
- DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
- |
- // Remove device from map. |
- scoped_ptr<EventConverterEvdev> converter(converters_[path]); |
- converters_.erase(path); |
- |
- if (converter) { |
- // Cancel libevent notifications from this converter. This part must be |
- // on UI since the polling happens on UI. |
- converter->Stop(); |
- |
- NotifyDeviceChange(*converter); |
- |
- // Dispatch task to close from the worker pool, since close may block. |
- base::WorkerPool::PostTask( |
- FROM_HERE, |
- base::Bind(&CloseInputDevice, path, base::Passed(&converter)), |
- true); |
- } |
-} |
- |
void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget, |
const gfx::PointF& location) { |
if (cursor_) { |
@@ -404,107 +212,8 @@ void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget, |
} |
} |
-void EventFactoryEvdev::DisableInternalTouchpad() { |
- for (const auto& it : converters_) { |
- EventConverterEvdev* converter = it.second; |
- if (converter->type() == InputDeviceType::INPUT_DEVICE_INTERNAL && |
- converter->HasTouchpad()) { |
- DCHECK(!converter->HasKeyboard()); |
- converter->set_ignore_events(true); |
- } |
- } |
-} |
- |
-void EventFactoryEvdev::EnableInternalTouchpad() { |
- for (const auto& it : converters_) { |
- EventConverterEvdev* converter = it.second; |
- if (converter->type() == InputDeviceType::INPUT_DEVICE_INTERNAL && |
- converter->HasTouchpad()) { |
- DCHECK(!converter->HasKeyboard()); |
- converter->set_ignore_events(false); |
- } |
- } |
-} |
- |
-void EventFactoryEvdev::DisableInternalKeyboardExceptKeys( |
- scoped_ptr<std::set<DomCode>> excepted_keys) { |
- for (const auto& it : converters_) { |
- EventConverterEvdev* converter = it.second; |
- if (converter->type() == InputDeviceType::INPUT_DEVICE_INTERNAL && |
- converter->HasKeyboard()) { |
- converter->SetAllowedKeys(excepted_keys.Pass()); |
- } |
- } |
-} |
- |
-void EventFactoryEvdev::EnableInternalKeyboard() { |
- for (const auto& it : converters_) { |
- EventConverterEvdev* converter = it.second; |
- if (converter->type() == InputDeviceType::INPUT_DEVICE_INTERNAL && |
- converter->HasKeyboard()) { |
- converter->AllowAllKeys(); |
- } |
- } |
-} |
- |
-void EventFactoryEvdev::NotifyDeviceChange( |
- const EventConverterEvdev& converter) { |
- if (converter.HasTouchscreen()) |
- NotifyTouchscreensUpdated(); |
- |
- if (converter.HasKeyboard()) |
- NotifyKeyboardsUpdated(); |
-} |
- |
-void EventFactoryEvdev::NotifyTouchscreensUpdated() { |
- DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); |
- std::vector<TouchscreenDevice> touchscreens; |
- for (auto it = converters_.begin(); it != converters_.end(); ++it) { |
- if (it->second->HasTouchscreen()) { |
- // TODO(spang): Extract the number of touch-points supported by the |
- // device. |
- const int touch_points = 11; |
- touchscreens.push_back(TouchscreenDevice( |
- it->second->id(), it->second->type(), std::string() /* Device name */, |
- it->second->GetTouchscreenSize(), touch_points)); |
- } |
- } |
- |
- observer->OnTouchscreenDevicesUpdated(touchscreens); |
-} |
- |
-void EventFactoryEvdev::NotifyKeyboardsUpdated() { |
- DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); |
- std::vector<KeyboardDevice> keyboards; |
- for (auto it = converters_.begin(); it != converters_.end(); ++it) { |
- if (it->second->HasKeyboard()) { |
- keyboards.push_back(KeyboardDevice(it->second->id(), it->second->type(), |
- std::string() /* Device name */)); |
- } |
- } |
- |
- observer->OnKeyboardDevicesUpdated(keyboards); |
-} |
- |
int EventFactoryEvdev::NextDeviceId() { |
return ++last_device_id_; |
} |
-bool EventFactoryEvdev::GetDeviceIdsByType(const EventDeviceType type, |
- std::vector<int>* device_ids) { |
- if (device_ids) |
- device_ids->clear(); |
- std::vector<int> ids; |
- |
-#if defined(USE_EVDEV_GESTURES) |
- // Ask GesturePropertyProvider for matching devices. |
- gesture_property_provider_->GetDeviceIdsByType(type, &ids); |
-#endif |
- // In the future we can add other device matching logics here. |
- |
- if (device_ids) |
- device_ids->assign(ids.begin(), ids.end()); |
- return !ids.empty(); |
-} |
- |
} // namespace ui |