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