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