summaryrefslogtreecommitdiffstats
path: root/modules/input/evdev/InputDevice.cpp
diff options
context:
space:
mode:
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