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