blob: bff1b9776932fde6959500538ff1e3620b205171 [file] [log] [blame]
Jeff Brown5912f952013-07-01 19:10:31 -07001/*
2 * Copyright (C) 2010 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#define LOG_TAG "Input"
18//#define LOG_NDEBUG 0
19
Jeff Brown5912f952013-07-01 19:10:31 -070020#include <limits.h>
21
22#include <input/Input.h>
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080023#include <input/InputDevice.h>
Michael Wright872db4f2014-04-22 15:03:51 -070024#include <input/InputEventLabels.h>
Jeff Brown5912f952013-07-01 19:10:31 -070025
Elliott Hughes6071da72015-08-12 15:27:47 -070026#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -070027#include <binder/Parcel.h>
Jeff Brown5912f952013-07-01 19:10:31 -070028#endif
29
30namespace android {
31
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -080032const char* motionClassificationToString(MotionClassification classification) {
33 switch (classification) {
34 case MotionClassification::NONE:
35 return "NONE";
36 case MotionClassification::AMBIGUOUS_GESTURE:
37 return "AMBIGUOUS_GESTURE";
38 case MotionClassification::DEEP_PRESS:
39 return "DEEP_PRESS";
40 }
41}
42
Jeff Brown5912f952013-07-01 19:10:31 -070043// --- InputEvent ---
44
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080045const char* inputEventTypeToString(int32_t type) {
46 switch (type) {
47 case AINPUT_EVENT_TYPE_KEY: {
48 return "KEY";
49 }
50 case AINPUT_EVENT_TYPE_MOTION: {
51 return "MOTION";
52 }
53 case AINPUT_EVENT_TYPE_FOCUS: {
54 return "FOCUS";
55 }
56 }
57 return "UNKNOWN";
58}
59
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -060060void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId,
61 std::array<uint8_t, 32> hmac) {
Jeff Brown5912f952013-07-01 19:10:31 -070062 mDeviceId = deviceId;
63 mSource = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010064 mDisplayId = displayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -060065 mHmac = hmac;
Jeff Brown5912f952013-07-01 19:10:31 -070066}
67
68void InputEvent::initialize(const InputEvent& from) {
69 mDeviceId = from.mDeviceId;
70 mSource = from.mSource;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010071 mDisplayId = from.mDisplayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -060072 mHmac = from.mHmac;
Jeff Brown5912f952013-07-01 19:10:31 -070073}
74
75// --- KeyEvent ---
76
Michael Wright872db4f2014-04-22 15:03:51 -070077const char* KeyEvent::getLabel(int32_t keyCode) {
78 return getLabelByKeyCode(keyCode);
Jeff Brown5912f952013-07-01 19:10:31 -070079}
80
Michael Wright872db4f2014-04-22 15:03:51 -070081int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
82 return getKeyCodeByLabel(label);
Jeff Brown5912f952013-07-01 19:10:31 -070083}
84
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -060085void KeyEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId,
86 std::array<uint8_t, 32> hmac, int32_t action, int32_t flags,
87 int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
88 nsecs_t downTime, nsecs_t eventTime) {
89 InputEvent::initialize(deviceId, source, displayId, hmac);
Jeff Brown5912f952013-07-01 19:10:31 -070090 mAction = action;
91 mFlags = flags;
92 mKeyCode = keyCode;
93 mScanCode = scanCode;
94 mMetaState = metaState;
95 mRepeatCount = repeatCount;
96 mDownTime = downTime;
97 mEventTime = eventTime;
98}
99
100void KeyEvent::initialize(const KeyEvent& from) {
101 InputEvent::initialize(from);
102 mAction = from.mAction;
103 mFlags = from.mFlags;
104 mKeyCode = from.mKeyCode;
105 mScanCode = from.mScanCode;
106 mMetaState = from.mMetaState;
107 mRepeatCount = from.mRepeatCount;
108 mDownTime = from.mDownTime;
109 mEventTime = from.mEventTime;
110}
111
112
113// --- PointerCoords ---
114
115float PointerCoords::getAxisValue(int32_t axis) const {
Michael Wright38dcdff2014-03-19 12:06:10 -0700116 if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
Jeff Brown5912f952013-07-01 19:10:31 -0700117 return 0;
118 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700119 return values[BitSet64::getIndexOfBit(bits, axis)];
Jeff Brown5912f952013-07-01 19:10:31 -0700120}
121
122status_t PointerCoords::setAxisValue(int32_t axis, float value) {
123 if (axis < 0 || axis > 63) {
124 return NAME_NOT_FOUND;
125 }
126
Michael Wright38dcdff2014-03-19 12:06:10 -0700127 uint32_t index = BitSet64::getIndexOfBit(bits, axis);
128 if (!BitSet64::hasBit(bits, axis)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700129 if (value == 0) {
130 return OK; // axes with value 0 do not need to be stored
131 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700132
133 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700134 if (count >= MAX_AXES) {
135 tooManyAxes(axis);
136 return NO_MEMORY;
137 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700138 BitSet64::markBit(bits, axis);
Jeff Brown5912f952013-07-01 19:10:31 -0700139 for (uint32_t i = count; i > index; i--) {
140 values[i] = values[i - 1];
141 }
142 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700143
Jeff Brown5912f952013-07-01 19:10:31 -0700144 values[index] = value;
145 return OK;
146}
147
148static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
149 float value = c.getAxisValue(axis);
150 if (value != 0) {
151 c.setAxisValue(axis, value * scaleFactor);
152 }
153}
154
Robert Carre07e1032018-11-26 12:55:53 -0800155void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
Jeff Brown5912f952013-07-01 19:10:31 -0700156 // No need to scale pressure or size since they are normalized.
157 // No need to scale orientation since it is meaningless to do so.
Robert Carre07e1032018-11-26 12:55:53 -0800158
159 // If there is a global scale factor, it is included in the windowX/YScale
160 // so we don't need to apply it twice to the X/Y axes.
161 // However we don't want to apply any windowXYScale not included in the global scale
162 // to the TOUCH_MAJOR/MINOR coordinates.
163 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
164 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
165 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
166 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
167 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
168 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
169}
170
171void PointerCoords::scale(float globalScaleFactor) {
172 scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700173}
174
Jeff Brownf086ddb2014-02-11 14:28:48 -0800175void PointerCoords::applyOffset(float xOffset, float yOffset) {
176 setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
177 setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
178}
179
Elliott Hughes6071da72015-08-12 15:27:47 -0700180#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700181status_t PointerCoords::readFromParcel(Parcel* parcel) {
182 bits = parcel->readInt64();
183
Michael Wright38dcdff2014-03-19 12:06:10 -0700184 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700185 if (count > MAX_AXES) {
186 return BAD_VALUE;
187 }
188
189 for (uint32_t i = 0; i < count; i++) {
190 values[i] = parcel->readFloat();
191 }
192 return OK;
193}
194
195status_t PointerCoords::writeToParcel(Parcel* parcel) const {
196 parcel->writeInt64(bits);
197
Michael Wright38dcdff2014-03-19 12:06:10 -0700198 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700199 for (uint32_t i = 0; i < count; i++) {
200 parcel->writeFloat(values[i]);
201 }
202 return OK;
203}
204#endif
205
206void PointerCoords::tooManyAxes(int axis) {
207 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
208 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
209}
210
211bool PointerCoords::operator==(const PointerCoords& other) const {
212 if (bits != other.bits) {
213 return false;
214 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700215 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700216 for (uint32_t i = 0; i < count; i++) {
217 if (values[i] != other.values[i]) {
218 return false;
219 }
220 }
221 return true;
222}
223
224void PointerCoords::copyFrom(const PointerCoords& other) {
225 bits = other.bits;
Michael Wright38dcdff2014-03-19 12:06:10 -0700226 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700227 for (uint32_t i = 0; i < count; i++) {
228 values[i] = other.values[i];
229 }
230}
231
232
233// --- PointerProperties ---
234
235bool PointerProperties::operator==(const PointerProperties& other) const {
236 return id == other.id
237 && toolType == other.toolType;
238}
239
240void PointerProperties::copyFrom(const PointerProperties& other) {
241 id = other.id;
242 toolType = other.toolType;
243}
244
245
246// --- MotionEvent ---
247
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600248void MotionEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId,
249 std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
250 int32_t flags, int32_t edgeFlags, int32_t metaState,
251 int32_t buttonState, MotionClassification classification, float xScale,
252 float yScale, float xOffset, float yOffset, float xPrecision,
253 float yPrecision, float rawXCursorPosition, float rawYCursorPosition,
254 nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
255 const PointerProperties* pointerProperties,
Garfield Tan00f511d2019-06-12 16:55:40 -0700256 const PointerCoords* pointerCoords) {
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600257 InputEvent::initialize(deviceId, source, displayId, hmac);
Jeff Brown5912f952013-07-01 19:10:31 -0700258 mAction = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100259 mActionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700260 mFlags = flags;
261 mEdgeFlags = edgeFlags;
262 mMetaState = metaState;
263 mButtonState = buttonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800264 mClassification = classification;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600265 mXScale = xScale;
266 mYScale = yScale;
Jeff Brown5912f952013-07-01 19:10:31 -0700267 mXOffset = xOffset;
268 mYOffset = yOffset;
269 mXPrecision = xPrecision;
270 mYPrecision = yPrecision;
Garfield Tan937bb832019-07-25 17:48:31 -0700271 mRawXCursorPosition = rawXCursorPosition;
272 mRawYCursorPosition = rawYCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700273 mDownTime = downTime;
274 mPointerProperties.clear();
275 mPointerProperties.appendArray(pointerProperties, pointerCount);
276 mSampleEventTimes.clear();
277 mSamplePointerCoords.clear();
278 addSample(eventTime, pointerCoords);
279}
280
281void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600282 InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId, other->mHmac);
Jeff Brown5912f952013-07-01 19:10:31 -0700283 mAction = other->mAction;
Michael Wright7b159c92015-05-14 14:48:03 +0100284 mActionButton = other->mActionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700285 mFlags = other->mFlags;
286 mEdgeFlags = other->mEdgeFlags;
287 mMetaState = other->mMetaState;
288 mButtonState = other->mButtonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800289 mClassification = other->mClassification;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600290 mXScale = other->mXScale;
291 mYScale = other->mYScale;
Jeff Brown5912f952013-07-01 19:10:31 -0700292 mXOffset = other->mXOffset;
293 mYOffset = other->mYOffset;
294 mXPrecision = other->mXPrecision;
295 mYPrecision = other->mYPrecision;
Garfield Tan937bb832019-07-25 17:48:31 -0700296 mRawXCursorPosition = other->mRawXCursorPosition;
297 mRawYCursorPosition = other->mRawYCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700298 mDownTime = other->mDownTime;
299 mPointerProperties = other->mPointerProperties;
300
301 if (keepHistory) {
302 mSampleEventTimes = other->mSampleEventTimes;
303 mSamplePointerCoords = other->mSamplePointerCoords;
304 } else {
305 mSampleEventTimes.clear();
306 mSampleEventTimes.push(other->getEventTime());
307 mSamplePointerCoords.clear();
308 size_t pointerCount = other->getPointerCount();
309 size_t historySize = other->getHistorySize();
310 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
311 + (historySize * pointerCount), pointerCount);
312 }
313}
314
315void MotionEvent::addSample(
316 int64_t eventTime,
317 const PointerCoords* pointerCoords) {
318 mSampleEventTimes.push(eventTime);
319 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
320}
321
Garfield Tan00f511d2019-06-12 16:55:40 -0700322float MotionEvent::getXCursorPosition() const {
323 const float rawX = getRawXCursorPosition();
324 return rawX + mXOffset;
325}
326
327float MotionEvent::getYCursorPosition() const {
328 const float rawY = getRawYCursorPosition();
329 return rawY + mYOffset;
330}
331
Garfield Tan937bb832019-07-25 17:48:31 -0700332void MotionEvent::setCursorPosition(float x, float y) {
333 mRawXCursorPosition = x - mXOffset;
334 mRawYCursorPosition = y - mYOffset;
335}
336
Jeff Brown5912f952013-07-01 19:10:31 -0700337const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
338 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
339}
340
341float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
342 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
343}
344
345float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
346 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
347 switch (axis) {
348 case AMOTION_EVENT_AXIS_X:
349 return value + mXOffset;
350 case AMOTION_EVENT_AXIS_Y:
351 return value + mYOffset;
352 }
353 return value;
354}
355
356const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
357 size_t pointerIndex, size_t historicalIndex) const {
358 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
359}
360
361float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
362 size_t historicalIndex) const {
363 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
364}
365
366float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
367 size_t historicalIndex) const {
368 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
369 switch (axis) {
370 case AMOTION_EVENT_AXIS_X:
371 return value + mXOffset;
372 case AMOTION_EVENT_AXIS_Y:
373 return value + mYOffset;
374 }
375 return value;
376}
377
378ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
379 size_t pointerCount = mPointerProperties.size();
380 for (size_t i = 0; i < pointerCount; i++) {
381 if (mPointerProperties.itemAt(i).id == pointerId) {
382 return i;
383 }
384 }
385 return -1;
386}
387
388void MotionEvent::offsetLocation(float xOffset, float yOffset) {
389 mXOffset += xOffset;
390 mYOffset += yOffset;
391}
392
Robert Carre07e1032018-11-26 12:55:53 -0800393void MotionEvent::scale(float globalScaleFactor) {
394 mXOffset *= globalScaleFactor;
395 mYOffset *= globalScaleFactor;
396 mXPrecision *= globalScaleFactor;
397 mYPrecision *= globalScaleFactor;
Jeff Brown5912f952013-07-01 19:10:31 -0700398
399 size_t numSamples = mSamplePointerCoords.size();
400 for (size_t i = 0; i < numSamples; i++) {
Robert Carre07e1032018-11-26 12:55:53 -0800401 mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700402 }
403}
404
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700405static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
406 // Apply perspective transform like Skia.
407 float newX = matrix[0] * x + matrix[1] * y + matrix[2];
408 float newY = matrix[3] * x + matrix[4] * y + matrix[5];
409 float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
410 if (newZ) {
411 newZ = 1.0f / newZ;
412 }
413 *outX = newX * newZ;
414 *outY = newY * newZ;
415}
416
417static float transformAngle(const float matrix[9], float angleRadians,
418 float originX, float originY) {
Jeff Brown5912f952013-07-01 19:10:31 -0700419 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
420 // Coordinate system: down is increasing Y, right is increasing X.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700421 float x = sinf(angleRadians);
422 float y = -cosf(angleRadians);
423 transformPoint(matrix, x, y, &x, &y);
424 x -= originX;
425 y -= originY;
Jeff Brown5912f952013-07-01 19:10:31 -0700426
427 // Derive the transformed vector's clockwise angle from vertical.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700428 float result = atan2f(x, -y);
Jeff Brown5912f952013-07-01 19:10:31 -0700429 if (result < - M_PI_2) {
430 result += M_PI;
431 } else if (result > M_PI_2) {
432 result -= M_PI;
433 }
434 return result;
435}
436
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700437void MotionEvent::transform(const float matrix[9]) {
Jeff Brown5912f952013-07-01 19:10:31 -0700438 // The tricky part of this implementation is to preserve the value of
439 // rawX and rawY. So we apply the transformation to the first point
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700440 // then derive an appropriate new X/Y offset that will preserve rawX
441 // and rawY for that point.
442 float oldXOffset = mXOffset;
443 float oldYOffset = mYOffset;
444 float newX, newY;
Jeff Brown5912f952013-07-01 19:10:31 -0700445 float rawX = getRawX(0);
446 float rawY = getRawY(0);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700447 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
448 mXOffset = newX - rawX;
449 mYOffset = newY - rawY;
Jeff Brown5912f952013-07-01 19:10:31 -0700450
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700451 // Determine how the origin is transformed by the matrix so that we
452 // can transform orientation vectors.
453 float originX, originY;
454 transformPoint(matrix, 0, 0, &originX, &originY);
Jeff Brown5912f952013-07-01 19:10:31 -0700455
Garfield Tan00f511d2019-06-12 16:55:40 -0700456 // Apply the transformation to cursor position.
Garfield Tan937bb832019-07-25 17:48:31 -0700457 if (isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) {
458 float x = mRawXCursorPosition + oldXOffset;
459 float y = mRawYCursorPosition + oldYOffset;
Garfield Tan00f511d2019-06-12 16:55:40 -0700460 transformPoint(matrix, x, y, &x, &y);
Garfield Tan937bb832019-07-25 17:48:31 -0700461 mRawXCursorPosition = x - mXOffset;
462 mRawYCursorPosition = y - mYOffset;
Garfield Tan00f511d2019-06-12 16:55:40 -0700463 }
464
Jeff Brown5912f952013-07-01 19:10:31 -0700465 // Apply the transformation to all samples.
466 size_t numSamples = mSamplePointerCoords.size();
467 for (size_t i = 0; i < numSamples; i++) {
468 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
469 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
470 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700471 transformPoint(matrix, x, y, &x, &y);
472 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
473 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
Jeff Brown5912f952013-07-01 19:10:31 -0700474
475 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700476 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
477 transformAngle(matrix, orientation, originX, originY));
Jeff Brown5912f952013-07-01 19:10:31 -0700478 }
479}
480
Elliott Hughes6071da72015-08-12 15:27:47 -0700481#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700482status_t MotionEvent::readFromParcel(Parcel* parcel) {
483 size_t pointerCount = parcel->readInt32();
484 size_t sampleCount = parcel->readInt32();
Flanker552a8a52015-09-07 15:28:58 +0800485 if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
486 sampleCount == 0 || sampleCount > MAX_SAMPLES) {
Jeff Brown5912f952013-07-01 19:10:31 -0700487 return BAD_VALUE;
488 }
489
490 mDeviceId = parcel->readInt32();
491 mSource = parcel->readInt32();
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800492 mDisplayId = parcel->readInt32();
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600493 std::vector<uint8_t> hmac;
494 status_t result = parcel->readByteVector(&hmac);
495 if (result != OK || hmac.size() != 32) {
496 return BAD_VALUE;
497 }
498 std::move(hmac.begin(), hmac.begin() + hmac.size(), mHmac.begin());
Jeff Brown5912f952013-07-01 19:10:31 -0700499 mAction = parcel->readInt32();
Michael Wright7b159c92015-05-14 14:48:03 +0100500 mActionButton = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700501 mFlags = parcel->readInt32();
502 mEdgeFlags = parcel->readInt32();
503 mMetaState = parcel->readInt32();
504 mButtonState = parcel->readInt32();
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800505 mClassification = static_cast<MotionClassification>(parcel->readByte());
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600506 mXScale = parcel->readFloat();
507 mYScale = parcel->readFloat();
Jeff Brown5912f952013-07-01 19:10:31 -0700508 mXOffset = parcel->readFloat();
509 mYOffset = parcel->readFloat();
510 mXPrecision = parcel->readFloat();
511 mYPrecision = parcel->readFloat();
Garfield Tan937bb832019-07-25 17:48:31 -0700512 mRawXCursorPosition = parcel->readFloat();
513 mRawYCursorPosition = parcel->readFloat();
Jeff Brown5912f952013-07-01 19:10:31 -0700514 mDownTime = parcel->readInt64();
515
516 mPointerProperties.clear();
517 mPointerProperties.setCapacity(pointerCount);
518 mSampleEventTimes.clear();
519 mSampleEventTimes.setCapacity(sampleCount);
520 mSamplePointerCoords.clear();
521 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
522
523 for (size_t i = 0; i < pointerCount; i++) {
524 mPointerProperties.push();
525 PointerProperties& properties = mPointerProperties.editTop();
526 properties.id = parcel->readInt32();
527 properties.toolType = parcel->readInt32();
528 }
529
Dan Austinc94fc452015-09-22 14:22:41 -0700530 while (sampleCount > 0) {
531 sampleCount--;
Jeff Brown5912f952013-07-01 19:10:31 -0700532 mSampleEventTimes.push(parcel->readInt64());
533 for (size_t i = 0; i < pointerCount; i++) {
534 mSamplePointerCoords.push();
535 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
536 if (status) {
537 return status;
538 }
539 }
540 }
541 return OK;
542}
543
544status_t MotionEvent::writeToParcel(Parcel* parcel) const {
545 size_t pointerCount = mPointerProperties.size();
546 size_t sampleCount = mSampleEventTimes.size();
547
548 parcel->writeInt32(pointerCount);
549 parcel->writeInt32(sampleCount);
550
551 parcel->writeInt32(mDeviceId);
552 parcel->writeInt32(mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800553 parcel->writeInt32(mDisplayId);
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600554 std::vector<uint8_t> hmac(mHmac.begin(), mHmac.end());
555 parcel->writeByteVector(hmac);
Jeff Brown5912f952013-07-01 19:10:31 -0700556 parcel->writeInt32(mAction);
Michael Wright7b159c92015-05-14 14:48:03 +0100557 parcel->writeInt32(mActionButton);
Jeff Brown5912f952013-07-01 19:10:31 -0700558 parcel->writeInt32(mFlags);
559 parcel->writeInt32(mEdgeFlags);
560 parcel->writeInt32(mMetaState);
561 parcel->writeInt32(mButtonState);
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800562 parcel->writeByte(static_cast<int8_t>(mClassification));
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600563 parcel->writeFloat(mXScale);
564 parcel->writeFloat(mYScale);
Jeff Brown5912f952013-07-01 19:10:31 -0700565 parcel->writeFloat(mXOffset);
566 parcel->writeFloat(mYOffset);
567 parcel->writeFloat(mXPrecision);
568 parcel->writeFloat(mYPrecision);
Garfield Tan937bb832019-07-25 17:48:31 -0700569 parcel->writeFloat(mRawXCursorPosition);
570 parcel->writeFloat(mRawYCursorPosition);
Jeff Brown5912f952013-07-01 19:10:31 -0700571 parcel->writeInt64(mDownTime);
572
573 for (size_t i = 0; i < pointerCount; i++) {
574 const PointerProperties& properties = mPointerProperties.itemAt(i);
575 parcel->writeInt32(properties.id);
576 parcel->writeInt32(properties.toolType);
577 }
578
579 const PointerCoords* pc = mSamplePointerCoords.array();
580 for (size_t h = 0; h < sampleCount; h++) {
581 parcel->writeInt64(mSampleEventTimes.itemAt(h));
582 for (size_t i = 0; i < pointerCount; i++) {
583 status_t status = (pc++)->writeToParcel(parcel);
584 if (status) {
585 return status;
586 }
587 }
588 }
589 return OK;
590}
591#endif
592
593bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
594 if (source & AINPUT_SOURCE_CLASS_POINTER) {
595 // Specifically excludes HOVER_MOVE and SCROLL.
596 switch (action & AMOTION_EVENT_ACTION_MASK) {
597 case AMOTION_EVENT_ACTION_DOWN:
598 case AMOTION_EVENT_ACTION_MOVE:
599 case AMOTION_EVENT_ACTION_UP:
600 case AMOTION_EVENT_ACTION_POINTER_DOWN:
601 case AMOTION_EVENT_ACTION_POINTER_UP:
602 case AMOTION_EVENT_ACTION_CANCEL:
603 case AMOTION_EVENT_ACTION_OUTSIDE:
604 return true;
605 }
606 }
607 return false;
608}
609
Michael Wright872db4f2014-04-22 15:03:51 -0700610const char* MotionEvent::getLabel(int32_t axis) {
611 return getAxisLabel(axis);
612}
613
614int32_t MotionEvent::getAxisFromLabel(const char* label) {
615 return getAxisByLabel(label);
616}
617
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800618// --- FocusEvent ---
619
620void FocusEvent::initialize(bool hasFocus, bool inTouchMode) {
621 InputEvent::initialize(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600622 ADISPLAY_ID_NONE, INVALID_HMAC);
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800623 mHasFocus = hasFocus;
624 mInTouchMode = inTouchMode;
625}
626
627void FocusEvent::initialize(const FocusEvent& from) {
628 InputEvent::initialize(from);
629 mHasFocus = from.mHasFocus;
630 mInTouchMode = from.mInTouchMode;
631}
Jeff Brown5912f952013-07-01 19:10:31 -0700632
633// --- PooledInputEventFactory ---
634
635PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
636 mMaxPoolSize(maxPoolSize) {
637}
638
639PooledInputEventFactory::~PooledInputEventFactory() {
Jeff Brown5912f952013-07-01 19:10:31 -0700640}
641
642KeyEvent* PooledInputEventFactory::createKeyEvent() {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800643 if (mKeyEventPool.empty()) {
644 return new KeyEvent();
Jeff Brown5912f952013-07-01 19:10:31 -0700645 }
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800646 KeyEvent* event = mKeyEventPool.front().release();
647 mKeyEventPool.pop();
648 return event;
Jeff Brown5912f952013-07-01 19:10:31 -0700649}
650
651MotionEvent* PooledInputEventFactory::createMotionEvent() {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800652 if (mMotionEventPool.empty()) {
653 return new MotionEvent();
Jeff Brown5912f952013-07-01 19:10:31 -0700654 }
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800655 MotionEvent* event = mMotionEventPool.front().release();
656 mMotionEventPool.pop();
657 return event;
Jeff Brown5912f952013-07-01 19:10:31 -0700658}
659
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800660FocusEvent* PooledInputEventFactory::createFocusEvent() {
661 if (mFocusEventPool.empty()) {
662 return new FocusEvent();
663 }
664 FocusEvent* event = mFocusEventPool.front().release();
665 mFocusEventPool.pop();
666 return event;
667}
668
Jeff Brown5912f952013-07-01 19:10:31 -0700669void PooledInputEventFactory::recycle(InputEvent* event) {
670 switch (event->getType()) {
671 case AINPUT_EVENT_TYPE_KEY:
672 if (mKeyEventPool.size() < mMaxPoolSize) {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800673 mKeyEventPool.push(std::unique_ptr<KeyEvent>(static_cast<KeyEvent*>(event)));
Jeff Brown5912f952013-07-01 19:10:31 -0700674 return;
675 }
676 break;
677 case AINPUT_EVENT_TYPE_MOTION:
678 if (mMotionEventPool.size() < mMaxPoolSize) {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800679 mMotionEventPool.push(std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event)));
Jeff Brown5912f952013-07-01 19:10:31 -0700680 return;
681 }
682 break;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800683 case AINPUT_EVENT_TYPE_FOCUS:
684 if (mFocusEventPool.size() < mMaxPoolSize) {
685 mFocusEventPool.push(std::unique_ptr<FocusEvent>(static_cast<FocusEvent*>(event)));
686 return;
687 }
688 break;
Jeff Brown5912f952013-07-01 19:10:31 -0700689 }
690 delete event;
691}
692
693} // namespace android