blob: 34b305e548169c4d5c1f3a05226e35e42d2e9422 [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,
Garfield Tan937bb832019-07-25 17:48:31 -0700241 float xPrecision, float yPrecision, float rawXCursorPosition,
242 float rawYCursorPosition, nsecs_t downTime, nsecs_t eventTime,
Garfield Tan00f511d2019-06-12 16:55:40 -0700243 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 Tan937bb832019-07-25 17:48:31 -0700257 mRawXCursorPosition = rawXCursorPosition;
258 mRawYCursorPosition = rawYCursorPosition;
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 Tan937bb832019-07-25 17:48:31 -0700280 mRawXCursorPosition = other->mRawXCursorPosition;
281 mRawYCursorPosition = other->mRawYCursorPosition;
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
Garfield Tan937bb832019-07-25 17:48:31 -0700316void MotionEvent::setCursorPosition(float x, float y) {
317 mRawXCursorPosition = x - mXOffset;
318 mRawYCursorPosition = y - mYOffset;
319}
320
Jeff Brown5912f952013-07-01 19:10:31 -0700321const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
322 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
323}
324
325float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
326 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
327}
328
329float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
330 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
331 switch (axis) {
332 case AMOTION_EVENT_AXIS_X:
333 return value + mXOffset;
334 case AMOTION_EVENT_AXIS_Y:
335 return value + mYOffset;
336 }
337 return value;
338}
339
340const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
341 size_t pointerIndex, size_t historicalIndex) const {
342 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
343}
344
345float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
346 size_t historicalIndex) const {
347 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
348}
349
350float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
351 size_t historicalIndex) const {
352 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
353 switch (axis) {
354 case AMOTION_EVENT_AXIS_X:
355 return value + mXOffset;
356 case AMOTION_EVENT_AXIS_Y:
357 return value + mYOffset;
358 }
359 return value;
360}
361
362ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
363 size_t pointerCount = mPointerProperties.size();
364 for (size_t i = 0; i < pointerCount; i++) {
365 if (mPointerProperties.itemAt(i).id == pointerId) {
366 return i;
367 }
368 }
369 return -1;
370}
371
372void MotionEvent::offsetLocation(float xOffset, float yOffset) {
373 mXOffset += xOffset;
374 mYOffset += yOffset;
375}
376
Robert Carre07e1032018-11-26 12:55:53 -0800377void MotionEvent::scale(float globalScaleFactor) {
378 mXOffset *= globalScaleFactor;
379 mYOffset *= globalScaleFactor;
380 mXPrecision *= globalScaleFactor;
381 mYPrecision *= globalScaleFactor;
Jeff Brown5912f952013-07-01 19:10:31 -0700382
383 size_t numSamples = mSamplePointerCoords.size();
384 for (size_t i = 0; i < numSamples; i++) {
Robert Carre07e1032018-11-26 12:55:53 -0800385 mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700386 }
387}
388
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700389static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
390 // Apply perspective transform like Skia.
391 float newX = matrix[0] * x + matrix[1] * y + matrix[2];
392 float newY = matrix[3] * x + matrix[4] * y + matrix[5];
393 float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
394 if (newZ) {
395 newZ = 1.0f / newZ;
396 }
397 *outX = newX * newZ;
398 *outY = newY * newZ;
399}
400
401static float transformAngle(const float matrix[9], float angleRadians,
402 float originX, float originY) {
Jeff Brown5912f952013-07-01 19:10:31 -0700403 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
404 // Coordinate system: down is increasing Y, right is increasing X.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700405 float x = sinf(angleRadians);
406 float y = -cosf(angleRadians);
407 transformPoint(matrix, x, y, &x, &y);
408 x -= originX;
409 y -= originY;
Jeff Brown5912f952013-07-01 19:10:31 -0700410
411 // Derive the transformed vector's clockwise angle from vertical.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700412 float result = atan2f(x, -y);
Jeff Brown5912f952013-07-01 19:10:31 -0700413 if (result < - M_PI_2) {
414 result += M_PI;
415 } else if (result > M_PI_2) {
416 result -= M_PI;
417 }
418 return result;
419}
420
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700421void MotionEvent::transform(const float matrix[9]) {
Jeff Brown5912f952013-07-01 19:10:31 -0700422 // The tricky part of this implementation is to preserve the value of
423 // rawX and rawY. So we apply the transformation to the first point
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700424 // then derive an appropriate new X/Y offset that will preserve rawX
425 // and rawY for that point.
426 float oldXOffset = mXOffset;
427 float oldYOffset = mYOffset;
428 float newX, newY;
Jeff Brown5912f952013-07-01 19:10:31 -0700429 float rawX = getRawX(0);
430 float rawY = getRawY(0);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700431 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
432 mXOffset = newX - rawX;
433 mYOffset = newY - rawY;
Jeff Brown5912f952013-07-01 19:10:31 -0700434
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700435 // Determine how the origin is transformed by the matrix so that we
436 // can transform orientation vectors.
437 float originX, originY;
438 transformPoint(matrix, 0, 0, &originX, &originY);
Jeff Brown5912f952013-07-01 19:10:31 -0700439
Garfield Tan00f511d2019-06-12 16:55:40 -0700440 // Apply the transformation to cursor position.
Garfield Tan937bb832019-07-25 17:48:31 -0700441 if (isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) {
442 float x = mRawXCursorPosition + oldXOffset;
443 float y = mRawYCursorPosition + oldYOffset;
Garfield Tan00f511d2019-06-12 16:55:40 -0700444 transformPoint(matrix, x, y, &x, &y);
Garfield Tan937bb832019-07-25 17:48:31 -0700445 mRawXCursorPosition = x - mXOffset;
446 mRawYCursorPosition = y - mYOffset;
Garfield Tan00f511d2019-06-12 16:55:40 -0700447 }
448
Jeff Brown5912f952013-07-01 19:10:31 -0700449 // Apply the transformation to all samples.
450 size_t numSamples = mSamplePointerCoords.size();
451 for (size_t i = 0; i < numSamples; i++) {
452 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
453 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
454 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700455 transformPoint(matrix, x, y, &x, &y);
456 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
457 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
Jeff Brown5912f952013-07-01 19:10:31 -0700458
459 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700460 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
461 transformAngle(matrix, orientation, originX, originY));
Jeff Brown5912f952013-07-01 19:10:31 -0700462 }
463}
464
Elliott Hughes6071da72015-08-12 15:27:47 -0700465#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700466status_t MotionEvent::readFromParcel(Parcel* parcel) {
467 size_t pointerCount = parcel->readInt32();
468 size_t sampleCount = parcel->readInt32();
Flanker552a8a52015-09-07 15:28:58 +0800469 if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
470 sampleCount == 0 || sampleCount > MAX_SAMPLES) {
Jeff Brown5912f952013-07-01 19:10:31 -0700471 return BAD_VALUE;
472 }
473
474 mDeviceId = parcel->readInt32();
475 mSource = parcel->readInt32();
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800476 mDisplayId = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700477 mAction = parcel->readInt32();
Michael Wright7b159c92015-05-14 14:48:03 +0100478 mActionButton = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700479 mFlags = parcel->readInt32();
480 mEdgeFlags = parcel->readInt32();
481 mMetaState = parcel->readInt32();
482 mButtonState = parcel->readInt32();
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800483 mClassification = static_cast<MotionClassification>(parcel->readByte());
Jeff Brown5912f952013-07-01 19:10:31 -0700484 mXOffset = parcel->readFloat();
485 mYOffset = parcel->readFloat();
486 mXPrecision = parcel->readFloat();
487 mYPrecision = parcel->readFloat();
Garfield Tan937bb832019-07-25 17:48:31 -0700488 mRawXCursorPosition = parcel->readFloat();
489 mRawYCursorPosition = parcel->readFloat();
Jeff Brown5912f952013-07-01 19:10:31 -0700490 mDownTime = parcel->readInt64();
491
492 mPointerProperties.clear();
493 mPointerProperties.setCapacity(pointerCount);
494 mSampleEventTimes.clear();
495 mSampleEventTimes.setCapacity(sampleCount);
496 mSamplePointerCoords.clear();
497 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
498
499 for (size_t i = 0; i < pointerCount; i++) {
500 mPointerProperties.push();
501 PointerProperties& properties = mPointerProperties.editTop();
502 properties.id = parcel->readInt32();
503 properties.toolType = parcel->readInt32();
504 }
505
Dan Austinc94fc452015-09-22 14:22:41 -0700506 while (sampleCount > 0) {
507 sampleCount--;
Jeff Brown5912f952013-07-01 19:10:31 -0700508 mSampleEventTimes.push(parcel->readInt64());
509 for (size_t i = 0; i < pointerCount; i++) {
510 mSamplePointerCoords.push();
511 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
512 if (status) {
513 return status;
514 }
515 }
516 }
517 return OK;
518}
519
520status_t MotionEvent::writeToParcel(Parcel* parcel) const {
521 size_t pointerCount = mPointerProperties.size();
522 size_t sampleCount = mSampleEventTimes.size();
523
524 parcel->writeInt32(pointerCount);
525 parcel->writeInt32(sampleCount);
526
527 parcel->writeInt32(mDeviceId);
528 parcel->writeInt32(mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800529 parcel->writeInt32(mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700530 parcel->writeInt32(mAction);
Michael Wright7b159c92015-05-14 14:48:03 +0100531 parcel->writeInt32(mActionButton);
Jeff Brown5912f952013-07-01 19:10:31 -0700532 parcel->writeInt32(mFlags);
533 parcel->writeInt32(mEdgeFlags);
534 parcel->writeInt32(mMetaState);
535 parcel->writeInt32(mButtonState);
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800536 parcel->writeByte(static_cast<int8_t>(mClassification));
Jeff Brown5912f952013-07-01 19:10:31 -0700537 parcel->writeFloat(mXOffset);
538 parcel->writeFloat(mYOffset);
539 parcel->writeFloat(mXPrecision);
540 parcel->writeFloat(mYPrecision);
Garfield Tan937bb832019-07-25 17:48:31 -0700541 parcel->writeFloat(mRawXCursorPosition);
542 parcel->writeFloat(mRawYCursorPosition);
Jeff Brown5912f952013-07-01 19:10:31 -0700543 parcel->writeInt64(mDownTime);
544
545 for (size_t i = 0; i < pointerCount; i++) {
546 const PointerProperties& properties = mPointerProperties.itemAt(i);
547 parcel->writeInt32(properties.id);
548 parcel->writeInt32(properties.toolType);
549 }
550
551 const PointerCoords* pc = mSamplePointerCoords.array();
552 for (size_t h = 0; h < sampleCount; h++) {
553 parcel->writeInt64(mSampleEventTimes.itemAt(h));
554 for (size_t i = 0; i < pointerCount; i++) {
555 status_t status = (pc++)->writeToParcel(parcel);
556 if (status) {
557 return status;
558 }
559 }
560 }
561 return OK;
562}
563#endif
564
565bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
566 if (source & AINPUT_SOURCE_CLASS_POINTER) {
567 // Specifically excludes HOVER_MOVE and SCROLL.
568 switch (action & AMOTION_EVENT_ACTION_MASK) {
569 case AMOTION_EVENT_ACTION_DOWN:
570 case AMOTION_EVENT_ACTION_MOVE:
571 case AMOTION_EVENT_ACTION_UP:
572 case AMOTION_EVENT_ACTION_POINTER_DOWN:
573 case AMOTION_EVENT_ACTION_POINTER_UP:
574 case AMOTION_EVENT_ACTION_CANCEL:
575 case AMOTION_EVENT_ACTION_OUTSIDE:
576 return true;
577 }
578 }
579 return false;
580}
581
Michael Wright872db4f2014-04-22 15:03:51 -0700582const char* MotionEvent::getLabel(int32_t axis) {
583 return getAxisLabel(axis);
584}
585
586int32_t MotionEvent::getAxisFromLabel(const char* label) {
587 return getAxisByLabel(label);
588}
589
Jeff Brown5912f952013-07-01 19:10:31 -0700590
591// --- PooledInputEventFactory ---
592
593PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
594 mMaxPoolSize(maxPoolSize) {
595}
596
597PooledInputEventFactory::~PooledInputEventFactory() {
598 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
599 delete mKeyEventPool.itemAt(i);
600 }
601 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
602 delete mMotionEventPool.itemAt(i);
603 }
604}
605
606KeyEvent* PooledInputEventFactory::createKeyEvent() {
607 if (!mKeyEventPool.isEmpty()) {
608 KeyEvent* event = mKeyEventPool.top();
609 mKeyEventPool.pop();
610 return event;
611 }
612 return new KeyEvent();
613}
614
615MotionEvent* PooledInputEventFactory::createMotionEvent() {
616 if (!mMotionEventPool.isEmpty()) {
617 MotionEvent* event = mMotionEventPool.top();
618 mMotionEventPool.pop();
619 return event;
620 }
621 return new MotionEvent();
622}
623
624void PooledInputEventFactory::recycle(InputEvent* event) {
625 switch (event->getType()) {
626 case AINPUT_EVENT_TYPE_KEY:
627 if (mKeyEventPool.size() < mMaxPoolSize) {
628 mKeyEventPool.push(static_cast<KeyEvent*>(event));
629 return;
630 }
631 break;
632 case AINPUT_EVENT_TYPE_MOTION:
633 if (mMotionEventPool.size() < mMaxPoolSize) {
634 mMotionEventPool.push(static_cast<MotionEvent*>(event));
635 return;
636 }
637 break;
638 }
639 delete event;
640}
641
642} // namespace android