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