blob: 930c7c77e76f4989270f96dc1f76da23fdcd32c6 [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
63EventEntry::EventEntry(uint32_t sequenceNum, int32_t type, nsecs_t eventTime, uint32_t policyFlags)
64 : 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)
95 : EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {}
96
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)
106 : EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0), deviceId(deviceId) {}
107
108DeviceResetEntry::~DeviceResetEntry() {}
109
110void DeviceResetEntry::appendDescription(std::string& msg) const {
111 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
112}
113
114// --- KeyEntry ---
115
116KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
117 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t flags,
118 int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
119 nsecs_t downTime)
120 : EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
121 deviceId(deviceId),
122 source(source),
123 displayId(displayId),
124 action(action),
125 flags(flags),
126 keyCode(keyCode),
127 scanCode(scanCode),
128 metaState(metaState),
129 repeatCount(repeatCount),
130 downTime(downTime),
131 syntheticRepeat(false),
132 interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
133 interceptKeyWakeupTime(0) {}
134
135KeyEntry::~KeyEntry() {}
136
137void KeyEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700138 msg += StringPrintf("KeyEvent");
139 if (!GetBoolProperty("ro.debuggable", false)) {
140 return;
141 }
142 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Garfield Tane84e6f92019-08-29 17:28:41 -0700143 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
144 "repeatCount=%d), policyFlags=0x%08x",
145 deviceId, source, displayId, keyActionToString(action).c_str(), flags,
146 keyCode, scanCode, metaState, repeatCount, policyFlags);
147}
148
149void KeyEntry::recycle() {
150 releaseInjectionState();
151
152 dispatchInProgress = false;
153 syntheticRepeat = false;
154 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
155 interceptKeyWakeupTime = 0;
156}
157
158// --- MotionEntry ---
159
160MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
161 int32_t displayId, uint32_t policyFlags, int32_t action,
162 int32_t actionButton, int32_t flags, int32_t metaState,
163 int32_t buttonState, MotionClassification classification,
164 int32_t edgeFlags, float xPrecision, float yPrecision,
165 float xCursorPosition, float yCursorPosition, nsecs_t downTime,
166 uint32_t pointerCount, const PointerProperties* pointerProperties,
167 const PointerCoords* pointerCoords, float xOffset, float yOffset)
168 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
169 eventTime(eventTime),
170 deviceId(deviceId),
171 source(source),
172 displayId(displayId),
173 action(action),
174 actionButton(actionButton),
175 flags(flags),
176 metaState(metaState),
177 buttonState(buttonState),
178 classification(classification),
179 edgeFlags(edgeFlags),
180 xPrecision(xPrecision),
181 yPrecision(yPrecision),
182 xCursorPosition(xCursorPosition),
183 yCursorPosition(yCursorPosition),
184 downTime(downTime),
185 pointerCount(pointerCount) {
186 for (uint32_t i = 0; i < pointerCount; i++) {
187 this->pointerProperties[i].copyFrom(pointerProperties[i]);
188 this->pointerCoords[i].copyFrom(pointerCoords[i]);
189 if (xOffset || yOffset) {
190 this->pointerCoords[i].applyOffset(xOffset, yOffset);
191 }
192 }
193}
194
195MotionEntry::~MotionEntry() {}
196
197void MotionEntry::appendDescription(std::string& msg) const {
Ashwini Orugantid399a522019-10-10 11:16:45 -0700198 msg += StringPrintf("MotionEvent");
199 if (!GetBoolProperty("ro.debuggable", false)) {
200 return;
201 }
202 msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tane84e6f92019-08-29 17:28:41 -0700203 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
204 "buttonState=0x%08x, "
205 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
206 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
207 deviceId, source, displayId, motionActionToString(action).c_str(),
208 actionButton, flags, metaState, buttonState,
209 motionClassificationToString(classification), edgeFlags, xPrecision,
210 yPrecision, xCursorPosition, yCursorPosition);
211
212 for (uint32_t i = 0; i < pointerCount; i++) {
213 if (i) {
214 msg += ", ";
215 }
216 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id, pointerCoords[i].getX(),
217 pointerCoords[i].getY());
218 }
219 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
220}
221
222// --- DispatchEntry ---
223
224volatile int32_t DispatchEntry::sNextSeqAtomic;
225
226DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset,
227 float yOffset, float globalScaleFactor, float windowXScale,
228 float windowYScale)
229 : seq(nextSeq()),
230 eventEntry(eventEntry),
231 targetFlags(targetFlags),
232 xOffset(xOffset),
233 yOffset(yOffset),
234 globalScaleFactor(globalScaleFactor),
235 windowXScale(windowXScale),
236 windowYScale(windowYScale),
237 deliveryTime(0),
238 resolvedAction(0),
239 resolvedFlags(0) {
240 eventEntry->refCount += 1;
241}
242
243DispatchEntry::~DispatchEntry() {
244 eventEntry->release();
245}
246
247uint32_t DispatchEntry::nextSeq() {
248 // Sequence number 0 is reserved and will never be returned.
249 uint32_t seq;
250 do {
251 seq = android_atomic_inc(&sNextSeqAtomic);
252 } while (!seq);
253 return seq;
254}
255
256// --- CommandEntry ---
257
258CommandEntry::CommandEntry(Command command)
259 : command(command),
260 eventTime(0),
261 keyEntry(nullptr),
262 userActivityEventType(0),
263 seq(0),
264 handled(false) {}
265
266CommandEntry::~CommandEntry() {}
267
268} // namespace android::inputdispatcher