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

Unified Diff: components/arc/arc_bridge_input_devices.cc

Issue 1408263006: chromeos: Add ArcInputBridge to components/arc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@arcxx
Patch Set: Arc: Extend ArcBridgeService with input bridge Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: components/arc/arc_bridge_input_devices.cc
diff --git a/components/arc/arc_bridge_input_devices.cc b/components/arc/arc_bridge_input_devices.cc
new file mode 100644
index 0000000000000000000000000000000000000000..114b60000725a6cdd0eead2c38b926a2652ebfdb
--- /dev/null
+++ b/components/arc/arc_bridge_input_devices.cc
@@ -0,0 +1,167 @@
+#include "components/arc/arc_bridge_input_devices.h"
+
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/ozone/evdev/keyboard_util_evdev.h"
+
+#include <linux/input.h>
+
+namespace arc {
+
+// BridgeInputDevice
+
+BridgeInputDevice::BridgeInputDevice(base::ScopedFD fd): fd_(fd.Pass()) {}
+
+void BridgeInputDevice::SendEvent(base::TimeDelta time,
elijahtaylor1 2015/11/02 22:30:29 time is highlighted in the code review tool, maybe
denniskempin 2015/11/16 18:39:28 Done.
+ __u16 type,
elijahtaylor1 2015/11/02 22:30:29 nit: alignment?
denniskempin 2015/11/16 18:39:28 Done.
+ __u16 code,
+ __s32 value) {
+ // Luckily Chrome on POSIX and the receiver both use monotonic time for
+ // input events, so we can just fill in the same timestamp.
elijahtaylor1 2015/11/02 22:30:29 on ARC, we had issues with wall time vs system tim
denniskempin 2015/11/16 18:39:28 I did notice some problems where android will star
+ struct input_event event;
+ event.time.tv_sec = time.InSeconds();
+ base::TimeDelta remainder =
+ time - base::TimeDelta::FromSeconds(event.time.tv_sec);
+ event.time.tv_usec = remainder.InMicroseconds();
+ event.type = type;
+ event.code = code;
+ event.value = value;
+
+ // Write event to file descriptor
+ int num_written = write(fd_.get(), reinterpret_cast<void*>(&event),
+ sizeof(struct input_event));
+ if (num_written != sizeof(struct input_event)) {
+ LOG(ERROR) << "Can't write to file descriptor";
+ }
+}
+
+void BridgeInputDevice::SendSynReport(base::TimeDelta time) {
+ SendEvent(time, EV_SYN, SYN_REPORT, 0);
+}
+
+// KeyboardBridgeInputDevice
+
+void KeyboardBridgeInputDevice::OnKeyEvent(ui::KeyEvent* event) {
elijahtaylor1 2015/11/02 22:30:29 I feel like we should either include the keyboard
denniskempin 2015/11/16 18:39:28 This comment seems to be on the wrong file but I u
+ int native_code =
+ ui::KeycodeConverter::DomCodeToNativeKeycode(event->code());
+
+ __u16 evdev_code = ui::NativeCodeToEvdevCode(native_code);
+ __u32 evdev_value;
+ if (event->type() == ui::ET_KEY_PRESSED) {
+ if (event->flags() & ui::EF_IS_REPEAT) {
+ evdev_value = kKeyRepeated;
+ } else {
+ evdev_value = kKeyPressed;
+ }
+ } else if (event->type() == ui::ET_KEY_RELEASED) {
+ evdev_value = kKeyReleased;
+ }
+
+ SendEvent(event->time_stamp(), EV_KEY, evdev_code, evdev_value);
+ SendSynReport(event->time_stamp());
+}
+
+// MouseBridgeInputDevice
+
+void MouseBridgeInputDevice::OnMouseEvent(ui::MouseEvent* event) {
+ base::TimeDelta time = event->time_stamp();
+
+ // update location
+ SendEvent(time, EV_ABS, ABS_X, event->x());
+ SendEvent(time, EV_ABS, ABS_Y, event->y());
+
+ // update buttons
+ SendMouseButton(event, ui::EF_LEFT_MOUSE_BUTTON, BTN_LEFT);
+ SendMouseButton(event, ui::EF_RIGHT_MOUSE_BUTTON, BTN_RIGHT);
+ SendMouseButton(event, ui::EF_MIDDLE_MOUSE_BUTTON, BTN_MIDDLE);
+
+ // update scroll wheel
+ if (event->IsMouseWheelEvent()) {
+ ui::MouseWheelEvent* wheel_event =
+ static_cast<ui::MouseWheelEvent*>(event);
+ SendEvent(time, EV_REL, REL_WHEEL, wheel_event->y_offset());
+ SendEvent(time, EV_REL, REL_HWHEEL, wheel_event->x_offset());
+ }
+
+ SendSynReport(time);
+}
+
+void MouseBridgeInputDevice::SendMouseButton(ui::MouseEvent* event, int flag,
+ int evdev_code) {
+ if (event->changed_button_flags() & flag) {
+ bool button_value = event->flags() & flag;
+ SendEvent(event->time_stamp(), EV_KEY, evdev_code, (__s32)button_value);
+ }
+}
+
+// TouchscreenBridgeInputDevice
+
+TouchscreenBridgeInputDevice::TouchscreenBridgeInputDevice(base::ScopedFD fd) :
+ BridgeInputDevice(fd.Pass()),
+ current_slot_tracking_ids_(kMaxSlots, kEmptySlot) {}
+
+void TouchscreenBridgeInputDevice::OnTouchEvent(ui::TouchEvent* event) {
+ ui::PointerDetails details = event->pointer_details();
+ base::TimeDelta time = event->time_stamp();
+
+ // find or assing a slot for this tracking id
+ int slot_id = AcquireSlot(event);
+ if (slot_id < 0) {
+ LOG(ERROR) << "Ran out of slot IDs.";
+ return;
+ }
+
+ // we only need to send the slot ID when it has changed.
+ if (slot_id != current_slot_) {
+ current_slot_ = slot_id;
+ SendEvent(time, EV_ABS, ABS_MT_SLOT, current_slot_);
+ }
+
+ // update tracking id
+ if (event->type() == ui::ET_TOUCH_PRESSED) {
+ SendEvent(time, EV_ABS, ABS_MT_TRACKING_ID, event->touch_id());
+ } else if (event->type() == ui::ET_TOUCH_RELEASED) {
+ SendEvent(time, EV_ABS, ABS_MT_TRACKING_ID, -1);
+ }
+
+ // update touch information
+ if (event->type() == ui::ET_TOUCH_MOVED ||
+ event->type() == ui::ET_TOUCH_PRESSED) {
+ SendEvent(time, EV_ABS, ABS_MT_POSITION_X, event->x());
+ SendEvent(time, EV_ABS, ABS_MT_POSITION_Y, event->y());
+ SendEvent(time, EV_ABS, ABS_MT_TOUCH_MAJOR, details.radius_x());
+ SendEvent(time, EV_ABS, ABS_MT_TOUCH_MINOR, details.radius_y());
+ }
+ SendSynReport(time);
+}
+
+int TouchscreenBridgeInputDevice::AcquireSlot(ui::TouchEvent* event) {
+ int slot_id;
+ if (event->type() == ui::ET_TOUCH_PRESSED) {
+ slot_id = FindSlot(kEmptySlot);
+ } else {
+ slot_id = FindSlot(event->touch_id());
+ }
+ if (slot_id < 0) {
+ return -1;
+ }
+
+ if (event->type() == ui::ET_TOUCH_RELEASED) {
+ current_slot_tracking_ids_[slot_id] = kEmptySlot;
+ } else if (event->type() == ui::ET_TOUCH_PRESSED) {
+ current_slot_tracking_ids_[slot_id] = event->touch_id();
+ }
+ return slot_id;
+}
+
+int TouchscreenBridgeInputDevice::FindSlot(int tracking_id) {
+ for (int i = 0; i < kMaxSlots; ++i) {
+ if (current_slot_tracking_ids_[i] == tracking_id) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+} // namespace arc

Powered by Google App Engine
This is Rietveld 408576698