blob: 3266b0740d1bd2dfe15ee01c3680b40ebc89858c [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
20#include <math.h>
21#include <limits.h>
22
23#include <input/Input.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 Vishniakoua62a8dd2018-06-08 21:17:33 +010045void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
Jeff Brown5912f952013-07-01 19:10:31 -070046 mDeviceId = deviceId;
47 mSource = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010048 mDisplayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -070049}
50
51void InputEvent::initialize(const InputEvent& from) {
52 mDeviceId = from.mDeviceId;
53 mSource = from.mSource;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010054 mDisplayId = from.mDisplayId;
Jeff Brown5912f952013-07-01 19:10:31 -070055}
56
57// --- KeyEvent ---
58
Michael Wright872db4f2014-04-22 15:03:51 -070059const char* KeyEvent::getLabel(int32_t keyCode) {
60 return getLabelByKeyCode(keyCode);
Jeff Brown5912f952013-07-01 19:10:31 -070061}
62
Michael Wright872db4f2014-04-22 15:03:51 -070063int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
64 return getKeyCodeByLabel(label);
Jeff Brown5912f952013-07-01 19:10:31 -070065}
66
67void KeyEvent::initialize(
68 int32_t deviceId,
69 int32_t source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010070 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -070071 int32_t action,
72 int32_t flags,
73 int32_t keyCode,
74 int32_t scanCode,
75 int32_t metaState,
76 int32_t repeatCount,
77 nsecs_t downTime,
78 nsecs_t eventTime) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010079 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -070080 mAction = action;
81 mFlags = flags;
82 mKeyCode = keyCode;
83 mScanCode = scanCode;
84 mMetaState = metaState;
85 mRepeatCount = repeatCount;
86 mDownTime = downTime;
87 mEventTime = eventTime;
88}
89
90void KeyEvent::initialize(const KeyEvent& from) {
91 InputEvent::initialize(from);
92 mAction = from.mAction;
93 mFlags = from.mFlags;
94 mKeyCode = from.mKeyCode;
95 mScanCode = from.mScanCode;
96 mMetaState = from.mMetaState;
97 mRepeatCount = from.mRepeatCount;
98 mDownTime = from.mDownTime;
99 mEventTime = from.mEventTime;
100}
101
102
103// --- PointerCoords ---
104
105float PointerCoords::getAxisValue(int32_t axis) const {
Michael Wright38dcdff2014-03-19 12:06:10 -0700106 if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
Jeff Brown5912f952013-07-01 19:10:31 -0700107 return 0;
108 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700109 return values[BitSet64::getIndexOfBit(bits, axis)];
Jeff Brown5912f952013-07-01 19:10:31 -0700110}
111
112status_t PointerCoords::setAxisValue(int32_t axis, float value) {
113 if (axis < 0 || axis > 63) {
114 return NAME_NOT_FOUND;
115 }
116
Michael Wright38dcdff2014-03-19 12:06:10 -0700117 uint32_t index = BitSet64::getIndexOfBit(bits, axis);
118 if (!BitSet64::hasBit(bits, axis)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700119 if (value == 0) {
120 return OK; // axes with value 0 do not need to be stored
121 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700122
123 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700124 if (count >= MAX_AXES) {
125 tooManyAxes(axis);
126 return NO_MEMORY;
127 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700128 BitSet64::markBit(bits, axis);
Jeff Brown5912f952013-07-01 19:10:31 -0700129 for (uint32_t i = count; i > index; i--) {
130 values[i] = values[i - 1];
131 }
132 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700133
Jeff Brown5912f952013-07-01 19:10:31 -0700134 values[index] = value;
135 return OK;
136}
137
138static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
139 float value = c.getAxisValue(axis);
140 if (value != 0) {
141 c.setAxisValue(axis, value * scaleFactor);
142 }
143}
144
Robert Carre07e1032018-11-26 12:55:53 -0800145void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
Jeff Brown5912f952013-07-01 19:10:31 -0700146 // No need to scale pressure or size since they are normalized.
147 // No need to scale orientation since it is meaningless to do so.
Robert Carre07e1032018-11-26 12:55:53 -0800148
149 // If there is a global scale factor, it is included in the windowX/YScale
150 // so we don't need to apply it twice to the X/Y axes.
151 // However we don't want to apply any windowXYScale not included in the global scale
152 // to the TOUCH_MAJOR/MINOR coordinates.
153 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
154 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
155 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
156 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
157 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
158 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
159}
160
161void PointerCoords::scale(float globalScaleFactor) {
162 scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700163}
164
Jeff Brownf086ddb2014-02-11 14:28:48 -0800165void PointerCoords::applyOffset(float xOffset, float yOffset) {
166 setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
167 setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
168}
169
Elliott Hughes6071da72015-08-12 15:27:47 -0700170#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700171status_t PointerCoords::readFromParcel(Parcel* parcel) {
172 bits = parcel->readInt64();
173
Michael Wright38dcdff2014-03-19 12:06:10 -0700174 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700175 if (count > MAX_AXES) {
176 return BAD_VALUE;
177 }
178
179 for (uint32_t i = 0; i < count; i++) {
180 values[i] = parcel->readFloat();
181 }
182 return OK;
183}
184
185status_t PointerCoords::writeToParcel(Parcel* parcel) const {
186 parcel->writeInt64(bits);
187
Michael Wright38dcdff2014-03-19 12:06:10 -0700188 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700189 for (uint32_t i = 0; i < count; i++) {
190 parcel->writeFloat(values[i]);
191 }
192 return OK;
193}
194#endif
195
196void PointerCoords::tooManyAxes(int axis) {
197 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
198 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
199}
200
201bool PointerCoords::operator==(const PointerCoords& other) const {
202 if (bits != other.bits) {
203 return false;
204 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700205 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700206 for (uint32_t i = 0; i < count; i++) {
207 if (values[i] != other.values[i]) {
208 return false;
209 }
210 }
211 return true;
212}
213
214void PointerCoords::copyFrom(const PointerCoords& other) {
215 bits = other.bits;
Michael Wright38dcdff2014-03-19 12:06:10 -0700216 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700217 for (uint32_t i = 0; i < count; i++) {
218 values[i] = other.values[i];
219 }
220}
221
222
223// --- PointerProperties ---
224
225bool PointerProperties::operator==(const PointerProperties& other) const {
226 return id == other.id
227 && toolType == other.toolType;
228}
229
230void PointerProperties::copyFrom(const PointerProperties& other) {
231 id = other.id;
232 toolType = other.toolType;
233}
234
235
236// --- MotionEvent ---
237
Garfield Tan00f511d2019-06-12 16:55:40 -0700238void MotionEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
239 int32_t actionButton, int32_t flags, int32_t edgeFlags,
240 int32_t metaState, int32_t buttonState,
241 MotionClassification classification, float xOffset, float yOffset,
242 float xPrecision, float yPrecision, float xCursorPosition,
243 float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
244 size_t pointerCount, const PointerProperties* pointerProperties,
245 const PointerCoords* pointerCoords) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100246 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700247 mAction = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100248 mActionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700249 mFlags = flags;
250 mEdgeFlags = edgeFlags;
251 mMetaState = metaState;
252 mButtonState = buttonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800253 mClassification = classification;
Jeff Brown5912f952013-07-01 19:10:31 -0700254 mXOffset = xOffset;
255 mYOffset = yOffset;
256 mXPrecision = xPrecision;
257 mYPrecision = yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700258 mXCursorPosition = xCursorPosition;
259 mYCursorPosition = yCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700260 mDownTime = downTime;
261 mPointerProperties.clear();
262 mPointerProperties.appendArray(pointerProperties, pointerCount);
263 mSampleEventTimes.clear();
264 mSamplePointerCoords.clear();
265 addSample(eventTime, pointerCoords);
266}
267
268void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100269 InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700270 mAction = other->mAction;
Michael Wright7b159c92015-05-14 14:48:03 +0100271 mActionButton = other->mActionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700272 mFlags = other->mFlags;
273 mEdgeFlags = other->mEdgeFlags;
274 mMetaState = other->mMetaState;
275 mButtonState = other->mButtonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800276 mClassification = other->mClassification;
Jeff Brown5912f952013-07-01 19:10:31 -0700277 mXOffset = other->mXOffset;
278 mYOffset = other->mYOffset;
279 mXPrecision = other->mXPrecision;
280 mYPrecision = other->mYPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700281 mXCursorPosition = other->mXCursorPosition;
282 mYCursorPosition = other->mYCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700283 mDownTime = other->mDownTime;
284 mPointerProperties = other->mPointerProperties;
285
286 if (keepHistory) {
287 mSampleEventTimes = other->mSampleEventTimes;
288 mSamplePointerCoords = other->mSamplePointerCoords;
289 } else {
290 mSampleEventTimes.clear();
291 mSampleEventTimes.push(other->getEventTime());
292 mSamplePointerCoords.clear();
293 size_t pointerCount = other->getPointerCount();
294 size_t historySize = other->getHistorySize();
295 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
296 + (historySize * pointerCount), pointerCount);
297 }
298}
299
300void MotionEvent::addSample(
301 int64_t eventTime,
302 const PointerCoords* pointerCoords) {
303 mSampleEventTimes.push(eventTime);
304 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
305}
306
Garfield Tan00f511d2019-06-12 16:55:40 -0700307float MotionEvent::getXCursorPosition() const {
308 const float rawX = getRawXCursorPosition();
309 return rawX + mXOffset;
310}
311
312float MotionEvent::getYCursorPosition() const {
313 const float rawY = getRawYCursorPosition();
314 return rawY + mYOffset;
315}
316
Jeff Brown5912f952013-07-01 19:10:31 -0700317const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
318 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
319}
320
321float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
322 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
323}
324
325float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
326 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
327 switch (axis) {
328 case AMOTION_EVENT_AXIS_X:
329 return value + mXOffset;
330 case AMOTION_EVENT_AXIS_Y:
331 return value + mYOffset;
332 }
333 return value;
334}
335
336const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
337 size_t pointerIndex, size_t historicalIndex) const {
338 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
339}
340
341float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
342 size_t historicalIndex) const {
343 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
344}
345
346float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
347 size_t historicalIndex) const {
348 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
349 switch (axis) {
350 case AMOTION_EVENT_AXIS_X:
351 return value + mXOffset;
352 case AMOTION_EVENT_AXIS_Y:
353 return value + mYOffset;
354 }
355 return value;
356}
357
358ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
359 size_t pointerCount = mPointerProperties.size();
360 for (size_t i = 0; i < pointerCount; i++) {
361 if (mPointerProperties.itemAt(i).id == pointerId) {
362 return i;
363 }
364 }
365 return -1;
366}
367
368void MotionEvent::offsetLocation(float xOffset, float yOffset) {
369 mXOffset += xOffset;
370 mYOffset += yOffset;
371}
372
Robert Carre07e1032018-11-26 12:55:53 -0800373void MotionEvent::scale(float globalScaleFactor) {
374 mXOffset *= globalScaleFactor;
375 mYOffset *= globalScaleFactor;
376 mXPrecision *= globalScaleFactor;
377 mYPrecision *= globalScaleFactor;
Jeff Brown5912f952013-07-01 19:10:31 -0700378
379 size_t numSamples = mSamplePointerCoords.size();
380 for (size_t i = 0; i < numSamples; i++) {
Robert Carre07e1032018-11-26 12:55:53 -0800381 mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700382 }
383}
384
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700385static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
386 // Apply perspective transform like Skia.
387 float newX = matrix[0] * x + matrix[1] * y + matrix[2];
388 float newY = matrix[3] * x + matrix[4] * y + matrix[5];
389 float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
390 if (newZ) {
391 newZ = 1.0f / newZ;
392 }
393 *outX = newX * newZ;
394 *outY = newY * newZ;
395}
396
397static float transformAngle(const float matrix[9], float angleRadians,
398 float originX, float originY) {
Jeff Brown5912f952013-07-01 19:10:31 -0700399 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
400 // Coordinate system: down is increasing Y, right is increasing X.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700401 float x = sinf(angleRadians);
402 float y = -cosf(angleRadians);
403 transformPoint(matrix, x, y, &x, &y);
404 x -= originX;
405 y -= originY;
Jeff Brown5912f952013-07-01 19:10:31 -0700406
407 // Derive the transformed vector's clockwise angle from vertical.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700408 float result = atan2f(x, -y);
Jeff Brown5912f952013-07-01 19:10:31 -0700409 if (result < - M_PI_2) {
410 result += M_PI;
411 } else if (result > M_PI_2) {
412 result -= M_PI;
413 }
414 return result;
415}
416
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700417void MotionEvent::transform(const float matrix[9]) {
Jeff Brown5912f952013-07-01 19:10:31 -0700418 // The tricky part of this implementation is to preserve the value of
419 // rawX and rawY. So we apply the transformation to the first point
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700420 // then derive an appropriate new X/Y offset that will preserve rawX
421 // and rawY for that point.
422 float oldXOffset = mXOffset;
423 float oldYOffset = mYOffset;
424 float newX, newY;
Jeff Brown5912f952013-07-01 19:10:31 -0700425 float rawX = getRawX(0);
426 float rawY = getRawY(0);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700427 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
428 mXOffset = newX - rawX;
429 mYOffset = newY - rawY;
Jeff Brown5912f952013-07-01 19:10:31 -0700430
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700431 // Determine how the origin is transformed by the matrix so that we
432 // can transform orientation vectors.
433 float originX, originY;
434 transformPoint(matrix, 0, 0, &originX, &originY);
Jeff Brown5912f952013-07-01 19:10:31 -0700435
Garfield Tan00f511d2019-06-12 16:55:40 -0700436 // Apply the transformation to cursor position.
437 if (!isnan(mXCursorPosition) && !isnan(mYCursorPosition)) {
438 float x = mXCursorPosition + oldXOffset;
439 float y = mYCursorPosition + oldYOffset;
440 transformPoint(matrix, x, y, &x, &y);
441 mXCursorPosition = x - mXOffset;
442 mYCursorPosition = y - mYOffset;
443 }
444
Jeff Brown5912f952013-07-01 19:10:31 -0700445 // Apply the transformation to all samples.
446 size_t numSamples = mSamplePointerCoords.size();
447 for (size_t i = 0; i < numSamples; i++) {
448 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
449 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
450 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700451 transformPoint(matrix, x, y, &x, &y);
452 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
453 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
Jeff Brown5912f952013-07-01 19:10:31 -0700454
455 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700456 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
457 transformAngle(matrix, orientation, originX, originY));
Jeff Brown5912f952013-07-01 19:10:31 -0700458 }
459}
460
Elliott Hughes6071da72015-08-12 15:27:47 -0700461#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700462status_t MotionEvent::readFromParcel(Parcel* parcel) {
463 size_t pointerCount = parcel->readInt32();
464 size_t sampleCount = parcel->readInt32();
Flanker552a8a52015-09-07 15:28:58 +0800465 if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
466 sampleCount == 0 || sampleCount > MAX_SAMPLES) {
Jeff Brown5912f952013-07-01 19:10:31 -0700467 return BAD_VALUE;
468 }
469
470 mDeviceId = parcel->readInt32();
471 mSource = parcel->readInt32();
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800472 mDisplayId = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700473 mAction = parcel->readInt32();
Michael Wright7b159c92015-05-14 14:48:03 +0100474 mActionButton = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700475 mFlags = parcel->readInt32();
476 mEdgeFlags = parcel->readInt32();
477 mMetaState = parcel->readInt32();
478 mButtonState = parcel->readInt32();
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800479 mClassification = static_cast<MotionClassification>(parcel->readByte());
Jeff Brown5912f952013-07-01 19:10:31 -0700480 mXOffset = parcel->readFloat();
481 mYOffset = parcel->readFloat();
482 mXPrecision = parcel->readFloat();
483 mYPrecision = parcel->readFloat();
Garfield Tan00f511d2019-06-12 16:55:40 -0700484 mXCursorPosition = parcel->readFloat();
485 mYCursorPosition = parcel->readFloat();
Jeff Brown5912f952013-07-01 19:10:31 -0700486 mDownTime = parcel->readInt64();
487
488 mPointerProperties.clear();
489 mPointerProperties.setCapacity(pointerCount);
490 mSampleEventTimes.clear();
491 mSampleEventTimes.setCapacity(sampleCount);
492 mSamplePointerCoords.clear();
493 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
494
495 for (size_t i = 0; i < pointerCount; i++) {
496 mPointerProperties.push();
497 PointerProperties& properties = mPointerProperties.editTop();
498 properties.id = parcel->readInt32();
499 properties.toolType = parcel->readInt32();
500 }
501
Dan Austinc94fc452015-09-22 14:22:41 -0700502 while (sampleCount > 0) {
503 sampleCount--;
Jeff Brown5912f952013-07-01 19:10:31 -0700504 mSampleEventTimes.push(parcel->readInt64());
505 for (size_t i = 0; i < pointerCount; i++) {
506 mSamplePointerCoords.push();
507 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
508 if (status) {
509 return status;
510 }
511 }
512 }
513 return OK;
514}
515
516status_t MotionEvent::writeToParcel(Parcel* parcel) const {
517 size_t pointerCount = mPointerProperties.size();
518 size_t sampleCount = mSampleEventTimes.size();
519
520 parcel->writeInt32(pointerCount);
521 parcel->writeInt32(sampleCount);
522
523 parcel->writeInt32(mDeviceId);
524 parcel->writeInt32(mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800525 parcel->writeInt32(mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700526 parcel->writeInt32(mAction);
Michael Wright7b159c92015-05-14 14:48:03 +0100527 parcel->writeInt32(mActionButton);
Jeff Brown5912f952013-07-01 19:10:31 -0700528 parcel->writeInt32(mFlags);
529 parcel->writeInt32(mEdgeFlags);
530 parcel->writeInt32(mMetaState);
531 parcel->writeInt32(mButtonState);
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800532 parcel->writeByte(static_cast<int8_t>(mClassification));
Jeff Brown5912f952013-07-01 19:10:31 -0700533 parcel->writeFloat(mXOffset);
534 parcel->writeFloat(mYOffset);
535 parcel->writeFloat(mXPrecision);
536 parcel->writeFloat(mYPrecision);
Garfield Tan00f511d2019-06-12 16:55:40 -0700537 parcel->writeFloat(mXCursorPosition);
538 parcel->writeFloat(mYCursorPosition);
Jeff Brown5912f952013-07-01 19:10:31 -0700539 parcel->writeInt64(mDownTime);
540
541 for (size_t i = 0; i < pointerCount; i++) {
542 const PointerProperties& properties = mPointerProperties.itemAt(i);
543 parcel->writeInt32(properties.id);
544 parcel->writeInt32(properties.toolType);
545 }
546
547 const PointerCoords* pc = mSamplePointerCoords.array();
548 for (size_t h = 0; h < sampleCount; h++) {
549 parcel->writeInt64(mSampleEventTimes.itemAt(h));
550 for (size_t i = 0; i < pointerCount; i++) {
551 status_t status = (pc++)->writeToParcel(parcel);
552 if (status) {
553 return status;
554 }
555 }
556 }
557 return OK;
558}
559#endif
560
561bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
562 if (source & AINPUT_SOURCE_CLASS_POINTER) {
563 // Specifically excludes HOVER_MOVE and SCROLL.
564 switch (action & AMOTION_EVENT_ACTION_MASK) {
565 case AMOTION_EVENT_ACTION_DOWN:
566 case AMOTION_EVENT_ACTION_MOVE:
567 case AMOTION_EVENT_ACTION_UP:
568 case AMOTION_EVENT_ACTION_POINTER_DOWN:
569 case AMOTION_EVENT_ACTION_POINTER_UP:
570 case AMOTION_EVENT_ACTION_CANCEL:
571 case AMOTION_EVENT_ACTION_OUTSIDE:
572 return true;
573 }
574 }
575 return false;
576}
577
Michael Wright872db4f2014-04-22 15:03:51 -0700578const char* MotionEvent::getLabel(int32_t axis) {
579 return getAxisLabel(axis);
580}
581
582int32_t MotionEvent::getAxisFromLabel(const char* label) {
583 return getAxisByLabel(label);
584}
585
Jeff Brown5912f952013-07-01 19:10:31 -0700586
587// --- PooledInputEventFactory ---
588
589PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
590 mMaxPoolSize(maxPoolSize) {
591}
592
593PooledInputEventFactory::~PooledInputEventFactory() {
594 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
595 delete mKeyEventPool.itemAt(i);
596 }
597 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
598 delete mMotionEventPool.itemAt(i);
599 }
600}
601
602KeyEvent* PooledInputEventFactory::createKeyEvent() {
603 if (!mKeyEventPool.isEmpty()) {
604 KeyEvent* event = mKeyEventPool.top();
605 mKeyEventPool.pop();
606 return event;
607 }
608 return new KeyEvent();
609}
610
611MotionEvent* PooledInputEventFactory::createMotionEvent() {
612 if (!mMotionEventPool.isEmpty()) {
613 MotionEvent* event = mMotionEventPool.top();
614 mMotionEventPool.pop();
615 return event;
616 }
617 return new MotionEvent();
618}
619
620void PooledInputEventFactory::recycle(InputEvent* event) {
621 switch (event->getType()) {
622 case AINPUT_EVENT_TYPE_KEY:
623 if (mKeyEventPool.size() < mMaxPoolSize) {
624 mKeyEventPool.push(static_cast<KeyEvent*>(event));
625 return;
626 }
627 break;
628 case AINPUT_EVENT_TYPE_MOTION:
629 if (mMotionEventPool.size() < mMaxPoolSize) {
630 mMotionEventPool.push(static_cast<MotionEvent*>(event));
631 return;
632 }
633 break;
634 }
635 delete event;
636}
637
638} // namespace android