blob: dc4978b836d52b6ac147f5ad2abf32604ffdff35 [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>
Michael Wright872db4f2014-04-22 15:03:51 -070023#include <input/InputEventLabels.h>
Jeff Brown5912f952013-07-01 19:10:31 -070024
Elliott Hughes6071da72015-08-12 15:27:47 -070025#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -070026#include <binder/Parcel.h>
Jeff Brown5912f952013-07-01 19:10:31 -070027#endif
28
29namespace android {
30
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -080031const char* motionClassificationToString(MotionClassification classification) {
32 switch (classification) {
33 case MotionClassification::NONE:
34 return "NONE";
35 case MotionClassification::AMBIGUOUS_GESTURE:
36 return "AMBIGUOUS_GESTURE";
37 case MotionClassification::DEEP_PRESS:
38 return "DEEP_PRESS";
39 }
40}
41
Jeff Brown5912f952013-07-01 19:10:31 -070042// --- InputEvent ---
43
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010044void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
Jeff Brown5912f952013-07-01 19:10:31 -070045 mDeviceId = deviceId;
46 mSource = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010047 mDisplayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -070048}
49
50void InputEvent::initialize(const InputEvent& from) {
51 mDeviceId = from.mDeviceId;
52 mSource = from.mSource;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010053 mDisplayId = from.mDisplayId;
Jeff Brown5912f952013-07-01 19:10:31 -070054}
55
56// --- KeyEvent ---
57
Michael Wright872db4f2014-04-22 15:03:51 -070058const char* KeyEvent::getLabel(int32_t keyCode) {
59 return getLabelByKeyCode(keyCode);
Jeff Brown5912f952013-07-01 19:10:31 -070060}
61
Michael Wright872db4f2014-04-22 15:03:51 -070062int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
63 return getKeyCodeByLabel(label);
Jeff Brown5912f952013-07-01 19:10:31 -070064}
65
66void KeyEvent::initialize(
67 int32_t deviceId,
68 int32_t source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010069 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -070070 int32_t action,
71 int32_t flags,
72 int32_t keyCode,
73 int32_t scanCode,
74 int32_t metaState,
75 int32_t repeatCount,
76 nsecs_t downTime,
77 nsecs_t eventTime) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010078 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -070079 mAction = action;
80 mFlags = flags;
81 mKeyCode = keyCode;
82 mScanCode = scanCode;
83 mMetaState = metaState;
84 mRepeatCount = repeatCount;
85 mDownTime = downTime;
86 mEventTime = eventTime;
87}
88
89void KeyEvent::initialize(const KeyEvent& from) {
90 InputEvent::initialize(from);
91 mAction = from.mAction;
92 mFlags = from.mFlags;
93 mKeyCode = from.mKeyCode;
94 mScanCode = from.mScanCode;
95 mMetaState = from.mMetaState;
96 mRepeatCount = from.mRepeatCount;
97 mDownTime = from.mDownTime;
98 mEventTime = from.mEventTime;
99}
100
101
102// --- PointerCoords ---
103
104float PointerCoords::getAxisValue(int32_t axis) const {
Michael Wright38dcdff2014-03-19 12:06:10 -0700105 if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
Jeff Brown5912f952013-07-01 19:10:31 -0700106 return 0;
107 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700108 return values[BitSet64::getIndexOfBit(bits, axis)];
Jeff Brown5912f952013-07-01 19:10:31 -0700109}
110
111status_t PointerCoords::setAxisValue(int32_t axis, float value) {
112 if (axis < 0 || axis > 63) {
113 return NAME_NOT_FOUND;
114 }
115
Michael Wright38dcdff2014-03-19 12:06:10 -0700116 uint32_t index = BitSet64::getIndexOfBit(bits, axis);
117 if (!BitSet64::hasBit(bits, axis)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700118 if (value == 0) {
119 return OK; // axes with value 0 do not need to be stored
120 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700121
122 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700123 if (count >= MAX_AXES) {
124 tooManyAxes(axis);
125 return NO_MEMORY;
126 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700127 BitSet64::markBit(bits, axis);
Jeff Brown5912f952013-07-01 19:10:31 -0700128 for (uint32_t i = count; i > index; i--) {
129 values[i] = values[i - 1];
130 }
131 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700132
Jeff Brown5912f952013-07-01 19:10:31 -0700133 values[index] = value;
134 return OK;
135}
136
137static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
138 float value = c.getAxisValue(axis);
139 if (value != 0) {
140 c.setAxisValue(axis, value * scaleFactor);
141 }
142}
143
Robert Carre07e1032018-11-26 12:55:53 -0800144void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
Jeff Brown5912f952013-07-01 19:10:31 -0700145 // No need to scale pressure or size since they are normalized.
146 // No need to scale orientation since it is meaningless to do so.
Robert Carre07e1032018-11-26 12:55:53 -0800147
148 // If there is a global scale factor, it is included in the windowX/YScale
149 // so we don't need to apply it twice to the X/Y axes.
150 // However we don't want to apply any windowXYScale not included in the global scale
151 // to the TOUCH_MAJOR/MINOR coordinates.
152 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
153 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
154 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
155 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
156 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
157 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
158}
159
160void PointerCoords::scale(float globalScaleFactor) {
161 scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700162}
163
Jeff Brownf086ddb2014-02-11 14:28:48 -0800164void PointerCoords::applyOffset(float xOffset, float yOffset) {
165 setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
166 setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
167}
168
Elliott Hughes6071da72015-08-12 15:27:47 -0700169#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700170status_t PointerCoords::readFromParcel(Parcel* parcel) {
171 bits = parcel->readInt64();
172
Michael Wright38dcdff2014-03-19 12:06:10 -0700173 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700174 if (count > MAX_AXES) {
175 return BAD_VALUE;
176 }
177
178 for (uint32_t i = 0; i < count; i++) {
179 values[i] = parcel->readFloat();
180 }
181 return OK;
182}
183
184status_t PointerCoords::writeToParcel(Parcel* parcel) const {
185 parcel->writeInt64(bits);
186
Michael Wright38dcdff2014-03-19 12:06:10 -0700187 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700188 for (uint32_t i = 0; i < count; i++) {
189 parcel->writeFloat(values[i]);
190 }
191 return OK;
192}
193#endif
194
195void PointerCoords::tooManyAxes(int axis) {
196 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
197 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
198}
199
200bool PointerCoords::operator==(const PointerCoords& other) const {
201 if (bits != other.bits) {
202 return false;
203 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700204 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700205 for (uint32_t i = 0; i < count; i++) {
206 if (values[i] != other.values[i]) {
207 return false;
208 }
209 }
210 return true;
211}
212
213void PointerCoords::copyFrom(const PointerCoords& other) {
214 bits = other.bits;
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 values[i] = other.values[i];
218 }
219}
220
221
222// --- PointerProperties ---
223
224bool PointerProperties::operator==(const PointerProperties& other) const {
225 return id == other.id
226 && toolType == other.toolType;
227}
228
229void PointerProperties::copyFrom(const PointerProperties& other) {
230 id = other.id;
231 toolType = other.toolType;
232}
233
234
235// --- MotionEvent ---
236
Garfield Tan00f511d2019-06-12 16:55:40 -0700237void MotionEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
238 int32_t actionButton, int32_t flags, int32_t edgeFlags,
239 int32_t metaState, int32_t buttonState,
240 MotionClassification classification, float xOffset, float yOffset,
241 float xPrecision, float yPrecision, float xCursorPosition,
242 float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
243 size_t pointerCount, const PointerProperties* pointerProperties,
244 const PointerCoords* pointerCoords) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100245 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700246 mAction = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100247 mActionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700248 mFlags = flags;
249 mEdgeFlags = edgeFlags;
250 mMetaState = metaState;
251 mButtonState = buttonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800252 mClassification = classification;
Jeff Brown5912f952013-07-01 19:10:31 -0700253 mXOffset = xOffset;
254 mYOffset = yOffset;
255 mXPrecision = xPrecision;
256 mYPrecision = yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700257 mXCursorPosition = xCursorPosition;
258 mYCursorPosition = yCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700259 mDownTime = downTime;
260 mPointerProperties.clear();
261 mPointerProperties.appendArray(pointerProperties, pointerCount);
262 mSampleEventTimes.clear();
263 mSamplePointerCoords.clear();
264 addSample(eventTime, pointerCoords);
265}
266
267void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100268 InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700269 mAction = other->mAction;
Michael Wright7b159c92015-05-14 14:48:03 +0100270 mActionButton = other->mActionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700271 mFlags = other->mFlags;
272 mEdgeFlags = other->mEdgeFlags;
273 mMetaState = other->mMetaState;
274 mButtonState = other->mButtonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800275 mClassification = other->mClassification;
Jeff Brown5912f952013-07-01 19:10:31 -0700276 mXOffset = other->mXOffset;
277 mYOffset = other->mYOffset;
278 mXPrecision = other->mXPrecision;
279 mYPrecision = other->mYPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700280 mXCursorPosition = other->mXCursorPosition;
281 mYCursorPosition = other->mYCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700282 mDownTime = other->mDownTime;
283 mPointerProperties = other->mPointerProperties;
284
285 if (keepHistory) {
286 mSampleEventTimes = other->mSampleEventTimes;
287 mSamplePointerCoords = other->mSamplePointerCoords;
288 } else {
289 mSampleEventTimes.clear();
290 mSampleEventTimes.push(other->getEventTime());
291 mSamplePointerCoords.clear();
292 size_t pointerCount = other->getPointerCount();
293 size_t historySize = other->getHistorySize();
294 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
295 + (historySize * pointerCount), pointerCount);
296 }
297}
298
299void MotionEvent::addSample(
300 int64_t eventTime,
301 const PointerCoords* pointerCoords) {
302 mSampleEventTimes.push(eventTime);
303 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
304}
305
Garfield Tan00f511d2019-06-12 16:55:40 -0700306float MotionEvent::getXCursorPosition() const {
307 const float rawX = getRawXCursorPosition();
308 return rawX + mXOffset;
309}
310
311float MotionEvent::getYCursorPosition() const {
312 const float rawY = getRawYCursorPosition();
313 return rawY + mYOffset;
314}
315
Jeff Brown5912f952013-07-01 19:10:31 -0700316const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
317 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
318}
319
320float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
321 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
322}
323
324float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
325 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
326 switch (axis) {
327 case AMOTION_EVENT_AXIS_X:
328 return value + mXOffset;
329 case AMOTION_EVENT_AXIS_Y:
330 return value + mYOffset;
331 }
332 return value;
333}
334
335const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
336 size_t pointerIndex, size_t historicalIndex) const {
337 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
338}
339
340float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
341 size_t historicalIndex) const {
342 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
343}
344
345float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
346 size_t historicalIndex) const {
347 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
348 switch (axis) {
349 case AMOTION_EVENT_AXIS_X:
350 return value + mXOffset;
351 case AMOTION_EVENT_AXIS_Y:
352 return value + mYOffset;
353 }
354 return value;
355}
356
357ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
358 size_t pointerCount = mPointerProperties.size();
359 for (size_t i = 0; i < pointerCount; i++) {
360 if (mPointerProperties.itemAt(i).id == pointerId) {
361 return i;
362 }
363 }
364 return -1;
365}
366
367void MotionEvent::offsetLocation(float xOffset, float yOffset) {
368 mXOffset += xOffset;
369 mYOffset += yOffset;
370}
371
Robert Carre07e1032018-11-26 12:55:53 -0800372void MotionEvent::scale(float globalScaleFactor) {
373 mXOffset *= globalScaleFactor;
374 mYOffset *= globalScaleFactor;
375 mXPrecision *= globalScaleFactor;
376 mYPrecision *= globalScaleFactor;
Jeff Brown5912f952013-07-01 19:10:31 -0700377
378 size_t numSamples = mSamplePointerCoords.size();
379 for (size_t i = 0; i < numSamples; i++) {
Robert Carre07e1032018-11-26 12:55:53 -0800380 mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700381 }
382}
383
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700384static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
385 // Apply perspective transform like Skia.
386 float newX = matrix[0] * x + matrix[1] * y + matrix[2];
387 float newY = matrix[3] * x + matrix[4] * y + matrix[5];
388 float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
389 if (newZ) {
390 newZ = 1.0f / newZ;
391 }
392 *outX = newX * newZ;
393 *outY = newY * newZ;
394}
395
396static float transformAngle(const float matrix[9], float angleRadians,
397 float originX, float originY) {
Jeff Brown5912f952013-07-01 19:10:31 -0700398 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
399 // Coordinate system: down is increasing Y, right is increasing X.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700400 float x = sinf(angleRadians);
401 float y = -cosf(angleRadians);
402 transformPoint(matrix, x, y, &x, &y);
403 x -= originX;
404 y -= originY;
Jeff Brown5912f952013-07-01 19:10:31 -0700405
406 // Derive the transformed vector's clockwise angle from vertical.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700407 float result = atan2f(x, -y);
Jeff Brown5912f952013-07-01 19:10:31 -0700408 if (result < - M_PI_2) {
409 result += M_PI;
410 } else if (result > M_PI_2) {
411 result -= M_PI;
412 }
413 return result;
414}
415
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700416void MotionEvent::transform(const float matrix[9]) {
Jeff Brown5912f952013-07-01 19:10:31 -0700417 // The tricky part of this implementation is to preserve the value of
418 // rawX and rawY. So we apply the transformation to the first point
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700419 // then derive an appropriate new X/Y offset that will preserve rawX
420 // and rawY for that point.
421 float oldXOffset = mXOffset;
422 float oldYOffset = mYOffset;
423 float newX, newY;
Jeff Brown5912f952013-07-01 19:10:31 -0700424 float rawX = getRawX(0);
425 float rawY = getRawY(0);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700426 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
427 mXOffset = newX - rawX;
428 mYOffset = newY - rawY;
Jeff Brown5912f952013-07-01 19:10:31 -0700429
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700430 // Determine how the origin is transformed by the matrix so that we
431 // can transform orientation vectors.
432 float originX, originY;
433 transformPoint(matrix, 0, 0, &originX, &originY);
Jeff Brown5912f952013-07-01 19:10:31 -0700434
Garfield Tan00f511d2019-06-12 16:55:40 -0700435 // Apply the transformation to cursor position.
Garfield Tanab0ab9c2019-07-10 18:58:28 -0700436 if (isValidCursorPosition(mXCursorPosition, mYCursorPosition)) {
Garfield Tan00f511d2019-06-12 16:55:40 -0700437 float x = mXCursorPosition + oldXOffset;
438 float y = mYCursorPosition + oldYOffset;
439 transformPoint(matrix, x, y, &x, &y);
440 mXCursorPosition = x - mXOffset;
441 mYCursorPosition = y - mYOffset;
442 }
443
Jeff Brown5912f952013-07-01 19:10:31 -0700444 // Apply the transformation to all samples.
445 size_t numSamples = mSamplePointerCoords.size();
446 for (size_t i = 0; i < numSamples; i++) {
447 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
448 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
449 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700450 transformPoint(matrix, x, y, &x, &y);
451 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
452 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
Jeff Brown5912f952013-07-01 19:10:31 -0700453
454 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700455 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
456 transformAngle(matrix, orientation, originX, originY));
Jeff Brown5912f952013-07-01 19:10:31 -0700457 }
458}
459
Elliott Hughes6071da72015-08-12 15:27:47 -0700460#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700461status_t MotionEvent::readFromParcel(Parcel* parcel) {
462 size_t pointerCount = parcel->readInt32();
463 size_t sampleCount = parcel->readInt32();
Flanker552a8a52015-09-07 15:28:58 +0800464 if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
465 sampleCount == 0 || sampleCount > MAX_SAMPLES) {
Jeff Brown5912f952013-07-01 19:10:31 -0700466 return BAD_VALUE;
467 }
468
469 mDeviceId = parcel->readInt32();
470 mSource = parcel->readInt32();
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800471 mDisplayId = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700472 mAction = parcel->readInt32();
Michael Wright7b159c92015-05-14 14:48:03 +0100473 mActionButton = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700474 mFlags = parcel->readInt32();
475 mEdgeFlags = parcel->readInt32();
476 mMetaState = parcel->readInt32();
477 mButtonState = parcel->readInt32();
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800478 mClassification = static_cast<MotionClassification>(parcel->readByte());
Jeff Brown5912f952013-07-01 19:10:31 -0700479 mXOffset = parcel->readFloat();
480 mYOffset = parcel->readFloat();
481 mXPrecision = parcel->readFloat();
482 mYPrecision = parcel->readFloat();
Garfield Tan00f511d2019-06-12 16:55:40 -0700483 mXCursorPosition = parcel->readFloat();
484 mYCursorPosition = parcel->readFloat();
Jeff Brown5912f952013-07-01 19:10:31 -0700485 mDownTime = parcel->readInt64();
486
487 mPointerProperties.clear();
488 mPointerProperties.setCapacity(pointerCount);
489 mSampleEventTimes.clear();
490 mSampleEventTimes.setCapacity(sampleCount);
491 mSamplePointerCoords.clear();
492 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
493
494 for (size_t i = 0; i < pointerCount; i++) {
495 mPointerProperties.push();
496 PointerProperties& properties = mPointerProperties.editTop();
497 properties.id = parcel->readInt32();
498 properties.toolType = parcel->readInt32();
499 }
500
Dan Austinc94fc452015-09-22 14:22:41 -0700501 while (sampleCount > 0) {
502 sampleCount--;
Jeff Brown5912f952013-07-01 19:10:31 -0700503 mSampleEventTimes.push(parcel->readInt64());
504 for (size_t i = 0; i < pointerCount; i++) {
505 mSamplePointerCoords.push();
506 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
507 if (status) {
508 return status;
509 }
510 }
511 }
512 return OK;
513}
514
515status_t MotionEvent::writeToParcel(Parcel* parcel) const {
516 size_t pointerCount = mPointerProperties.size();
517 size_t sampleCount = mSampleEventTimes.size();
518
519 parcel->writeInt32(pointerCount);
520 parcel->writeInt32(sampleCount);
521
522 parcel->writeInt32(mDeviceId);
523 parcel->writeInt32(mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800524 parcel->writeInt32(mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700525 parcel->writeInt32(mAction);
Michael Wright7b159c92015-05-14 14:48:03 +0100526 parcel->writeInt32(mActionButton);
Jeff Brown5912f952013-07-01 19:10:31 -0700527 parcel->writeInt32(mFlags);
528 parcel->writeInt32(mEdgeFlags);
529 parcel->writeInt32(mMetaState);
530 parcel->writeInt32(mButtonState);
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800531 parcel->writeByte(static_cast<int8_t>(mClassification));
Jeff Brown5912f952013-07-01 19:10:31 -0700532 parcel->writeFloat(mXOffset);
533 parcel->writeFloat(mYOffset);
534 parcel->writeFloat(mXPrecision);
535 parcel->writeFloat(mYPrecision);
Garfield Tan00f511d2019-06-12 16:55:40 -0700536 parcel->writeFloat(mXCursorPosition);
537 parcel->writeFloat(mYCursorPosition);
Jeff Brown5912f952013-07-01 19:10:31 -0700538 parcel->writeInt64(mDownTime);
539
540 for (size_t i = 0; i < pointerCount; i++) {
541 const PointerProperties& properties = mPointerProperties.itemAt(i);
542 parcel->writeInt32(properties.id);
543 parcel->writeInt32(properties.toolType);
544 }
545
546 const PointerCoords* pc = mSamplePointerCoords.array();
547 for (size_t h = 0; h < sampleCount; h++) {
548 parcel->writeInt64(mSampleEventTimes.itemAt(h));
549 for (size_t i = 0; i < pointerCount; i++) {
550 status_t status = (pc++)->writeToParcel(parcel);
551 if (status) {
552 return status;
553 }
554 }
555 }
556 return OK;
557}
558#endif
559
560bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
561 if (source & AINPUT_SOURCE_CLASS_POINTER) {
562 // Specifically excludes HOVER_MOVE and SCROLL.
563 switch (action & AMOTION_EVENT_ACTION_MASK) {
564 case AMOTION_EVENT_ACTION_DOWN:
565 case AMOTION_EVENT_ACTION_MOVE:
566 case AMOTION_EVENT_ACTION_UP:
567 case AMOTION_EVENT_ACTION_POINTER_DOWN:
568 case AMOTION_EVENT_ACTION_POINTER_UP:
569 case AMOTION_EVENT_ACTION_CANCEL:
570 case AMOTION_EVENT_ACTION_OUTSIDE:
571 return true;
572 }
573 }
574 return false;
575}
576
Michael Wright872db4f2014-04-22 15:03:51 -0700577const char* MotionEvent::getLabel(int32_t axis) {
578 return getAxisLabel(axis);
579}
580
581int32_t MotionEvent::getAxisFromLabel(const char* label) {
582 return getAxisByLabel(label);
583}
584
Jeff Brown5912f952013-07-01 19:10:31 -0700585
586// --- PooledInputEventFactory ---
587
588PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
589 mMaxPoolSize(maxPoolSize) {
590}
591
592PooledInputEventFactory::~PooledInputEventFactory() {
593 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
594 delete mKeyEventPool.itemAt(i);
595 }
596 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
597 delete mMotionEventPool.itemAt(i);
598 }
599}
600
601KeyEvent* PooledInputEventFactory::createKeyEvent() {
602 if (!mKeyEventPool.isEmpty()) {
603 KeyEvent* event = mKeyEventPool.top();
604 mKeyEventPool.pop();
605 return event;
606 }
607 return new KeyEvent();
608}
609
610MotionEvent* PooledInputEventFactory::createMotionEvent() {
611 if (!mMotionEventPool.isEmpty()) {
612 MotionEvent* event = mMotionEventPool.top();
613 mMotionEventPool.pop();
614 return event;
615 }
616 return new MotionEvent();
617}
618
619void PooledInputEventFactory::recycle(InputEvent* event) {
620 switch (event->getType()) {
621 case AINPUT_EVENT_TYPE_KEY:
622 if (mKeyEventPool.size() < mMaxPoolSize) {
623 mKeyEventPool.push(static_cast<KeyEvent*>(event));
624 return;
625 }
626 break;
627 case AINPUT_EVENT_TYPE_MOTION:
628 if (mMotionEventPool.size() < mMaxPoolSize) {
629 mMotionEventPool.push(static_cast<MotionEvent*>(event));
630 return;
631 }
632 break;
633 }
634 delete event;
635}
636
637} // namespace android