1 /*
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 #define LOG_TAG "InputDispatcher"
18
19 #include "Entry.h"
20
21 #include "Connection.h"
22 #include "DebugConfig.h"
23
24 #include <android-base/stringprintf.h>
25 #include <cutils/atomic.h>
26 #include <inttypes.h>
27
28 using android::base::StringPrintf;
29
30 namespace android::inputdispatcher {
31
verifiedKeyEventFromKeyEntry(const KeyEntry & entry)32 VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry) {
33 return {{VerifiedInputEvent::Type::KEY, entry.deviceId, entry.eventTime, entry.source,
34 entry.displayId},
35 entry.action,
36 entry.flags & VERIFIED_KEY_EVENT_FLAGS,
37 entry.downTime,
38 entry.keyCode,
39 entry.scanCode,
40 entry.metaState,
41 entry.repeatCount};
42 }
43
verifiedMotionEventFromMotionEntry(const MotionEntry & entry,const ui::Transform & rawTransform)44 VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry,
45 const ui::Transform& rawTransform) {
46 const vec2 rawXY = MotionEvent::calculateTransformedXY(entry.source, rawTransform,
47 entry.pointerCoords[0].getXYValue());
48 const int actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
49 return {{VerifiedInputEvent::Type::MOTION, entry.deviceId, entry.eventTime, entry.source,
50 entry.displayId},
51 rawXY.x,
52 rawXY.y,
53 actionMasked,
54 entry.flags & VERIFIED_MOTION_EVENT_FLAGS,
55 entry.downTime,
56 entry.metaState,
57 entry.buttonState};
58 }
59
60 // --- EventEntry ---
61
EventEntry(int32_t id,Type type,nsecs_t eventTime,uint32_t policyFlags)62 EventEntry::EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags)
63 : id(id),
64 type(type),
65 eventTime(eventTime),
66 policyFlags(policyFlags),
67 injectionState(nullptr),
68 dispatchInProgress(false) {}
69
~EventEntry()70 EventEntry::~EventEntry() {
71 releaseInjectionState();
72 }
73
releaseInjectionState()74 void EventEntry::releaseInjectionState() {
75 if (injectionState) {
76 injectionState->release();
77 injectionState = nullptr;
78 }
79 }
80
81 // --- ConfigurationChangedEntry ---
82
ConfigurationChangedEntry(int32_t id,nsecs_t eventTime)83 ConfigurationChangedEntry::ConfigurationChangedEntry(int32_t id, nsecs_t eventTime)
84 : EventEntry(id, Type::CONFIGURATION_CHANGED, eventTime, 0) {}
85
~ConfigurationChangedEntry()86 ConfigurationChangedEntry::~ConfigurationChangedEntry() {}
87
getDescription() const88 std::string ConfigurationChangedEntry::getDescription() const {
89 return StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
90 }
91
92 // --- DeviceResetEntry ---
93
DeviceResetEntry(int32_t id,nsecs_t eventTime,int32_t deviceId)94 DeviceResetEntry::DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId)
95 : EventEntry(id, Type::DEVICE_RESET, eventTime, 0), deviceId(deviceId) {}
96
~DeviceResetEntry()97 DeviceResetEntry::~DeviceResetEntry() {}
98
getDescription() const99 std::string DeviceResetEntry::getDescription() const {
100 return StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
101 }
102
103 // --- FocusEntry ---
104
105 // Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
FocusEntry(int32_t id,nsecs_t eventTime,sp<IBinder> connectionToken,bool hasFocus,const std::string & reason)106 FocusEntry::FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus,
107 const std::string& reason)
108 : EventEntry(id, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER),
109 connectionToken(connectionToken),
110 hasFocus(hasFocus),
111 reason(reason) {}
112
~FocusEntry()113 FocusEntry::~FocusEntry() {}
114
getDescription() const115 std::string FocusEntry::getDescription() const {
116 return StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
117 }
118
119 // --- PointerCaptureChangedEntry ---
120
121 // PointerCaptureChanged notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER
122 // for all entries.
PointerCaptureChangedEntry(int32_t id,nsecs_t eventTime,const PointerCaptureRequest & request)123 PointerCaptureChangedEntry::PointerCaptureChangedEntry(int32_t id, nsecs_t eventTime,
124 const PointerCaptureRequest& request)
125 : EventEntry(id, Type::POINTER_CAPTURE_CHANGED, eventTime, POLICY_FLAG_PASS_TO_USER),
126 pointerCaptureRequest(request) {}
127
~PointerCaptureChangedEntry()128 PointerCaptureChangedEntry::~PointerCaptureChangedEntry() {}
129
getDescription() const130 std::string PointerCaptureChangedEntry::getDescription() const {
131 return StringPrintf("PointerCaptureChangedEvent(pointerCaptureEnabled=%s)",
132 pointerCaptureRequest.enable ? "true" : "false");
133 }
134
135 // --- DragEntry ---
136
137 // Drag notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
DragEntry(int32_t id,nsecs_t eventTime,sp<IBinder> connectionToken,bool isExiting,float x,float y)138 DragEntry::DragEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool isExiting,
139 float x, float y)
140 : EventEntry(id, Type::DRAG, eventTime, POLICY_FLAG_PASS_TO_USER),
141 connectionToken(connectionToken),
142 isExiting(isExiting),
143 x(x),
144 y(y) {}
145
~DragEntry()146 DragEntry::~DragEntry() {}
147
getDescription() const148 std::string DragEntry::getDescription() const {
149 return StringPrintf("DragEntry(isExiting=%s, x=%f, y=%f)", isExiting ? "true" : "false", x, y);
150 }
151
152 // --- KeyEntry ---
153
KeyEntry(int32_t id,nsecs_t eventTime,int32_t deviceId,uint32_t source,int32_t displayId,uint32_t policyFlags,int32_t action,int32_t flags,int32_t keyCode,int32_t scanCode,int32_t metaState,int32_t repeatCount,nsecs_t downTime)154 KeyEntry::KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
155 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t flags,
156 int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
157 nsecs_t downTime)
158 : EventEntry(id, Type::KEY, eventTime, policyFlags),
159 deviceId(deviceId),
160 source(source),
161 displayId(displayId),
162 action(action),
163 flags(flags),
164 keyCode(keyCode),
165 scanCode(scanCode),
166 metaState(metaState),
167 repeatCount(repeatCount),
168 downTime(downTime),
169 syntheticRepeat(false),
170 interceptKeyResult(KeyEntry::InterceptKeyResult::UNKNOWN),
171 interceptKeyWakeupTime(0) {}
172
~KeyEntry()173 KeyEntry::~KeyEntry() {}
174
getDescription() const175 std::string KeyEntry::getDescription() const {
176 if (!IS_DEBUGGABLE_BUILD) {
177 return "KeyEvent";
178 }
179 return StringPrintf("KeyEvent(deviceId=%d, eventTime=%" PRIu64 ", source=%s, displayId=%" PRId32
180 ", action=%s, "
181 "flags=0x%08x, keyCode=%s(%d), scanCode=%d, metaState=0x%08x, "
182 "repeatCount=%d), policyFlags=0x%08x",
183 deviceId, eventTime, inputEventSourceToString(source).c_str(), displayId,
184 KeyEvent::actionToString(action), flags, KeyEvent::getLabel(keyCode),
185 keyCode, scanCode, metaState, repeatCount, policyFlags);
186 }
187
recycle()188 void KeyEntry::recycle() {
189 releaseInjectionState();
190
191 dispatchInProgress = false;
192 syntheticRepeat = false;
193 interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
194 interceptKeyWakeupTime = 0;
195 }
196
197 // --- TouchModeEntry ---
198
TouchModeEntry(int32_t id,nsecs_t eventTime,bool inTouchMode,int displayId)199 TouchModeEntry::TouchModeEntry(int32_t id, nsecs_t eventTime, bool inTouchMode, int displayId)
200 : EventEntry(id, Type::TOUCH_MODE_CHANGED, eventTime, POLICY_FLAG_PASS_TO_USER),
201 inTouchMode(inTouchMode),
202 displayId(displayId) {}
203
~TouchModeEntry()204 TouchModeEntry::~TouchModeEntry() {}
205
getDescription() const206 std::string TouchModeEntry::getDescription() const {
207 return StringPrintf("TouchModeEvent(inTouchMode=%s)", inTouchMode ? "true" : "false");
208 }
209
210 // --- MotionEntry ---
211
MotionEntry(int32_t id,nsecs_t eventTime,int32_t deviceId,uint32_t source,int32_t displayId,uint32_t policyFlags,int32_t action,int32_t actionButton,int32_t flags,int32_t metaState,int32_t buttonState,MotionClassification classification,int32_t edgeFlags,float xPrecision,float yPrecision,float xCursorPosition,float yCursorPosition,nsecs_t downTime,uint32_t pointerCount,const PointerProperties * pointerProperties,const PointerCoords * pointerCoords)212 MotionEntry::MotionEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
213 int32_t displayId, uint32_t policyFlags, int32_t action,
214 int32_t actionButton, int32_t flags, int32_t metaState,
215 int32_t buttonState, MotionClassification classification,
216 int32_t edgeFlags, float xPrecision, float yPrecision,
217 float xCursorPosition, float yCursorPosition, nsecs_t downTime,
218 uint32_t pointerCount, const PointerProperties* pointerProperties,
219 const PointerCoords* pointerCoords)
220 : EventEntry(id, Type::MOTION, eventTime, policyFlags),
221 deviceId(deviceId),
222 source(source),
223 displayId(displayId),
224 action(action),
225 actionButton(actionButton),
226 flags(flags),
227 metaState(metaState),
228 buttonState(buttonState),
229 classification(classification),
230 edgeFlags(edgeFlags),
231 xPrecision(xPrecision),
232 yPrecision(yPrecision),
233 xCursorPosition(xCursorPosition),
234 yCursorPosition(yCursorPosition),
235 downTime(downTime),
236 pointerCount(pointerCount) {
237 for (uint32_t i = 0; i < pointerCount; i++) {
238 this->pointerProperties[i].copyFrom(pointerProperties[i]);
239 this->pointerCoords[i].copyFrom(pointerCoords[i]);
240 }
241 }
242
~MotionEntry()243 MotionEntry::~MotionEntry() {}
244
getDescription() const245 std::string MotionEntry::getDescription() const {
246 if (!IS_DEBUGGABLE_BUILD) {
247 return "MotionEvent";
248 }
249 std::string msg;
250 msg += StringPrintf("MotionEvent(deviceId=%d, eventTime=%" PRIu64
251 ", source=%s, displayId=%" PRId32
252 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
253 "buttonState=0x%08x, "
254 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
255 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
256 deviceId, eventTime, inputEventSourceToString(source).c_str(), displayId,
257 MotionEvent::actionToString(action).c_str(), actionButton, flags, metaState,
258 buttonState, motionClassificationToString(classification), edgeFlags,
259 xPrecision, yPrecision, xCursorPosition, yCursorPosition);
260
261 for (uint32_t i = 0; i < pointerCount; i++) {
262 if (i) {
263 msg += ", ";
264 }
265 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id, pointerCoords[i].getX(),
266 pointerCoords[i].getY());
267 }
268 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
269 return msg;
270 }
271
272 // --- SensorEntry ---
273
SensorEntry(int32_t id,nsecs_t eventTime,int32_t deviceId,uint32_t source,uint32_t policyFlags,nsecs_t hwTimestamp,InputDeviceSensorType sensorType,InputDeviceSensorAccuracy accuracy,bool accuracyChanged,std::vector<float> values)274 SensorEntry::SensorEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
275 uint32_t policyFlags, nsecs_t hwTimestamp,
276 InputDeviceSensorType sensorType, InputDeviceSensorAccuracy accuracy,
277 bool accuracyChanged, std::vector<float> values)
278 : EventEntry(id, Type::SENSOR, eventTime, policyFlags),
279 deviceId(deviceId),
280 source(source),
281 sensorType(sensorType),
282 accuracy(accuracy),
283 accuracyChanged(accuracyChanged),
284 hwTimestamp(hwTimestamp),
285 values(std::move(values)) {}
286
~SensorEntry()287 SensorEntry::~SensorEntry() {}
288
getDescription() const289 std::string SensorEntry::getDescription() const {
290 std::string msg;
291 msg += StringPrintf("SensorEntry(deviceId=%d, source=%s, sensorType=%s, "
292 "accuracy=0x%08x, hwTimestamp=%" PRId64,
293 deviceId, inputEventSourceToString(source).c_str(),
294 ftl::enum_string(sensorType).c_str(), accuracy, hwTimestamp);
295
296 if (IS_DEBUGGABLE_BUILD) {
297 for (size_t i = 0; i < values.size(); i++) {
298 if (i > 0) {
299 msg += ", ";
300 }
301 msg += StringPrintf("(%.3f)", values[i]);
302 }
303 }
304 msg += StringPrintf(", policyFlags=0x%08x", policyFlags);
305 return msg;
306 }
307
308 // --- DispatchEntry ---
309
310 volatile int32_t DispatchEntry::sNextSeqAtomic;
311
DispatchEntry(std::shared_ptr<EventEntry> eventEntry,ftl::Flags<InputTarget::Flags> targetFlags,const ui::Transform & transform,const ui::Transform & rawTransform,float globalScaleFactor)312 DispatchEntry::DispatchEntry(std::shared_ptr<EventEntry> eventEntry,
313 ftl::Flags<InputTarget::Flags> targetFlags,
314 const ui::Transform& transform, const ui::Transform& rawTransform,
315 float globalScaleFactor)
316 : seq(nextSeq()),
317 eventEntry(std::move(eventEntry)),
318 targetFlags(targetFlags),
319 transform(transform),
320 rawTransform(rawTransform),
321 globalScaleFactor(globalScaleFactor),
322 deliveryTime(0),
323 resolvedAction(0),
324 resolvedFlags(0) {}
325
nextSeq()326 uint32_t DispatchEntry::nextSeq() {
327 // Sequence number 0 is reserved and will never be returned.
328 uint32_t seq;
329 do {
330 seq = android_atomic_inc(&sNextSeqAtomic);
331 } while (!seq);
332 return seq;
333 }
334
operator <<(std::ostream & out,const DispatchEntry & entry)335 std::ostream& operator<<(std::ostream& out, const DispatchEntry& entry) {
336 out << "DispatchEntry{resolvedAction=";
337 switch (entry.eventEntry->type) {
338 case EventEntry::Type::KEY: {
339 out << KeyEvent::actionToString(entry.resolvedAction);
340 break;
341 }
342 case EventEntry::Type::MOTION: {
343 out << MotionEvent::actionToString(entry.resolvedAction);
344 break;
345 }
346 default: {
347 out << "<invalid, not a key or a motion>";
348 break;
349 }
350 }
351 std::string transform;
352 entry.transform.dump(transform, "transform");
353 out << ", resolvedFlags=" << entry.resolvedFlags
354 << ", targetFlags=" << entry.targetFlags.string() << ", transform=" << transform
355 << "} original: " << entry.eventEntry->getDescription();
356 return out;
357 }
358
359 } // namespace android::inputdispatcher
360