blob: c0b59d7f3d6b7a6f9dca1a9dac0ef99a7525ca95 [file] [log] [blame]
Tim Kilbourn73475a42015-02-13 10:35:20 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDevice"
18#define LOG_NDEBUG 0
19
20#include <linux/input.h>
21
22#define __STDC_FORMAT_MACROS
23#include <cinttypes>
24#include <string>
25
26#include <utils/Log.h>
27#include <utils/Timers.h>
28
29#include "InputHub.h"
30#include "InputDevice.h"
31
32#define MSC_ANDROID_TIME_SEC 0x6
33#define MSC_ANDROID_TIME_USEC 0x7
34
35namespace android {
36
37EvdevDevice::EvdevDevice(std::shared_ptr<InputDeviceNode> node) :
38 mDeviceNode(node) {}
39
40void EvdevDevice::processInput(InputEvent& event, nsecs_t currentTime) {
41 std::string log;
42 log.append("---InputEvent for device %s---\n");
43 log.append(" when: %" PRId64 "\n");
44 log.append(" type: %d\n");
45 log.append(" code: %d\n");
46 log.append(" value: %d\n");
47 ALOGV(log.c_str(), mDeviceNode->getPath().c_str(), event.when, event.type, event.code,
48 event.value);
49
50 if (event.type == EV_MSC) {
51 if (event.code == MSC_ANDROID_TIME_SEC) {
52 mOverrideSec = event.value;
53 } else if (event.code == MSC_ANDROID_TIME_USEC) {
54 mOverrideUsec = event.value;
55 }
56 return;
57 }
58
59 if (mOverrideSec || mOverrideUsec) {
60 event.when = s2ns(mOverrideSec) + us2ns(mOverrideUsec);
61 ALOGV("applied override time %d.%06d", mOverrideSec, mOverrideUsec);
62
63 if (event.type == EV_SYN && event.code == SYN_REPORT) {
64 mOverrideSec = 0;
65 mOverrideUsec = 0;
66 }
67 }
68
69 // Bug 7291243: Add a guard in case the kernel generates timestamps
70 // that appear to be far into the future because they were generated
71 // using the wrong clock source.
72 //
73 // This can happen because when the input device is initially opened
74 // it has a default clock source of CLOCK_REALTIME. Any input events
75 // enqueued right after the device is opened will have timestamps
76 // generated using CLOCK_REALTIME. We later set the clock source
77 // to CLOCK_MONOTONIC but it is already too late.
78 //
79 // Invalid input event timestamps can result in ANRs, crashes and
80 // and other issues that are hard to track down. We must not let them
81 // propagate through the system.
82 //
83 // Log a warning so that we notice the problem and recover gracefully.
84 if (event.when >= currentTime + s2ns(10)) {
85 // Double-check. Time may have moved on.
86 auto time = systemTime(SYSTEM_TIME_MONOTONIC);
87 if (event.when > time) {
88 ALOGW("An input event from %s has a timestamp that appears to have "
89 "been generated using the wrong clock source (expected "
90 "CLOCK_MONOTONIC): event time %" PRId64 ", current time %" PRId64
91 ", call time %" PRId64 ". Using current time instead.",
92 mDeviceNode->getPath().c_str(), event.when, time, currentTime);
93 event.when = time;
94 } else {
95 ALOGV("Event time is ok but failed the fast path and required an extra "
96 "call to systemTime: event time %" PRId64 ", current time %" PRId64
97 ", call time %" PRId64 ".", event.when, time, currentTime);
98 }
99 }
100}
101
102} // namespace android