blob: 8ccbc7f650d04434c68dc0bb58e1243e81f390c0 [file] [log] [blame]
Jeff Brown5912f952013-07-01 19:10:31 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Input"
18//#define LOG_NDEBUG 0
19
Jeff Brown5912f952013-07-01 19:10:31 -070020#include <limits.h>
21
22#include <input/Input.h>
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080023#include <input/InputDevice.h>
Michael Wright872db4f2014-04-22 15:03:51 -070024#include <input/InputEventLabels.h>
Jeff Brown5912f952013-07-01 19:10:31 -070025
Elliott Hughes6071da72015-08-12 15:27:47 -070026#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -070027#include <binder/Parcel.h>
Jeff Brown5912f952013-07-01 19:10:31 -070028#endif
29
30namespace android {
31
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -080032const char* motionClassificationToString(MotionClassification classification) {
33 switch (classification) {
34 case MotionClassification::NONE:
35 return "NONE";
36 case MotionClassification::AMBIGUOUS_GESTURE:
37 return "AMBIGUOUS_GESTURE";
38 case MotionClassification::DEEP_PRESS:
39 return "DEEP_PRESS";
40 }
41}
42
Jeff Brown5912f952013-07-01 19:10:31 -070043// --- InputEvent ---
44
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080045const char* inputEventTypeToString(int32_t type) {
46 switch (type) {
47 case AINPUT_EVENT_TYPE_KEY: {
48 return "KEY";
49 }
50 case AINPUT_EVENT_TYPE_MOTION: {
51 return "MOTION";
52 }
53 case AINPUT_EVENT_TYPE_FOCUS: {
54 return "FOCUS";
55 }
56 }
57 return "UNKNOWN";
58}
59
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010060void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
Jeff Brown5912f952013-07-01 19:10:31 -070061 mDeviceId = deviceId;
62 mSource = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010063 mDisplayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -070064}
65
66void InputEvent::initialize(const InputEvent& from) {
67 mDeviceId = from.mDeviceId;
68 mSource = from.mSource;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010069 mDisplayId = from.mDisplayId;
Jeff Brown5912f952013-07-01 19:10:31 -070070}
71
72// --- KeyEvent ---
73
Michael Wright872db4f2014-04-22 15:03:51 -070074const char* KeyEvent::getLabel(int32_t keyCode) {
75 return getLabelByKeyCode(keyCode);
Jeff Brown5912f952013-07-01 19:10:31 -070076}
77
Michael Wright872db4f2014-04-22 15:03:51 -070078int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
79 return getKeyCodeByLabel(label);
Jeff Brown5912f952013-07-01 19:10:31 -070080}
81
82void KeyEvent::initialize(
83 int32_t deviceId,
84 int32_t source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010085 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -070086 int32_t action,
87 int32_t flags,
88 int32_t keyCode,
89 int32_t scanCode,
90 int32_t metaState,
91 int32_t repeatCount,
92 nsecs_t downTime,
93 nsecs_t eventTime) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010094 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -070095 mAction = action;
96 mFlags = flags;
97 mKeyCode = keyCode;
98 mScanCode = scanCode;
99 mMetaState = metaState;
100 mRepeatCount = repeatCount;
101 mDownTime = downTime;
102 mEventTime = eventTime;
103}
104
105void KeyEvent::initialize(const KeyEvent& from) {
106 InputEvent::initialize(from);
107 mAction = from.mAction;
108 mFlags = from.mFlags;
109 mKeyCode = from.mKeyCode;
110 mScanCode = from.mScanCode;
111 mMetaState = from.mMetaState;
112 mRepeatCount = from.mRepeatCount;
113 mDownTime = from.mDownTime;
114 mEventTime = from.mEventTime;
115}
116
117
118// --- PointerCoords ---
119
120float PointerCoords::getAxisValue(int32_t axis) const {
Michael Wright38dcdff2014-03-19 12:06:10 -0700121 if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
Jeff Brown5912f952013-07-01 19:10:31 -0700122 return 0;
123 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700124 return values[BitSet64::getIndexOfBit(bits, axis)];
Jeff Brown5912f952013-07-01 19:10:31 -0700125}
126
127status_t PointerCoords::setAxisValue(int32_t axis, float value) {
128 if (axis < 0 || axis > 63) {
129 return NAME_NOT_FOUND;
130 }
131
Michael Wright38dcdff2014-03-19 12:06:10 -0700132 uint32_t index = BitSet64::getIndexOfBit(bits, axis);
133 if (!BitSet64::hasBit(bits, axis)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700134 if (value == 0) {
135 return OK; // axes with value 0 do not need to be stored
136 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700137
138 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700139 if (count >= MAX_AXES) {
140 tooManyAxes(axis);
141 return NO_MEMORY;
142 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700143 BitSet64::markBit(bits, axis);
Jeff Brown5912f952013-07-01 19:10:31 -0700144 for (uint32_t i = count; i > index; i--) {
145 values[i] = values[i - 1];
146 }
147 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700148
Jeff Brown5912f952013-07-01 19:10:31 -0700149 values[index] = value;
150 return OK;
151}
152
153static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
154 float value = c.getAxisValue(axis);
155 if (value != 0) {
156 c.setAxisValue(axis, value * scaleFactor);
157 }
158}
159
Robert Carre07e1032018-11-26 12:55:53 -0800160void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
Jeff Brown5912f952013-07-01 19:10:31 -0700161 // No need to scale pressure or size since they are normalized.
162 // No need to scale orientation since it is meaningless to do so.
Robert Carre07e1032018-11-26 12:55:53 -0800163
164 // If there is a global scale factor, it is included in the windowX/YScale
165 // so we don't need to apply it twice to the X/Y axes.
166 // However we don't want to apply any windowXYScale not included in the global scale
167 // to the TOUCH_MAJOR/MINOR coordinates.
168 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
169 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
170 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
171 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
172 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
173 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
174}
175
176void PointerCoords::scale(float globalScaleFactor) {
177 scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700178}
179
Jeff Brownf086ddb2014-02-11 14:28:48 -0800180void PointerCoords::applyOffset(float xOffset, float yOffset) {
181 setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
182 setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
183}
184
Elliott Hughes6071da72015-08-12 15:27:47 -0700185#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700186status_t PointerCoords::readFromParcel(Parcel* parcel) {
187 bits = parcel->readInt64();
188
Michael Wright38dcdff2014-03-19 12:06:10 -0700189 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700190 if (count > MAX_AXES) {
191 return BAD_VALUE;
192 }
193
194 for (uint32_t i = 0; i < count; i++) {
195 values[i] = parcel->readFloat();
196 }
197 return OK;
198}
199
200status_t PointerCoords::writeToParcel(Parcel* parcel) const {
201 parcel->writeInt64(bits);
202
Michael Wright38dcdff2014-03-19 12:06:10 -0700203 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700204 for (uint32_t i = 0; i < count; i++) {
205 parcel->writeFloat(values[i]);
206 }
207 return OK;
208}
209#endif
210
211void PointerCoords::tooManyAxes(int axis) {
212 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
213 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
214}
215
216bool PointerCoords::operator==(const PointerCoords& other) const {
217 if (bits != other.bits) {
218 return false;
219 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700220 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700221 for (uint32_t i = 0; i < count; i++) {
222 if (values[i] != other.values[i]) {
223 return false;
224 }
225 }
226 return true;
227}
228
229void PointerCoords::copyFrom(const PointerCoords& other) {
230 bits = other.bits;
Michael Wright38dcdff2014-03-19 12:06:10 -0700231 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700232 for (uint32_t i = 0; i < count; i++) {
233 values[i] = other.values[i];
234 }
235}
236
237
238// --- PointerProperties ---
239
240bool PointerProperties::operator==(const PointerProperties& other) const {
241 return id == other.id
242 && toolType == other.toolType;
243}
244
245void PointerProperties::copyFrom(const PointerProperties& other) {
246 id = other.id;
247 toolType = other.toolType;
248}
249
250
251// --- MotionEvent ---
252
Garfield Tan00f511d2019-06-12 16:55:40 -0700253void MotionEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
254 int32_t actionButton, int32_t flags, int32_t edgeFlags,
255 int32_t metaState, int32_t buttonState,
256 MotionClassification classification, float xOffset, float yOffset,
Garfield Tan937bb832019-07-25 17:48:31 -0700257 float xPrecision, float yPrecision, float rawXCursorPosition,
258 float rawYCursorPosition, nsecs_t downTime, nsecs_t eventTime,
Garfield Tan00f511d2019-06-12 16:55:40 -0700259 size_t pointerCount, const PointerProperties* pointerProperties,
260 const PointerCoords* pointerCoords) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100261 InputEvent::initialize(deviceId, source, displayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700262 mAction = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100263 mActionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700264 mFlags = flags;
265 mEdgeFlags = edgeFlags;
266 mMetaState = metaState;
267 mButtonState = buttonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800268 mClassification = classification;
Jeff Brown5912f952013-07-01 19:10:31 -0700269 mXOffset = xOffset;
270 mYOffset = yOffset;
271 mXPrecision = xPrecision;
272 mYPrecision = yPrecision;
Garfield Tan937bb832019-07-25 17:48:31 -0700273 mRawXCursorPosition = rawXCursorPosition;
274 mRawYCursorPosition = rawYCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700275 mDownTime = downTime;
276 mPointerProperties.clear();
277 mPointerProperties.appendArray(pointerProperties, pointerCount);
278 mSampleEventTimes.clear();
279 mSamplePointerCoords.clear();
280 addSample(eventTime, pointerCoords);
281}
282
283void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100284 InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700285 mAction = other->mAction;
Michael Wright7b159c92015-05-14 14:48:03 +0100286 mActionButton = other->mActionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700287 mFlags = other->mFlags;
288 mEdgeFlags = other->mEdgeFlags;
289 mMetaState = other->mMetaState;
290 mButtonState = other->mButtonState;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800291 mClassification = other->mClassification;
Jeff Brown5912f952013-07-01 19:10:31 -0700292 mXOffset = other->mXOffset;
293 mYOffset = other->mYOffset;
294 mXPrecision = other->mXPrecision;
295 mYPrecision = other->mYPrecision;
Garfield Tan937bb832019-07-25 17:48:31 -0700296 mRawXCursorPosition = other->mRawXCursorPosition;
297 mRawYCursorPosition = other->mRawYCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700298 mDownTime = other->mDownTime;
299 mPointerProperties = other->mPointerProperties;
300
301 if (keepHistory) {
302 mSampleEventTimes = other->mSampleEventTimes;
303 mSamplePointerCoords = other->mSamplePointerCoords;
304 } else {
305 mSampleEventTimes.clear();
306 mSampleEventTimes.push(other->getEventTime());
307 mSamplePointerCoords.clear();
308 size_t pointerCount = other->getPointerCount();
309 size_t historySize = other->getHistorySize();
310 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
311 + (historySize * pointerCount), pointerCount);
312 }
313}
314
315void MotionEvent::addSample(
316 int64_t eventTime,
317 const PointerCoords* pointerCoords) {
318 mSampleEventTimes.push(eventTime);
319 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
320}
321
Garfield Tan00f511d2019-06-12 16:55:40 -0700322float MotionEvent::getXCursorPosition() const {
323 const float rawX = getRawXCursorPosition();
324 return rawX + mXOffset;
325}
326
327float MotionEvent::getYCursorPosition() const {
328 const float rawY = getRawYCursorPosition();
329 return rawY + mYOffset;
330}
331
Garfield Tan937bb832019-07-25 17:48:31 -0700332void MotionEvent::setCursorPosition(float x, float y) {
333 mRawXCursorPosition = x - mXOffset;
334 mRawYCursorPosition = y - mYOffset;
335}
336
Jeff Brown5912f952013-07-01 19:10:31 -0700337const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
338 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
339}
340
341float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
342 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
343}
344
345float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
346 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
347 switch (axis) {
348 case AMOTION_EVENT_AXIS_X:
349 return value + mXOffset;
350 case AMOTION_EVENT_AXIS_Y:
351 return value + mYOffset;
352 }
353 return value;
354}
355
356const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
357 size_t pointerIndex, size_t historicalIndex) const {
358 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
359}
360
361float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
362 size_t historicalIndex) const {
363 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
364}
365
366float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
367 size_t historicalIndex) const {
368 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
369 switch (axis) {
370 case AMOTION_EVENT_AXIS_X:
371 return value + mXOffset;
372 case AMOTION_EVENT_AXIS_Y:
373 return value + mYOffset;
374 }
375 return value;
376}
377
378ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
379 size_t pointerCount = mPointerProperties.size();
380 for (size_t i = 0; i < pointerCount; i++) {
381 if (mPointerProperties.itemAt(i).id == pointerId) {
382 return i;
383 }
384 }
385 return -1;
386}
387
388void MotionEvent::offsetLocation(float xOffset, float yOffset) {
389 mXOffset += xOffset;
390 mYOffset += yOffset;
391}
392
Robert Carre07e1032018-11-26 12:55:53 -0800393void MotionEvent::scale(float globalScaleFactor) {
394 mXOffset *= globalScaleFactor;
395 mYOffset *= globalScaleFactor;
396 mXPrecision *= globalScaleFactor;
397 mYPrecision *= globalScaleFactor;
Jeff Brown5912f952013-07-01 19:10:31 -0700398
399 size_t numSamples = mSamplePointerCoords.size();
400 for (size_t i = 0; i < numSamples; i++) {
Robert Carre07e1032018-11-26 12:55:53 -0800401 mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
Jeff Brown5912f952013-07-01 19:10:31 -0700402 }
403}
404
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700405static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
406 // Apply perspective transform like Skia.
407 float newX = matrix[0] * x + matrix[1] * y + matrix[2];
408 float newY = matrix[3] * x + matrix[4] * y + matrix[5];
409 float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
410 if (newZ) {
411 newZ = 1.0f / newZ;
412 }
413 *outX = newX * newZ;
414 *outY = newY * newZ;
415}
416
417static float transformAngle(const float matrix[9], float angleRadians,
418 float originX, float originY) {
Jeff Brown5912f952013-07-01 19:10:31 -0700419 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
420 // Coordinate system: down is increasing Y, right is increasing X.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700421 float x = sinf(angleRadians);
422 float y = -cosf(angleRadians);
423 transformPoint(matrix, x, y, &x, &y);
424 x -= originX;
425 y -= originY;
Jeff Brown5912f952013-07-01 19:10:31 -0700426
427 // Derive the transformed vector's clockwise angle from vertical.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700428 float result = atan2f(x, -y);
Jeff Brown5912f952013-07-01 19:10:31 -0700429 if (result < - M_PI_2) {
430 result += M_PI;
431 } else if (result > M_PI_2) {
432 result -= M_PI;
433 }
434 return result;
435}
436
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700437void MotionEvent::transform(const float matrix[9]) {
Jeff Brown5912f952013-07-01 19:10:31 -0700438 // The tricky part of this implementation is to preserve the value of
439 // rawX and rawY. So we apply the transformation to the first point
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700440 // then derive an appropriate new X/Y offset that will preserve rawX
441 // and rawY for that point.
442 float oldXOffset = mXOffset;
443 float oldYOffset = mYOffset;
444 float newX, newY;
Jeff Brown5912f952013-07-01 19:10:31 -0700445 float rawX = getRawX(0);
446 float rawY = getRawY(0);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700447 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
448 mXOffset = newX - rawX;
449 mYOffset = newY - rawY;
Jeff Brown5912f952013-07-01 19:10:31 -0700450
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700451 // Determine how the origin is transformed by the matrix so that we
452 // can transform orientation vectors.
453 float originX, originY;
454 transformPoint(matrix, 0, 0, &originX, &originY);
Jeff Brown5912f952013-07-01 19:10:31 -0700455
Garfield Tan00f511d2019-06-12 16:55:40 -0700456 // Apply the transformation to cursor position.
Garfield Tan937bb832019-07-25 17:48:31 -0700457 if (isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) {
458 float x = mRawXCursorPosition + oldXOffset;
459 float y = mRawYCursorPosition + oldYOffset;
Garfield Tan00f511d2019-06-12 16:55:40 -0700460 transformPoint(matrix, x, y, &x, &y);
Garfield Tan937bb832019-07-25 17:48:31 -0700461 mRawXCursorPosition = x - mXOffset;
462 mRawYCursorPosition = y - mYOffset;
Garfield Tan00f511d2019-06-12 16:55:40 -0700463 }
464
Jeff Brown5912f952013-07-01 19:10:31 -0700465 // Apply the transformation to all samples.
466 size_t numSamples = mSamplePointerCoords.size();
467 for (size_t i = 0; i < numSamples; i++) {
468 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
469 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
470 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700471 transformPoint(matrix, x, y, &x, &y);
472 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
473 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
Jeff Brown5912f952013-07-01 19:10:31 -0700474
475 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700476 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
477 transformAngle(matrix, orientation, originX, originY));
Jeff Brown5912f952013-07-01 19:10:31 -0700478 }
479}
480
Elliott Hughes6071da72015-08-12 15:27:47 -0700481#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700482status_t MotionEvent::readFromParcel(Parcel* parcel) {
483 size_t pointerCount = parcel->readInt32();
484 size_t sampleCount = parcel->readInt32();
Flanker552a8a52015-09-07 15:28:58 +0800485 if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
486 sampleCount == 0 || sampleCount > MAX_SAMPLES) {
Jeff Brown5912f952013-07-01 19:10:31 -0700487 return BAD_VALUE;
488 }
489
490 mDeviceId = parcel->readInt32();
491 mSource = parcel->readInt32();
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800492 mDisplayId = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700493 mAction = parcel->readInt32();
Michael Wright7b159c92015-05-14 14:48:03 +0100494 mActionButton = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700495 mFlags = parcel->readInt32();
496 mEdgeFlags = parcel->readInt32();
497 mMetaState = parcel->readInt32();
498 mButtonState = parcel->readInt32();
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800499 mClassification = static_cast<MotionClassification>(parcel->readByte());
Jeff Brown5912f952013-07-01 19:10:31 -0700500 mXOffset = parcel->readFloat();
501 mYOffset = parcel->readFloat();
502 mXPrecision = parcel->readFloat();
503 mYPrecision = parcel->readFloat();
Garfield Tan937bb832019-07-25 17:48:31 -0700504 mRawXCursorPosition = parcel->readFloat();
505 mRawYCursorPosition = parcel->readFloat();
Jeff Brown5912f952013-07-01 19:10:31 -0700506 mDownTime = parcel->readInt64();
507
508 mPointerProperties.clear();
509 mPointerProperties.setCapacity(pointerCount);
510 mSampleEventTimes.clear();
511 mSampleEventTimes.setCapacity(sampleCount);
512 mSamplePointerCoords.clear();
513 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
514
515 for (size_t i = 0; i < pointerCount; i++) {
516 mPointerProperties.push();
517 PointerProperties& properties = mPointerProperties.editTop();
518 properties.id = parcel->readInt32();
519 properties.toolType = parcel->readInt32();
520 }
521
Dan Austinc94fc452015-09-22 14:22:41 -0700522 while (sampleCount > 0) {
523 sampleCount--;
Jeff Brown5912f952013-07-01 19:10:31 -0700524 mSampleEventTimes.push(parcel->readInt64());
525 for (size_t i = 0; i < pointerCount; i++) {
526 mSamplePointerCoords.push();
527 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
528 if (status) {
529 return status;
530 }
531 }
532 }
533 return OK;
534}
535
536status_t MotionEvent::writeToParcel(Parcel* parcel) const {
537 size_t pointerCount = mPointerProperties.size();
538 size_t sampleCount = mSampleEventTimes.size();
539
540 parcel->writeInt32(pointerCount);
541 parcel->writeInt32(sampleCount);
542
543 parcel->writeInt32(mDeviceId);
544 parcel->writeInt32(mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800545 parcel->writeInt32(mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700546 parcel->writeInt32(mAction);
Michael Wright7b159c92015-05-14 14:48:03 +0100547 parcel->writeInt32(mActionButton);
Jeff Brown5912f952013-07-01 19:10:31 -0700548 parcel->writeInt32(mFlags);
549 parcel->writeInt32(mEdgeFlags);
550 parcel->writeInt32(mMetaState);
551 parcel->writeInt32(mButtonState);
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800552 parcel->writeByte(static_cast<int8_t>(mClassification));
Jeff Brown5912f952013-07-01 19:10:31 -0700553 parcel->writeFloat(mXOffset);
554 parcel->writeFloat(mYOffset);
555 parcel->writeFloat(mXPrecision);
556 parcel->writeFloat(mYPrecision);
Garfield Tan937bb832019-07-25 17:48:31 -0700557 parcel->writeFloat(mRawXCursorPosition);
558 parcel->writeFloat(mRawYCursorPosition);
Jeff Brown5912f952013-07-01 19:10:31 -0700559 parcel->writeInt64(mDownTime);
560
561 for (size_t i = 0; i < pointerCount; i++) {
562 const PointerProperties& properties = mPointerProperties.itemAt(i);
563 parcel->writeInt32(properties.id);
564 parcel->writeInt32(properties.toolType);
565 }
566
567 const PointerCoords* pc = mSamplePointerCoords.array();
568 for (size_t h = 0; h < sampleCount; h++) {
569 parcel->writeInt64(mSampleEventTimes.itemAt(h));
570 for (size_t i = 0; i < pointerCount; i++) {
571 status_t status = (pc++)->writeToParcel(parcel);
572 if (status) {
573 return status;
574 }
575 }
576 }
577 return OK;
578}
579#endif
580
581bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
582 if (source & AINPUT_SOURCE_CLASS_POINTER) {
583 // Specifically excludes HOVER_MOVE and SCROLL.
584 switch (action & AMOTION_EVENT_ACTION_MASK) {
585 case AMOTION_EVENT_ACTION_DOWN:
586 case AMOTION_EVENT_ACTION_MOVE:
587 case AMOTION_EVENT_ACTION_UP:
588 case AMOTION_EVENT_ACTION_POINTER_DOWN:
589 case AMOTION_EVENT_ACTION_POINTER_UP:
590 case AMOTION_EVENT_ACTION_CANCEL:
591 case AMOTION_EVENT_ACTION_OUTSIDE:
592 return true;
593 }
594 }
595 return false;
596}
597
Michael Wright872db4f2014-04-22 15:03:51 -0700598const char* MotionEvent::getLabel(int32_t axis) {
599 return getAxisLabel(axis);
600}
601
602int32_t MotionEvent::getAxisFromLabel(const char* label) {
603 return getAxisByLabel(label);
604}
605
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800606// --- FocusEvent ---
607
608void FocusEvent::initialize(bool hasFocus, bool inTouchMode) {
609 InputEvent::initialize(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
610 ADISPLAY_ID_NONE);
611 mHasFocus = hasFocus;
612 mInTouchMode = inTouchMode;
613}
614
615void FocusEvent::initialize(const FocusEvent& from) {
616 InputEvent::initialize(from);
617 mHasFocus = from.mHasFocus;
618 mInTouchMode = from.mInTouchMode;
619}
Jeff Brown5912f952013-07-01 19:10:31 -0700620
621// --- PooledInputEventFactory ---
622
623PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
624 mMaxPoolSize(maxPoolSize) {
625}
626
627PooledInputEventFactory::~PooledInputEventFactory() {
Jeff Brown5912f952013-07-01 19:10:31 -0700628}
629
630KeyEvent* PooledInputEventFactory::createKeyEvent() {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800631 if (mKeyEventPool.empty()) {
632 return new KeyEvent();
Jeff Brown5912f952013-07-01 19:10:31 -0700633 }
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800634 KeyEvent* event = mKeyEventPool.front().release();
635 mKeyEventPool.pop();
636 return event;
Jeff Brown5912f952013-07-01 19:10:31 -0700637}
638
639MotionEvent* PooledInputEventFactory::createMotionEvent() {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800640 if (mMotionEventPool.empty()) {
641 return new MotionEvent();
Jeff Brown5912f952013-07-01 19:10:31 -0700642 }
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800643 MotionEvent* event = mMotionEventPool.front().release();
644 mMotionEventPool.pop();
645 return event;
Jeff Brown5912f952013-07-01 19:10:31 -0700646}
647
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800648FocusEvent* PooledInputEventFactory::createFocusEvent() {
649 if (mFocusEventPool.empty()) {
650 return new FocusEvent();
651 }
652 FocusEvent* event = mFocusEventPool.front().release();
653 mFocusEventPool.pop();
654 return event;
655}
656
Jeff Brown5912f952013-07-01 19:10:31 -0700657void PooledInputEventFactory::recycle(InputEvent* event) {
658 switch (event->getType()) {
659 case AINPUT_EVENT_TYPE_KEY:
660 if (mKeyEventPool.size() < mMaxPoolSize) {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800661 mKeyEventPool.push(std::unique_ptr<KeyEvent>(static_cast<KeyEvent*>(event)));
Jeff Brown5912f952013-07-01 19:10:31 -0700662 return;
663 }
664 break;
665 case AINPUT_EVENT_TYPE_MOTION:
666 if (mMotionEventPool.size() < mMaxPoolSize) {
Siarhei Vishniakou727a44e2019-11-23 12:59:16 -0800667 mMotionEventPool.push(std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event)));
Jeff Brown5912f952013-07-01 19:10:31 -0700668 return;
669 }
670 break;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800671 case AINPUT_EVENT_TYPE_FOCUS:
672 if (mFocusEventPool.size() < mMaxPoolSize) {
673 mFocusEventPool.push(std::unique_ptr<FocusEvent>(static_cast<FocusEvent*>(event)));
674 return;
675 }
676 break;
Jeff Brown5912f952013-07-01 19:10:31 -0700677 }
678 delete event;
679}
680
681} // namespace android