1 /*
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
35 namespace android {
36
EvdevDevice(std::shared_ptr<InputDeviceNode> node)37 EvdevDevice::EvdevDevice(std::shared_ptr<InputDeviceNode> node) :
38 mDeviceNode(node) {}
39
processInput(InputEvent & event,nsecs_t currentTime)40 void 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
103