xref: /aosp_15_r20/frameworks/native/services/inputflinger/dispatcher/Entry.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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