blob: b7236547de04cfbbb1f7c2a2e9523fde395036b9 [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}
60
61// --- EventEntry ---
62
Siarhei Vishniakou49483272019-10-22 13:13:47 -070063EventEntry::EventEntry(uint32_t sequenceNum, Type type, nsecs_t eventTime, uint32_t policyFlags)
Garfield Tane84e6f92019-08-29 17:28:41 -070064 : sequenceNum(sequenceNum),
65 refCount(1),
66 type(type),
67 eventTime(eventTime),
68 policyFlags(policyFlags),
69 injectionState(nullptr),
70 dispatchInProgress(false) {}
71
72EventEntry::~EventEntry() {
73 releaseInjectionState();
74}
75
76void EventEntry::release() {
77 refCount -= 1;
78 if (refCount == 0) {
79 delete this;
80 } else {
81 ALOG_ASSERT(refCount > 0);
82 }
83}
84
85void EventEntry::releaseInjectionState() {
86 if (injectionState) {
87 injectionState->release();
88 injectionState = nullptr;
89 }
90}
91
92// --- ConfigurationChangedEntry ---
93
94ConfigurationChangedEntry::ConfigurationChangedEntry(uint32_t sequenceNum, nsecs_t eventTime)
Siarhei Vishniakou49483272019-10-22 13:13:47 -070095 : EventEntry(sequenceNum, Type::CONFIGURATION_CHANGED, eventTime, 0) {}
Garfield Tane84e6f92019-08-29 17:28:41 -070096
97ConfigurationChangedEntry::~ConfigurationChangedEntry() {}
98
99void ConfigurationChangedEntry::appendDescription(std::string& msg) const {
100 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
101}
102
103// --- DeviceResetEntry ---
104
105DeviceResetEntry::DeviceResetEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId)
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700106 : EventEntry(sequenceNum, Type::DEVICE_RESET, eventTime, 0), deviceId(deviceId) {}
Garfield Tane84e6f92019-08-29 17:28:41 -0700107
108DeviceResetEntry::~DeviceResetEntry() {}
109
110void DeviceResetEntry::appendDescription(std::string& msg) const {
111 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
112}
113
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100114// --- FocusEntry ---
115
116// Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
117FocusEntry::FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken,
118 bool hasFocus)
119 : EventEntry(sequenceNum, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER),
120 connectionToken(connectionToken),
121 hasFocus(hasFocus) {}
122
123FocusEntry::~FocusEntry() {}
124
125void FocusEntry::appendDescription(std::string& msg) const {
126 msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
127}
128
Garfield Tane84e6f92019-08-29 17:28:41 -0700129// --- KeyEntry ---
130
131KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
132 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t flags,
133 int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
134 nsecs_t downTime)
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700135 : EventEntry(sequenceNum, Type::KEY, eventTime, policyFlags),
Garfield Tane84e6f92019-08-29 17:28:41 -0700136 deviceId(deviceId),
137 source(source),
138 displayId(displayId),
139 action(action),
140 flags(flags),
141 keyCode(keyCode),
142 scanCode(scanCode),
143 metaState(metaState),
144 repeatCount(repeatCount),
145 downTime(downTime),
146 syntheticRepeat(false),
147 interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
148 interceptKeyWakeupTime(0) {}
149
150KeyEntry::~KeyEntry() {}
151
152void KeyEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700153 msg += StringPrintf("KeyEvent");
154 if (!GetBoolProperty("ro.debuggable", false)) {
155 return;
156 }
157 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Garfield Tane84e6f92019-08-29 17:28:41 -0700158 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
159 "repeatCount=%d), policyFlags=0x%08x",
160 deviceId, source, displayId, keyActionToString(action).c_str(), flags,
161 keyCode, scanCode, metaState, repeatCount, policyFlags);
162}
163
164void KeyEntry::recycle() {
165 releaseInjectionState();
166
167 dispatchInProgress = false;
168 syntheticRepeat = false;
169 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
170 interceptKeyWakeupTime = 0;
171}
172
173// --- MotionEntry ---
174
175MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
176 int32_t displayId, uint32_t policyFlags, int32_t action,
177 int32_t actionButton, int32_t flags, int32_t metaState,
178 int32_t buttonState, MotionClassification classification,
179 int32_t edgeFlags, float xPrecision, float yPrecision,
180 float xCursorPosition, float yCursorPosition, nsecs_t downTime,
181 uint32_t pointerCount, const PointerProperties* pointerProperties,
182 const PointerCoords* pointerCoords, float xOffset, float yOffset)
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700183 : EventEntry(sequenceNum, Type::MOTION, eventTime, policyFlags),
Garfield Tane84e6f92019-08-29 17:28:41 -0700184 eventTime(eventTime),
185 deviceId(deviceId),
186 source(source),
187 displayId(displayId),
188 action(action),
189 actionButton(actionButton),
190 flags(flags),
191 metaState(metaState),
192 buttonState(buttonState),
193 classification(classification),
194 edgeFlags(edgeFlags),
195 xPrecision(xPrecision),
196 yPrecision(yPrecision),
197 xCursorPosition(xCursorPosition),
198 yCursorPosition(yCursorPosition),
199 downTime(downTime),
200 pointerCount(pointerCount) {
201 for (uint32_t i = 0; i < pointerCount; i++) {
202 this->pointerProperties[i].copyFrom(pointerProperties[i]);
203 this->pointerCoords[i].copyFrom(pointerCoords[i]);
204 if (xOffset || yOffset) {
205 this->pointerCoords[i].applyOffset(xOffset, yOffset);
206 }
207 }
208}
209
210MotionEntry::~MotionEntry() {}
211
212void MotionEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700213 msg += StringPrintf("MotionEvent");
214 if (!GetBoolProperty("ro.debuggable", false)) {
215 return;
216 }
217 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tane84e6f92019-08-29 17:28:41 -0700218 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
219 "buttonState=0x%08x, "
220 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
221 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
222 deviceId, source, displayId, motionActionToString(action).c_str(),
223 actionButton, flags, metaState, buttonState,
224 motionClassificationToString(classification), edgeFlags, xPrecision,
225 yPrecision, xCursorPosition, yCursorPosition);
226
227 for (uint32_t i = 0; i < pointerCount; i++) {
228 if (i) {
229 msg += ", ";
230 }
231 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id, pointerCoords[i].getX(),
232 pointerCoords[i].getY());
233 }
234 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
235}
236
237// --- DispatchEntry ---
238
239volatile int32_t DispatchEntry::sNextSeqAtomic;
240
241DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset,
242 float yOffset, float globalScaleFactor, float windowXScale,
243 float windowYScale)
244 : seq(nextSeq()),
245 eventEntry(eventEntry),
246 targetFlags(targetFlags),
247 xOffset(xOffset),
248 yOffset(yOffset),
249 globalScaleFactor(globalScaleFactor),
250 windowXScale(windowXScale),
251 windowYScale(windowYScale),
252 deliveryTime(0),
253 resolvedAction(0),
254 resolvedFlags(0) {
255 eventEntry->refCount += 1;
256}
257
258DispatchEntry::~DispatchEntry() {
259 eventEntry->release();
260}
261
262uint32_t DispatchEntry::nextSeq() {
263 // Sequence number 0 is reserved and will never be returned.
264 uint32_t seq;
265 do {
266 seq = android_atomic_inc(&sNextSeqAtomic);
267 } while (!seq);
268 return seq;
269}
270
271// --- CommandEntry ---
272
273CommandEntry::CommandEntry(Command command)
274 : command(command),
275 eventTime(0),
276 keyEntry(nullptr),
277 userActivityEventType(0),
278 seq(0),
279 handled(false) {}
280
281CommandEntry::~CommandEntry() {}
282
283} // namespace android::inputdispatcher