blob: c4b378909069fd47c436abf58d4c2544c4244620 [file] [log] [blame]
Garfield Tane84e6f92019-08-29 17:28:41 -07001/*
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
Ashwini Orugantid399a522019-10-10 11:16:45 -070021#include <android-base/properties.h>
Garfield Tane84e6f92019-08-29 17:28:41 -070022#include <android-base/stringprintf.h>
23#include <cutils/atomic.h>
24#include <inttypes.h>
25
Ashwini Orugantid399a522019-10-10 11:16:45 -070026using android::base::GetBoolProperty;
Garfield Tane84e6f92019-08-29 17:28:41 -070027using android::base::StringPrintf;
28
29namespace android::inputdispatcher {
30
31static std::string motionActionToString(int32_t action) {
32 // Convert MotionEvent action to string
33 switch (action & AMOTION_EVENT_ACTION_MASK) {
34 case AMOTION_EVENT_ACTION_DOWN:
35 return "DOWN";
36 case AMOTION_EVENT_ACTION_MOVE:
37 return "MOVE";
38 case AMOTION_EVENT_ACTION_UP:
39 return "UP";
40 case AMOTION_EVENT_ACTION_POINTER_DOWN:
41 return "POINTER_DOWN";
42 case AMOTION_EVENT_ACTION_POINTER_UP:
43 return "POINTER_UP";
44 }
45 return StringPrintf("%" PRId32, action);
46}
47
48static std::string keyActionToString(int32_t action) {
49 // Convert KeyEvent action to string
50 switch (action) {
51 case AKEY_EVENT_ACTION_DOWN:
52 return "DOWN";
53 case AKEY_EVENT_ACTION_UP:
54 return "UP";
55 case AKEY_EVENT_ACTION_MULTIPLE:
56 return "MULTIPLE";
57 }
58 return StringPrintf("%" PRId32, action);
59}
Gang Wange9087892020-01-07 12:17:14 -050060VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry) {
61 return {{VerifiedInputEvent::Type::KEY, entry.deviceId, entry.eventTime, entry.source,
62 entry.displayId},
63 entry.action,
64 entry.downTime,
65 entry.flags & VERIFIED_KEY_EVENT_FLAGS,
66 entry.keyCode,
67 entry.scanCode,
68 entry.metaState,
69 entry.repeatCount};
70}
71
72VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry) {
73 const float rawX = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
74 const float rawY = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
75 const int actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
76 return {{VerifiedInputEvent::Type::MOTION, entry.deviceId, entry.eventTime, entry.source,
77 entry.displayId},
78 rawX,
79 rawY,
80 actionMasked,
81 entry.downTime,
82 entry.flags & VERIFIED_MOTION_EVENT_FLAGS,
83 entry.metaState,
84 entry.buttonState};
85}
Garfield Tane84e6f92019-08-29 17:28:41 -070086
87// --- EventEntry ---
88
Siarhei Vishniakou49483272019-10-22 13:13:47 -070089EventEntry::EventEntry(uint32_t sequenceNum, Type type, nsecs_t eventTime, uint32_t policyFlags)
Garfield Tane84e6f92019-08-29 17:28:41 -070090 : sequenceNum(sequenceNum),
91 refCount(1),
92 type(type),
93 eventTime(eventTime),
94 policyFlags(policyFlags),
95 injectionState(nullptr),
96 dispatchInProgress(false) {}
97
98EventEntry::~EventEntry() {
99 releaseInjectionState();
100}
101
102void EventEntry::release() {
103 refCount -= 1;
104 if (refCount == 0) {
105 delete this;
106 } else {
107 ALOG_ASSERT(refCount > 0);
108 }
109}
110
111void EventEntry::releaseInjectionState() {
112 if (injectionState) {
113 injectionState->release();
114 injectionState = nullptr;
115 }
116}
117
118// --- ConfigurationChangedEntry ---
119
120ConfigurationChangedEntry::ConfigurationChangedEntry(uint32_t sequenceNum, nsecs_t eventTime)
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700121 : EventEntry(sequenceNum, Type::CONFIGURATION_CHANGED, eventTime, 0) {}
Garfield Tane84e6f92019-08-29 17:28:41 -0700122
123ConfigurationChangedEntry::~ConfigurationChangedEntry() {}
124
125void ConfigurationChangedEntry::appendDescription(std::string& msg) const {
126 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
127}
128
129// --- DeviceResetEntry ---
130
131DeviceResetEntry::DeviceResetEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId)
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700132 : EventEntry(sequenceNum, Type::DEVICE_RESET, eventTime, 0), deviceId(deviceId) {}
Garfield Tane84e6f92019-08-29 17:28:41 -0700133
134DeviceResetEntry::~DeviceResetEntry() {}
135
136void DeviceResetEntry::appendDescription(std::string& msg) const {
137 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
138}
139
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100140// --- FocusEntry ---
141
142// Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
143FocusEntry::FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken,
144 bool hasFocus)
145 : EventEntry(sequenceNum, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER),
146 connectionToken(connectionToken),
147 hasFocus(hasFocus) {}
148
149FocusEntry::~FocusEntry() {}
150
151void FocusEntry::appendDescription(std::string& msg) const {
152 msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
153}
154
Garfield Tane84e6f92019-08-29 17:28:41 -0700155// --- KeyEntry ---
156
157KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
158 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t flags,
159 int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
160 nsecs_t downTime)
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700161 : EventEntry(sequenceNum, Type::KEY, eventTime, policyFlags),
Garfield Tane84e6f92019-08-29 17:28:41 -0700162 deviceId(deviceId),
163 source(source),
164 displayId(displayId),
165 action(action),
166 flags(flags),
167 keyCode(keyCode),
168 scanCode(scanCode),
169 metaState(metaState),
170 repeatCount(repeatCount),
171 downTime(downTime),
172 syntheticRepeat(false),
173 interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
174 interceptKeyWakeupTime(0) {}
175
176KeyEntry::~KeyEntry() {}
177
178void KeyEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700179 msg += StringPrintf("KeyEvent");
180 if (!GetBoolProperty("ro.debuggable", false)) {
181 return;
182 }
183 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Garfield Tane84e6f92019-08-29 17:28:41 -0700184 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
185 "repeatCount=%d), policyFlags=0x%08x",
186 deviceId, source, displayId, keyActionToString(action).c_str(), flags,
187 keyCode, scanCode, metaState, repeatCount, policyFlags);
188}
189
190void KeyEntry::recycle() {
191 releaseInjectionState();
192
193 dispatchInProgress = false;
194 syntheticRepeat = false;
195 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
196 interceptKeyWakeupTime = 0;
197}
198
199// --- MotionEntry ---
200
201MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
202 int32_t displayId, uint32_t policyFlags, int32_t action,
203 int32_t actionButton, int32_t flags, int32_t metaState,
204 int32_t buttonState, MotionClassification classification,
205 int32_t edgeFlags, float xPrecision, float yPrecision,
206 float xCursorPosition, float yCursorPosition, nsecs_t downTime,
207 uint32_t pointerCount, const PointerProperties* pointerProperties,
208 const PointerCoords* pointerCoords, float xOffset, float yOffset)
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700209 : EventEntry(sequenceNum, Type::MOTION, eventTime, policyFlags),
Garfield Tane84e6f92019-08-29 17:28:41 -0700210 eventTime(eventTime),
211 deviceId(deviceId),
212 source(source),
213 displayId(displayId),
214 action(action),
215 actionButton(actionButton),
216 flags(flags),
217 metaState(metaState),
218 buttonState(buttonState),
219 classification(classification),
220 edgeFlags(edgeFlags),
221 xPrecision(xPrecision),
222 yPrecision(yPrecision),
223 xCursorPosition(xCursorPosition),
224 yCursorPosition(yCursorPosition),
225 downTime(downTime),
226 pointerCount(pointerCount) {
227 for (uint32_t i = 0; i < pointerCount; i++) {
228 this->pointerProperties[i].copyFrom(pointerProperties[i]);
229 this->pointerCoords[i].copyFrom(pointerCoords[i]);
230 if (xOffset || yOffset) {
231 this->pointerCoords[i].applyOffset(xOffset, yOffset);
232 }
233 }
234}
235
236MotionEntry::~MotionEntry() {}
237
238void MotionEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700239 msg += StringPrintf("MotionEvent");
240 if (!GetBoolProperty("ro.debuggable", false)) {
241 return;
242 }
243 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tane84e6f92019-08-29 17:28:41 -0700244 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
245 "buttonState=0x%08x, "
246 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
247 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
248 deviceId, source, displayId, motionActionToString(action).c_str(),
249 actionButton, flags, metaState, buttonState,
250 motionClassificationToString(classification), edgeFlags, xPrecision,
251 yPrecision, xCursorPosition, yCursorPosition);
252
253 for (uint32_t i = 0; i < pointerCount; i++) {
254 if (i) {
255 msg += ", ";
256 }
257 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id, pointerCoords[i].getX(),
258 pointerCoords[i].getY());
259 }
260 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
261}
262
263// --- DispatchEntry ---
264
265volatile int32_t DispatchEntry::sNextSeqAtomic;
266
267DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset,
268 float yOffset, float globalScaleFactor, float windowXScale,
269 float windowYScale)
270 : seq(nextSeq()),
271 eventEntry(eventEntry),
272 targetFlags(targetFlags),
273 xOffset(xOffset),
274 yOffset(yOffset),
275 globalScaleFactor(globalScaleFactor),
276 windowXScale(windowXScale),
277 windowYScale(windowYScale),
278 deliveryTime(0),
279 resolvedAction(0),
280 resolvedFlags(0) {
281 eventEntry->refCount += 1;
282}
283
284DispatchEntry::~DispatchEntry() {
285 eventEntry->release();
286}
287
288uint32_t DispatchEntry::nextSeq() {
289 // Sequence number 0 is reserved and will never be returned.
290 uint32_t seq;
291 do {
292 seq = android_atomic_inc(&sNextSeqAtomic);
293 } while (!seq);
294 return seq;
295}
296
297// --- CommandEntry ---
298
299CommandEntry::CommandEntry(Command command)
300 : command(command),
301 eventTime(0),
302 keyEntry(nullptr),
303 userActivityEventType(0),
304 seq(0),
305 handled(false) {}
306
307CommandEntry::~CommandEntry() {}
308
309} // namespace android::inputdispatcher