summaryrefslogtreecommitdiffstats
path: root/modules/input/evdev/InputDevice.cpp
diff options
context:
space:
mode:
authorTim Kilbourn <tkilbourn@google.com>2015-02-13 10:35:20 -0800
committerTim Kilbourn <tkilbourn@google.com>2015-03-30 17:21:29 -0700
commit73475a4eb2cebf06f965c58e015d06c333e71e61 (patch)
treeee7d5d7a4673867738f0725a278f54a0f7aaf261 /modules/input/evdev/InputDevice.cpp
parent3fba7bebe84b6e2ae515dda142dc3b37071b4dcd (diff)
downloadhardware_libhardware-73475a4eb2cebf06f965c58e015d06c333e71e61.zip
hardware_libhardware-73475a4eb2cebf06f965c58e015d06c333e71e61.tar.gz
hardware_libhardware-73475a4eb2cebf06f965c58e015d06c333e71e61.tar.bz2
Input event hub for evdev input HAL module.
InputHub monitors paths for device changes and input events. InputDeviceManager creates InputDevices and routes input events to them. InputDevices currently just log these events during development. InputHost represents a wrapper around the HAL interface. Change-Id: Ic47d574498eb07bcdcd17812a648539fdf1c69d6
Diffstat (limited to 'modules/input/evdev/InputDevice.cpp')
-rw-r--r--modules/input/evdev/InputDevice.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/modules/input/evdev/InputDevice.cpp b/modules/input/evdev/InputDevice.cpp
new file mode 100644
index 0000000..c0b59d7
--- /dev/null
+++ b/modules/input/evdev/InputDevice.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputDevice"
+#define LOG_NDEBUG 0
+
+#include <linux/input.h>
+
+#define __STDC_FORMAT_MACROS
+#include <cinttypes>
+#include <string>
+
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#include "InputHub.h"
+#include "InputDevice.h"
+
+#define MSC_ANDROID_TIME_SEC 0x6
+#define MSC_ANDROID_TIME_USEC 0x7
+
+namespace android {
+
+EvdevDevice::EvdevDevice(std::shared_ptr<InputDeviceNode> node) :
+ mDeviceNode(node) {}
+
+void EvdevDevice::processInput(InputEvent& event, nsecs_t currentTime) {
+ std::string log;
+ log.append("---InputEvent for device %s---\n");
+ log.append(" when: %" PRId64 "\n");
+ log.append(" type: %d\n");
+ log.append(" code: %d\n");
+ log.append(" value: %d\n");
+ ALOGV(log.c_str(), mDeviceNode->getPath().c_str(), event.when, event.type, event.code,
+ event.value);
+
+ if (event.type == EV_MSC) {
+ if (event.code == MSC_ANDROID_TIME_SEC) {
+ mOverrideSec = event.value;
+ } else if (event.code == MSC_ANDROID_TIME_USEC) {
+ mOverrideUsec = event.value;
+ }
+ return;
+ }
+
+ if (mOverrideSec || mOverrideUsec) {
+ event.when = s2ns(mOverrideSec) + us2ns(mOverrideUsec);
+ ALOGV("applied override time %d.%06d", mOverrideSec, mOverrideUsec);
+
+ if (event.type == EV_SYN && event.code == SYN_REPORT) {
+ mOverrideSec = 0;
+ mOverrideUsec = 0;
+ }
+ }
+
+ // Bug 7291243: Add a guard in case the kernel generates timestamps
+ // that appear to be far into the future because they were generated
+ // using the wrong clock source.
+ //
+ // This can happen because when the input device is initially opened
+ // it has a default clock source of CLOCK_REALTIME. Any input events
+ // enqueued right after the device is opened will have timestamps
+ // generated using CLOCK_REALTIME. We later set the clock source
+ // to CLOCK_MONOTONIC but it is already too late.
+ //
+ // Invalid input event timestamps can result in ANRs, crashes and
+ // and other issues that are hard to track down. We must not let them
+ // propagate through the system.
+ //
+ // Log a warning so that we notice the problem and recover gracefully.
+ if (event.when >= currentTime + s2ns(10)) {
+ // Double-check. Time may have moved on.
+ auto time = systemTime(SYSTEM_TIME_MONOTONIC);
+ if (event.when > time) {
+ ALOGW("An input event from %s has a timestamp that appears to have "
+ "been generated using the wrong clock source (expected "
+ "CLOCK_MONOTONIC): event time %" PRId64 ", current time %" PRId64
+ ", call time %" PRId64 ". Using current time instead.",
+ mDeviceNode->getPath().c_str(), event.when, time, currentTime);
+ event.when = time;
+ } else {
+ ALOGV("Event time is ok but failed the fast path and required an extra "
+ "call to systemTime: event time %" PRId64 ", current time %" PRId64
+ ", call time %" PRId64 ".", event.when, time, currentTime);
+ }
+ }
+}
+
+} // namespace android