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