blob: db86c8ea300e19c31ffca9ea986f46552f9c0c16 [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
32// --- InputEvent ---
33
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010034void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
Jeff Brown5912f952013-07-01 19:10:31 -070035 mDeviceId = deviceId;
36 mSource = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010037 mDisplayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -070038}
39
40void InputEvent::initialize(const InputEvent& from) {
41 mDeviceId = from.mDeviceId;
42 mSource = from.mSource;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010043 mDisplayId = from.mDisplayId;
Jeff Brown5912f952013-07-01 19:10:31 -070044}
45
46// --- KeyEvent ---
47
Michael Wright872db4f2014-04-22 15:03:51 -070048const char* KeyEvent::getLabel(int32_t keyCode) {
49 return getLabelByKeyCode(keyCode);
Jeff Brown5912f952013-07-01 19:10:31 -070050}
51
Michael Wright872db4f2014-04-22 15:03:51 -070052int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
53 return getKeyCodeByLabel(label);
Jeff Brown5912f952013-07-01 19:10:31 -070054}
55
56void KeyEvent::initialize(
57 int32_t deviceId,
58 int32_t source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010059 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -070060 int32_t action,
61 int32_t flags,
62 int32_t keyCode,
63 int32_t scanCode,
64 int32_t metaState,
65 int32_t repeatCount,
66 nsecs_t downTime,
67 nsecs_t eventTime) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010068 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -070069 mAction = action;
70 mFlags = flags;
71 mKeyCode = keyCode;
72 mScanCode = scanCode;
73 mMetaState = metaState;
74 mRepeatCount = repeatCount;
75 mDownTime = downTime;
76 mEventTime = eventTime;
77}
78
79void KeyEvent::initialize(const KeyEvent& from) {
80 InputEvent::initialize(from);
81 mAction = from.mAction;
82 mFlags = from.mFlags;
83 mKeyCode = from.mKeyCode;
84 mScanCode = from.mScanCode;
85 mMetaState = from.mMetaState;
86 mRepeatCount = from.mRepeatCount;
87 mDownTime = from.mDownTime;
88 mEventTime = from.mEventTime;
89}
90
91
92// --- PointerCoords ---
93
94float PointerCoords::getAxisValue(int32_t axis) const {
Michael Wright38dcdff2014-03-19 12:06:10 -070095 if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
Jeff Brown5912f952013-07-01 19:10:31 -070096 return 0;
97 }
Michael Wright38dcdff2014-03-19 12:06:10 -070098 return values[BitSet64::getIndexOfBit(bits, axis)];
Jeff Brown5912f952013-07-01 19:10:31 -070099}
100
101status_t PointerCoords::setAxisValue(int32_t axis, float value) {
102 if (axis < 0 || axis > 63) {
103 return NAME_NOT_FOUND;
104 }
105
Michael Wright38dcdff2014-03-19 12:06:10 -0700106 uint32_t index = BitSet64::getIndexOfBit(bits, axis);
107 if (!BitSet64::hasBit(bits, axis)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700108 if (value == 0) {
109 return OK; // axes with value 0 do not need to be stored
110 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700111
112 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700113 if (count >= MAX_AXES) {
114 tooManyAxes(axis);
115 return NO_MEMORY;
116 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700117 BitSet64::markBit(bits, axis);
Jeff Brown5912f952013-07-01 19:10:31 -0700118 for (uint32_t i = count; i > index; i--) {
119 values[i] = values[i - 1];
120 }
121 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700122
Jeff Brown5912f952013-07-01 19:10:31 -0700123 values[index] = value;
124 return OK;
125}
126
127static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
128 float value = c.getAxisValue(axis);
129 if (value != 0) {
130 c.setAxisValue(axis, value * scaleFactor);
131 }
132}
133
Robert Carre07e1032018-11-26 12:55:53 -0800134void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
Jeff Brown5912f952013-07-01 19:10:31 -0700135 // No need to scale pressure or size since they are normalized.
136 // No need to scale orientation since it is meaningless to do so.
Robert Carre07e1032018-11-26 12:55:53 -0800137
138 // If there is a global scale factor, it is included in the windowX/YScale
139 // so we don't need to apply it twice to the X/Y axes.
140 // However we don't want to apply any windowXYScale not included in the global scale
141 // to the TOUCH_MAJOR/MINOR coordinates.
142 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
143 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
144 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
145 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
146 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
147 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
148}
149
150void PointerCoords::scale(float globalScaleFactor) {
151 scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700152}
153
Jeff Brownf086ddb2014-02-11 14:28:48 -0800154void PointerCoords::applyOffset(float xOffset, float yOffset) {
155 setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
156 setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
157}
158
Elliott Hughes6071da72015-08-12 15:27:47 -0700159#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700160status_t PointerCoords::readFromParcel(Parcel* parcel) {
161 bits = parcel->readInt64();
162
Michael Wright38dcdff2014-03-19 12:06:10 -0700163 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700164 if (count > MAX_AXES) {
165 return BAD_VALUE;
166 }
167
168 for (uint32_t i = 0; i < count; i++) {
169 values[i] = parcel->readFloat();
170 }
171 return OK;
172}
173
174status_t PointerCoords::writeToParcel(Parcel* parcel) const {
175 parcel->writeInt64(bits);
176
Michael Wright38dcdff2014-03-19 12:06:10 -0700177 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700178 for (uint32_t i = 0; i < count; i++) {
179 parcel->writeFloat(values[i]);
180 }
181 return OK;
182}
183#endif
184
185void PointerCoords::tooManyAxes(int axis) {
186 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
187 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
188}
189
190bool PointerCoords::operator==(const PointerCoords& other) const {
191 if (bits != other.bits) {
192 return false;
193 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700194 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700195 for (uint32_t i = 0; i < count; i++) {
196 if (values[i] != other.values[i]) {
197 return false;
198 }
199 }
200 return true;
201}
202
203void PointerCoords::copyFrom(const PointerCoords& other) {
204 bits = other.bits;
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 values[i] = other.values[i];
208 }
209}
210
211
212// --- PointerProperties ---
213
214bool PointerProperties::operator==(const PointerProperties& other) const {
215 return id == other.id
216 && toolType == other.toolType;
217}
218
219void PointerProperties::copyFrom(const PointerProperties& other) {
220 id = other.id;
221 toolType = other.toolType;
222}
223
224
225// --- MotionEvent ---
226
227void MotionEvent::initialize(
228 int32_t deviceId,
229 int32_t source,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800230 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -0700231 int32_t action,
Michael Wright7b159c92015-05-14 14:48:03 +0100232 int32_t actionButton,
Jeff Brown5912f952013-07-01 19:10:31 -0700233 int32_t flags,
234 int32_t edgeFlags,
235 int32_t metaState,
236 int32_t buttonState,
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800237 MotionClassification classification,
Jeff Brown5912f952013-07-01 19:10:31 -0700238 float xOffset,
239 float yOffset,
240 float xPrecision,
241 float yPrecision,
242 nsecs_t downTime,
243 nsecs_t eventTime,
244 size_t pointerCount,
245 const PointerProperties* pointerProperties,
246 const PointerCoords* pointerCoords) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100247 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700248 mAction = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100249 mActionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700250 mFlags = flags;
251 mEdgeFlags = edgeFlags;
252 mMetaState = metaState;
253 mButtonState = buttonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800254 mClassification = classification;
Jeff Brown5912f952013-07-01 19:10:31 -0700255 mXOffset = xOffset;
256 mYOffset = yOffset;
257 mXPrecision = xPrecision;
258 mYPrecision = yPrecision;
259 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;
280 mDownTime = other->mDownTime;
281 mPointerProperties = other->mPointerProperties;
282
283 if (keepHistory) {
284 mSampleEventTimes = other->mSampleEventTimes;
285 mSamplePointerCoords = other->mSamplePointerCoords;
286 } else {
287 mSampleEventTimes.clear();
288 mSampleEventTimes.push(other->getEventTime());
289 mSamplePointerCoords.clear();
290 size_t pointerCount = other->getPointerCount();
291 size_t historySize = other->getHistorySize();
292 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
293 + (historySize * pointerCount), pointerCount);
294 }
295}
296
297void MotionEvent::addSample(
298 int64_t eventTime,
299 const PointerCoords* pointerCoords) {
300 mSampleEventTimes.push(eventTime);
301 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
302}
303
304const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
305 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
306}
307
308float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
309 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
310}
311
312float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
313 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
314 switch (axis) {
315 case AMOTION_EVENT_AXIS_X:
316 return value + mXOffset;
317 case AMOTION_EVENT_AXIS_Y:
318 return value + mYOffset;
319 }
320 return value;
321}
322
323const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
324 size_t pointerIndex, size_t historicalIndex) const {
325 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
326}
327
328float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
329 size_t historicalIndex) const {
330 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
331}
332
333float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
334 size_t historicalIndex) const {
335 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
336 switch (axis) {
337 case AMOTION_EVENT_AXIS_X:
338 return value + mXOffset;
339 case AMOTION_EVENT_AXIS_Y:
340 return value + mYOffset;
341 }
342 return value;
343}
344
345ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
346 size_t pointerCount = mPointerProperties.size();
347 for (size_t i = 0; i < pointerCount; i++) {
348 if (mPointerProperties.itemAt(i).id == pointerId) {
349 return i;
350 }
351 }
352 return -1;
353}
354
355void MotionEvent::offsetLocation(float xOffset, float yOffset) {
356 mXOffset += xOffset;
357 mYOffset += yOffset;
358}
359
Robert Carre07e1032018-11-26 12:55:53 -0800360void MotionEvent::scale(float globalScaleFactor) {
361 mXOffset *= globalScaleFactor;
362 mYOffset *= globalScaleFactor;
363 mXPrecision *= globalScaleFactor;
364 mYPrecision *= globalScaleFactor;
Jeff Brown5912f952013-07-01 19:10:31 -0700365
366 size_t numSamples = mSamplePointerCoords.size();
367 for (size_t i = 0; i < numSamples; i++) {
Robert Carre07e1032018-11-26 12:55:53 -0800368 mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700369 }
370}
371
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700372static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
373 // Apply perspective transform like Skia.
374 float newX = matrix[0] * x + matrix[1] * y + matrix[2];
375 float newY = matrix[3] * x + matrix[4] * y + matrix[5];
376 float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
377 if (newZ) {
378 newZ = 1.0f / newZ;
379 }
380 *outX = newX * newZ;
381 *outY = newY * newZ;
382}
383
384static float transformAngle(const float matrix[9], float angleRadians,
385 float originX, float originY) {
Jeff Brown5912f952013-07-01 19:10:31 -0700386 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
387 // Coordinate system: down is increasing Y, right is increasing X.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700388 float x = sinf(angleRadians);
389 float y = -cosf(angleRadians);
390 transformPoint(matrix, x, y, &x, &y);
391 x -= originX;
392 y -= originY;
Jeff Brown5912f952013-07-01 19:10:31 -0700393
394 // Derive the transformed vector's clockwise angle from vertical.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700395 float result = atan2f(x, -y);
Jeff Brown5912f952013-07-01 19:10:31 -0700396 if (result < - M_PI_2) {
397 result += M_PI;
398 } else if (result > M_PI_2) {
399 result -= M_PI;
400 }
401 return result;
402}
403
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700404void MotionEvent::transform(const float matrix[9]) {
Jeff Brown5912f952013-07-01 19:10:31 -0700405 // The tricky part of this implementation is to preserve the value of
406 // rawX and rawY. So we apply the transformation to the first point
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700407 // then derive an appropriate new X/Y offset that will preserve rawX
408 // and rawY for that point.
409 float oldXOffset = mXOffset;
410 float oldYOffset = mYOffset;
411 float newX, newY;
Jeff Brown5912f952013-07-01 19:10:31 -0700412 float rawX = getRawX(0);
413 float rawY = getRawY(0);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700414 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
415 mXOffset = newX - rawX;
416 mYOffset = newY - rawY;
Jeff Brown5912f952013-07-01 19:10:31 -0700417
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700418 // Determine how the origin is transformed by the matrix so that we
419 // can transform orientation vectors.
420 float originX, originY;
421 transformPoint(matrix, 0, 0, &originX, &originY);
Jeff Brown5912f952013-07-01 19:10:31 -0700422
423 // Apply the transformation to all samples.
424 size_t numSamples = mSamplePointerCoords.size();
425 for (size_t i = 0; i < numSamples; i++) {
426 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
427 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
428 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700429 transformPoint(matrix, x, y, &x, &y);
430 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
431 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
Jeff Brown5912f952013-07-01 19:10:31 -0700432
433 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700434 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
435 transformAngle(matrix, orientation, originX, originY));
Jeff Brown5912f952013-07-01 19:10:31 -0700436 }
437}
438
Elliott Hughes6071da72015-08-12 15:27:47 -0700439#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700440status_t MotionEvent::readFromParcel(Parcel* parcel) {
441 size_t pointerCount = parcel->readInt32();
442 size_t sampleCount = parcel->readInt32();
Flanker552a8a52015-09-07 15:28:58 +0800443 if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
444 sampleCount == 0 || sampleCount > MAX_SAMPLES) {
Jeff Brown5912f952013-07-01 19:10:31 -0700445 return BAD_VALUE;
446 }
447
448 mDeviceId = parcel->readInt32();
449 mSource = parcel->readInt32();
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800450 mDisplayId = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700451 mAction = parcel->readInt32();
Michael Wright7b159c92015-05-14 14:48:03 +0100452 mActionButton = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700453 mFlags = parcel->readInt32();
454 mEdgeFlags = parcel->readInt32();
455 mMetaState = parcel->readInt32();
456 mButtonState = parcel->readInt32();
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800457 mClassification = static_cast<MotionClassification>(parcel->readByte());
Jeff Brown5912f952013-07-01 19:10:31 -0700458 mXOffset = parcel->readFloat();
459 mYOffset = parcel->readFloat();
460 mXPrecision = parcel->readFloat();
461 mYPrecision = parcel->readFloat();
462 mDownTime = parcel->readInt64();
463
464 mPointerProperties.clear();
465 mPointerProperties.setCapacity(pointerCount);
466 mSampleEventTimes.clear();
467 mSampleEventTimes.setCapacity(sampleCount);
468 mSamplePointerCoords.clear();
469 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
470
471 for (size_t i = 0; i < pointerCount; i++) {
472 mPointerProperties.push();
473 PointerProperties& properties = mPointerProperties.editTop();
474 properties.id = parcel->readInt32();
475 properties.toolType = parcel->readInt32();
476 }
477
Dan Austinc94fc452015-09-22 14:22:41 -0700478 while (sampleCount > 0) {
479 sampleCount--;
Jeff Brown5912f952013-07-01 19:10:31 -0700480 mSampleEventTimes.push(parcel->readInt64());
481 for (size_t i = 0; i < pointerCount; i++) {
482 mSamplePointerCoords.push();
483 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
484 if (status) {
485 return status;
486 }
487 }
488 }
489 return OK;
490}
491
492status_t MotionEvent::writeToParcel(Parcel* parcel) const {
493 size_t pointerCount = mPointerProperties.size();
494 size_t sampleCount = mSampleEventTimes.size();
495
496 parcel->writeInt32(pointerCount);
497 parcel->writeInt32(sampleCount);
498
499 parcel->writeInt32(mDeviceId);
500 parcel->writeInt32(mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800501 parcel->writeInt32(mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700502 parcel->writeInt32(mAction);
Michael Wright7b159c92015-05-14 14:48:03 +0100503 parcel->writeInt32(mActionButton);
Jeff Brown5912f952013-07-01 19:10:31 -0700504 parcel->writeInt32(mFlags);
505 parcel->writeInt32(mEdgeFlags);
506 parcel->writeInt32(mMetaState);
507 parcel->writeInt32(mButtonState);
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800508 parcel->writeByte(static_cast<int8_t>(mClassification));
Jeff Brown5912f952013-07-01 19:10:31 -0700509 parcel->writeFloat(mXOffset);
510 parcel->writeFloat(mYOffset);
511 parcel->writeFloat(mXPrecision);
512 parcel->writeFloat(mYPrecision);
513 parcel->writeInt64(mDownTime);
514
515 for (size_t i = 0; i < pointerCount; i++) {
516 const PointerProperties& properties = mPointerProperties.itemAt(i);
517 parcel->writeInt32(properties.id);
518 parcel->writeInt32(properties.toolType);
519 }
520
521 const PointerCoords* pc = mSamplePointerCoords.array();
522 for (size_t h = 0; h < sampleCount; h++) {
523 parcel->writeInt64(mSampleEventTimes.itemAt(h));
524 for (size_t i = 0; i < pointerCount; i++) {
525 status_t status = (pc++)->writeToParcel(parcel);
526 if (status) {
527 return status;
528 }
529 }
530 }
531 return OK;
532}
533#endif
534
535bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
536 if (source & AINPUT_SOURCE_CLASS_POINTER) {
537 // Specifically excludes HOVER_MOVE and SCROLL.
538 switch (action & AMOTION_EVENT_ACTION_MASK) {
539 case AMOTION_EVENT_ACTION_DOWN:
540 case AMOTION_EVENT_ACTION_MOVE:
541 case AMOTION_EVENT_ACTION_UP:
542 case AMOTION_EVENT_ACTION_POINTER_DOWN:
543 case AMOTION_EVENT_ACTION_POINTER_UP:
544 case AMOTION_EVENT_ACTION_CANCEL:
545 case AMOTION_EVENT_ACTION_OUTSIDE:
546 return true;
547 }
548 }
549 return false;
550}
551
Michael Wright872db4f2014-04-22 15:03:51 -0700552const char* MotionEvent::getLabel(int32_t axis) {
553 return getAxisLabel(axis);
554}
555
556int32_t MotionEvent::getAxisFromLabel(const char* label) {
557 return getAxisByLabel(label);
558}
559
Jeff Brown5912f952013-07-01 19:10:31 -0700560
561// --- PooledInputEventFactory ---
562
563PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
564 mMaxPoolSize(maxPoolSize) {
565}
566
567PooledInputEventFactory::~PooledInputEventFactory() {
568 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
569 delete mKeyEventPool.itemAt(i);
570 }
571 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
572 delete mMotionEventPool.itemAt(i);
573 }
574}
575
576KeyEvent* PooledInputEventFactory::createKeyEvent() {
577 if (!mKeyEventPool.isEmpty()) {
578 KeyEvent* event = mKeyEventPool.top();
579 mKeyEventPool.pop();
580 return event;
581 }
582 return new KeyEvent();
583}
584
585MotionEvent* PooledInputEventFactory::createMotionEvent() {
586 if (!mMotionEventPool.isEmpty()) {
587 MotionEvent* event = mMotionEventPool.top();
588 mMotionEventPool.pop();
589 return event;
590 }
591 return new MotionEvent();
592}
593
594void PooledInputEventFactory::recycle(InputEvent* event) {
595 switch (event->getType()) {
596 case AINPUT_EVENT_TYPE_KEY:
597 if (mKeyEventPool.size() < mMaxPoolSize) {
598 mKeyEventPool.push(static_cast<KeyEvent*>(event));
599 return;
600 }
601 break;
602 case AINPUT_EVENT_TYPE_MOTION:
603 if (mMotionEventPool.size() < mMaxPoolSize) {
604 mMotionEventPool.push(static_cast<MotionEvent*>(event));
605 return;
606 }
607 break;
608 }
609 delete event;
610}
611
612} // namespace android