blob: a1eb0079df033878e4c3bff788dc716b63ee7fc1 [file] [log] [blame]
Garfield Tane84e6f92019-08-29 17:28:41 -07001/*
2 * Copyright (C) 2019 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#include "Entry.h"
18
19#include "Connection.h"
20
Ashwini Orugantid399a522019-10-10 11:16:45 -070021#include <android-base/properties.h>
Garfield Tane84e6f92019-08-29 17:28:41 -070022#include <android-base/stringprintf.h>
23#include <cutils/atomic.h>
24#include <inttypes.h>
25
Ashwini Orugantid399a522019-10-10 11:16:45 -070026using android::base::GetBoolProperty;
Garfield Tane84e6f92019-08-29 17:28:41 -070027using android::base::StringPrintf;
28
29namespace android::inputdispatcher {
30
31static std::string motionActionToString(int32_t action) {
32 // Convert MotionEvent action to string
33 switch (action & AMOTION_EVENT_ACTION_MASK) {
34 case AMOTION_EVENT_ACTION_DOWN:
35 return "DOWN";
36 case AMOTION_EVENT_ACTION_MOVE:
37 return "MOVE";
38 case AMOTION_EVENT_ACTION_UP:
39 return "UP";
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070040 case AMOTION_EVENT_ACTION_CANCEL:
41 return "CANCEL";
Garfield Tane84e6f92019-08-29 17:28:41 -070042 case AMOTION_EVENT_ACTION_POINTER_DOWN:
43 return "POINTER_DOWN";
44 case AMOTION_EVENT_ACTION_POINTER_UP:
45 return "POINTER_UP";
46 }
47 return StringPrintf("%" PRId32, action);
48}
49
50static std::string keyActionToString(int32_t action) {
51 // Convert KeyEvent action to string
52 switch (action) {
53 case AKEY_EVENT_ACTION_DOWN:
54 return "DOWN";
55 case AKEY_EVENT_ACTION_UP:
56 return "UP";
57 case AKEY_EVENT_ACTION_MULTIPLE:
58 return "MULTIPLE";
59 }
60 return StringPrintf("%" PRId32, action);
61}
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070062
Gang Wange9087892020-01-07 12:17:14 -050063VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry) {
64 return {{VerifiedInputEvent::Type::KEY, entry.deviceId, entry.eventTime, entry.source,
65 entry.displayId},
66 entry.action,
67 entry.downTime,
68 entry.flags & VERIFIED_KEY_EVENT_FLAGS,
69 entry.keyCode,
70 entry.scanCode,
71 entry.metaState,
72 entry.repeatCount};
73}
74
75VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry) {
76 const float rawX = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
77 const float rawY = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
78 const int actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
79 return {{VerifiedInputEvent::Type::MOTION, entry.deviceId, entry.eventTime, entry.source,
80 entry.displayId},
81 rawX,
82 rawY,
83 actionMasked,
84 entry.downTime,
85 entry.flags & VERIFIED_MOTION_EVENT_FLAGS,
86 entry.metaState,
87 entry.buttonState};
88}
Garfield Tane84e6f92019-08-29 17:28:41 -070089
90// --- EventEntry ---
91
Garfield Tanc51d1ba2020-01-28 13:24:04 -080092EventEntry::EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags)
93 : id(id),
Garfield Tane84e6f92019-08-29 17:28:41 -070094 refCount(1),
95 type(type),
96 eventTime(eventTime),
97 policyFlags(policyFlags),
98 injectionState(nullptr),
99 dispatchInProgress(false) {}
100
101EventEntry::~EventEntry() {
102 releaseInjectionState();
103}
104
105void EventEntry::release() {
106 refCount -= 1;
107 if (refCount == 0) {
108 delete this;
109 } else {
110 ALOG_ASSERT(refCount > 0);
111 }
112}
113
114void EventEntry::releaseInjectionState() {
115 if (injectionState) {
116 injectionState->release();
117 injectionState = nullptr;
118 }
119}
120
121// --- ConfigurationChangedEntry ---
122
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800123ConfigurationChangedEntry::ConfigurationChangedEntry(int32_t id, nsecs_t eventTime)
124 : EventEntry(id, Type::CONFIGURATION_CHANGED, eventTime, 0) {}
Garfield Tane84e6f92019-08-29 17:28:41 -0700125
126ConfigurationChangedEntry::~ConfigurationChangedEntry() {}
127
128void ConfigurationChangedEntry::appendDescription(std::string& msg) const {
129 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
130}
131
132// --- DeviceResetEntry ---
133
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800134DeviceResetEntry::DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId)
135 : EventEntry(id, Type::DEVICE_RESET, eventTime, 0), deviceId(deviceId) {}
Garfield Tane84e6f92019-08-29 17:28:41 -0700136
137DeviceResetEntry::~DeviceResetEntry() {}
138
139void DeviceResetEntry::appendDescription(std::string& msg) const {
140 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
141}
142
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100143// --- FocusEntry ---
144
145// Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800146FocusEntry::FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus)
147 : EventEntry(id, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER),
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100148 connectionToken(connectionToken),
149 hasFocus(hasFocus) {}
150
151FocusEntry::~FocusEntry() {}
152
153void FocusEntry::appendDescription(std::string& msg) const {
154 msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
155}
156
Garfield Tane84e6f92019-08-29 17:28:41 -0700157// --- KeyEntry ---
158
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800159KeyEntry::KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
Garfield Tane84e6f92019-08-29 17:28:41 -0700160 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t flags,
161 int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
162 nsecs_t downTime)
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800163 : EventEntry(id, Type::KEY, eventTime, policyFlags),
Garfield Tane84e6f92019-08-29 17:28:41 -0700164 deviceId(deviceId),
165 source(source),
166 displayId(displayId),
167 action(action),
168 flags(flags),
169 keyCode(keyCode),
170 scanCode(scanCode),
171 metaState(metaState),
172 repeatCount(repeatCount),
173 downTime(downTime),
174 syntheticRepeat(false),
175 interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
176 interceptKeyWakeupTime(0) {}
177
178KeyEntry::~KeyEntry() {}
179
180void KeyEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700181 msg += StringPrintf("KeyEvent");
182 if (!GetBoolProperty("ro.debuggable", false)) {
183 return;
184 }
185 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Garfield Tane84e6f92019-08-29 17:28:41 -0700186 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
187 "repeatCount=%d), policyFlags=0x%08x",
188 deviceId, source, displayId, keyActionToString(action).c_str(), flags,
189 keyCode, scanCode, metaState, repeatCount, policyFlags);
190}
191
192void KeyEntry::recycle() {
193 releaseInjectionState();
194
195 dispatchInProgress = false;
196 syntheticRepeat = false;
197 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
198 interceptKeyWakeupTime = 0;
199}
200
201// --- MotionEntry ---
202
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800203MotionEntry::MotionEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
Garfield Tane84e6f92019-08-29 17:28:41 -0700204 int32_t displayId, uint32_t policyFlags, int32_t action,
205 int32_t actionButton, int32_t flags, int32_t metaState,
206 int32_t buttonState, MotionClassification classification,
207 int32_t edgeFlags, float xPrecision, float yPrecision,
208 float xCursorPosition, float yCursorPosition, nsecs_t downTime,
209 uint32_t pointerCount, const PointerProperties* pointerProperties,
210 const PointerCoords* pointerCoords, float xOffset, float yOffset)
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800211 : EventEntry(id, Type::MOTION, eventTime, policyFlags),
Garfield Tane84e6f92019-08-29 17:28:41 -0700212 eventTime(eventTime),
213 deviceId(deviceId),
214 source(source),
215 displayId(displayId),
216 action(action),
217 actionButton(actionButton),
218 flags(flags),
219 metaState(metaState),
220 buttonState(buttonState),
221 classification(classification),
222 edgeFlags(edgeFlags),
223 xPrecision(xPrecision),
224 yPrecision(yPrecision),
225 xCursorPosition(xCursorPosition),
226 yCursorPosition(yCursorPosition),
227 downTime(downTime),
228 pointerCount(pointerCount) {
229 for (uint32_t i = 0; i < pointerCount; i++) {
230 this->pointerProperties[i].copyFrom(pointerProperties[i]);
231 this->pointerCoords[i].copyFrom(pointerCoords[i]);
232 if (xOffset || yOffset) {
233 this->pointerCoords[i].applyOffset(xOffset, yOffset);
234 }
235 }
236}
237
238MotionEntry::~MotionEntry() {}
239
240void MotionEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700241 msg += StringPrintf("MotionEvent");
242 if (!GetBoolProperty("ro.debuggable", false)) {
243 return;
244 }
245 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tane84e6f92019-08-29 17:28:41 -0700246 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
247 "buttonState=0x%08x, "
248 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
249 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
250 deviceId, source, displayId, motionActionToString(action).c_str(),
251 actionButton, flags, metaState, buttonState,
252 motionClassificationToString(classification), edgeFlags, xPrecision,
253 yPrecision, xCursorPosition, yCursorPosition);
254
255 for (uint32_t i = 0; i < pointerCount; i++) {
256 if (i) {
257 msg += ", ";
258 }
259 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id, pointerCoords[i].getX(),
260 pointerCoords[i].getY());
261 }
262 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
263}
264
265// --- DispatchEntry ---
266
267volatile int32_t DispatchEntry::sNextSeqAtomic;
268
269DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset,
270 float yOffset, float globalScaleFactor, float windowXScale,
271 float windowYScale)
272 : seq(nextSeq()),
273 eventEntry(eventEntry),
274 targetFlags(targetFlags),
275 xOffset(xOffset),
276 yOffset(yOffset),
277 globalScaleFactor(globalScaleFactor),
278 windowXScale(windowXScale),
279 windowYScale(windowYScale),
280 deliveryTime(0),
281 resolvedAction(0),
282 resolvedFlags(0) {
283 eventEntry->refCount += 1;
284}
285
286DispatchEntry::~DispatchEntry() {
287 eventEntry->release();
288}
289
290uint32_t DispatchEntry::nextSeq() {
291 // Sequence number 0 is reserved and will never be returned.
292 uint32_t seq;
293 do {
294 seq = android_atomic_inc(&sNextSeqAtomic);
295 } while (!seq);
296 return seq;
297}
298
299// --- CommandEntry ---
300
301CommandEntry::CommandEntry(Command command)
302 : command(command),
303 eventTime(0),
304 keyEntry(nullptr),
305 userActivityEventType(0),
306 seq(0),
307 handled(false) {}
308
309CommandEntry::~CommandEntry() {}
310
311} // namespace android::inputdispatcher