blob: db27e11e24090814702aeb46a65805922a48c379 [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
34void InputEvent::initialize(int32_t deviceId, int32_t source) {
35 mDeviceId = deviceId;
36 mSource = source;
37}
38
39void InputEvent::initialize(const InputEvent& from) {
40 mDeviceId = from.mDeviceId;
41 mSource = from.mSource;
42}
43
44// --- KeyEvent ---
45
Michael Wright872db4f2014-04-22 15:03:51 -070046const char* KeyEvent::getLabel(int32_t keyCode) {
47 return getLabelByKeyCode(keyCode);
Jeff Brown5912f952013-07-01 19:10:31 -070048}
49
Michael Wright872db4f2014-04-22 15:03:51 -070050int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
51 return getKeyCodeByLabel(label);
Jeff Brown5912f952013-07-01 19:10:31 -070052}
53
54void KeyEvent::initialize(
55 int32_t deviceId,
56 int32_t source,
57 int32_t action,
58 int32_t flags,
59 int32_t keyCode,
60 int32_t scanCode,
61 int32_t metaState,
62 int32_t repeatCount,
63 nsecs_t downTime,
64 nsecs_t eventTime) {
65 InputEvent::initialize(deviceId, source);
66 mAction = action;
67 mFlags = flags;
68 mKeyCode = keyCode;
69 mScanCode = scanCode;
70 mMetaState = metaState;
71 mRepeatCount = repeatCount;
72 mDownTime = downTime;
73 mEventTime = eventTime;
74}
75
76void KeyEvent::initialize(const KeyEvent& from) {
77 InputEvent::initialize(from);
78 mAction = from.mAction;
79 mFlags = from.mFlags;
80 mKeyCode = from.mKeyCode;
81 mScanCode = from.mScanCode;
82 mMetaState = from.mMetaState;
83 mRepeatCount = from.mRepeatCount;
84 mDownTime = from.mDownTime;
85 mEventTime = from.mEventTime;
86}
87
88
89// --- PointerCoords ---
90
91float PointerCoords::getAxisValue(int32_t axis) const {
Michael Wright38dcdff2014-03-19 12:06:10 -070092 if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
Jeff Brown5912f952013-07-01 19:10:31 -070093 return 0;
94 }
Michael Wright38dcdff2014-03-19 12:06:10 -070095 return values[BitSet64::getIndexOfBit(bits, axis)];
Jeff Brown5912f952013-07-01 19:10:31 -070096}
97
98status_t PointerCoords::setAxisValue(int32_t axis, float value) {
99 if (axis < 0 || axis > 63) {
100 return NAME_NOT_FOUND;
101 }
102
Michael Wright38dcdff2014-03-19 12:06:10 -0700103 uint32_t index = BitSet64::getIndexOfBit(bits, axis);
104 if (!BitSet64::hasBit(bits, axis)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700105 if (value == 0) {
106 return OK; // axes with value 0 do not need to be stored
107 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700108
109 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700110 if (count >= MAX_AXES) {
111 tooManyAxes(axis);
112 return NO_MEMORY;
113 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700114 BitSet64::markBit(bits, axis);
Jeff Brown5912f952013-07-01 19:10:31 -0700115 for (uint32_t i = count; i > index; i--) {
116 values[i] = values[i - 1];
117 }
118 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700119
Jeff Brown5912f952013-07-01 19:10:31 -0700120 values[index] = value;
121 return OK;
122}
123
124static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
125 float value = c.getAxisValue(axis);
126 if (value != 0) {
127 c.setAxisValue(axis, value * scaleFactor);
128 }
129}
130
131void PointerCoords::scale(float scaleFactor) {
132 // No need to scale pressure or size since they are normalized.
133 // No need to scale orientation since it is meaningless to do so.
134 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
135 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
136 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
137 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
138 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
139 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
140}
141
Jeff Brownf086ddb2014-02-11 14:28:48 -0800142void PointerCoords::applyOffset(float xOffset, float yOffset) {
143 setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
144 setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
145}
146
Elliott Hughes6071da72015-08-12 15:27:47 -0700147#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700148status_t PointerCoords::readFromParcel(Parcel* parcel) {
149 bits = parcel->readInt64();
150
Michael Wright38dcdff2014-03-19 12:06:10 -0700151 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700152 if (count > MAX_AXES) {
153 return BAD_VALUE;
154 }
155
156 for (uint32_t i = 0; i < count; i++) {
157 values[i] = parcel->readFloat();
158 }
159 return OK;
160}
161
162status_t PointerCoords::writeToParcel(Parcel* parcel) const {
163 parcel->writeInt64(bits);
164
Michael Wright38dcdff2014-03-19 12:06:10 -0700165 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700166 for (uint32_t i = 0; i < count; i++) {
167 parcel->writeFloat(values[i]);
168 }
169 return OK;
170}
171#endif
172
173void PointerCoords::tooManyAxes(int axis) {
174 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
175 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
176}
177
178bool PointerCoords::operator==(const PointerCoords& other) const {
179 if (bits != other.bits) {
180 return false;
181 }
Michael Wright38dcdff2014-03-19 12:06:10 -0700182 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700183 for (uint32_t i = 0; i < count; i++) {
184 if (values[i] != other.values[i]) {
185 return false;
186 }
187 }
188 return true;
189}
190
191void PointerCoords::copyFrom(const PointerCoords& other) {
192 bits = other.bits;
Michael Wright38dcdff2014-03-19 12:06:10 -0700193 uint32_t count = BitSet64::count(bits);
Jeff Brown5912f952013-07-01 19:10:31 -0700194 for (uint32_t i = 0; i < count; i++) {
195 values[i] = other.values[i];
196 }
197}
198
199
200// --- PointerProperties ---
201
202bool PointerProperties::operator==(const PointerProperties& other) const {
203 return id == other.id
204 && toolType == other.toolType;
205}
206
207void PointerProperties::copyFrom(const PointerProperties& other) {
208 id = other.id;
209 toolType = other.toolType;
210}
211
212
213// --- MotionEvent ---
214
215void MotionEvent::initialize(
216 int32_t deviceId,
217 int32_t source,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800218 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -0700219 int32_t action,
Michael Wright7b159c92015-05-14 14:48:03 +0100220 int32_t actionButton,
Jeff Brown5912f952013-07-01 19:10:31 -0700221 int32_t flags,
222 int32_t edgeFlags,
223 int32_t metaState,
224 int32_t buttonState,
225 float xOffset,
226 float yOffset,
227 float xPrecision,
228 float yPrecision,
229 nsecs_t downTime,
230 nsecs_t eventTime,
231 size_t pointerCount,
232 const PointerProperties* pointerProperties,
233 const PointerCoords* pointerCoords) {
234 InputEvent::initialize(deviceId, source);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800235 mDisplayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700236 mAction = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100237 mActionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700238 mFlags = flags;
239 mEdgeFlags = edgeFlags;
240 mMetaState = metaState;
241 mButtonState = buttonState;
242 mXOffset = xOffset;
243 mYOffset = yOffset;
244 mXPrecision = xPrecision;
245 mYPrecision = yPrecision;
246 mDownTime = downTime;
247 mPointerProperties.clear();
248 mPointerProperties.appendArray(pointerProperties, pointerCount);
249 mSampleEventTimes.clear();
250 mSamplePointerCoords.clear();
251 addSample(eventTime, pointerCoords);
252}
253
254void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
255 InputEvent::initialize(other->mDeviceId, other->mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800256 mDisplayId = other->mDisplayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700257 mAction = other->mAction;
Michael Wright7b159c92015-05-14 14:48:03 +0100258 mActionButton = other->mActionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700259 mFlags = other->mFlags;
260 mEdgeFlags = other->mEdgeFlags;
261 mMetaState = other->mMetaState;
262 mButtonState = other->mButtonState;
263 mXOffset = other->mXOffset;
264 mYOffset = other->mYOffset;
265 mXPrecision = other->mXPrecision;
266 mYPrecision = other->mYPrecision;
267 mDownTime = other->mDownTime;
268 mPointerProperties = other->mPointerProperties;
269
270 if (keepHistory) {
271 mSampleEventTimes = other->mSampleEventTimes;
272 mSamplePointerCoords = other->mSamplePointerCoords;
273 } else {
274 mSampleEventTimes.clear();
275 mSampleEventTimes.push(other->getEventTime());
276 mSamplePointerCoords.clear();
277 size_t pointerCount = other->getPointerCount();
278 size_t historySize = other->getHistorySize();
279 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
280 + (historySize * pointerCount), pointerCount);
281 }
282}
283
284void MotionEvent::addSample(
285 int64_t eventTime,
286 const PointerCoords* pointerCoords) {
287 mSampleEventTimes.push(eventTime);
288 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
289}
290
291const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
292 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
293}
294
295float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
296 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
297}
298
299float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
300 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
301 switch (axis) {
302 case AMOTION_EVENT_AXIS_X:
303 return value + mXOffset;
304 case AMOTION_EVENT_AXIS_Y:
305 return value + mYOffset;
306 }
307 return value;
308}
309
310const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
311 size_t pointerIndex, size_t historicalIndex) const {
312 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
313}
314
315float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
316 size_t historicalIndex) const {
317 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
318}
319
320float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
321 size_t historicalIndex) const {
322 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
323 switch (axis) {
324 case AMOTION_EVENT_AXIS_X:
325 return value + mXOffset;
326 case AMOTION_EVENT_AXIS_Y:
327 return value + mYOffset;
328 }
329 return value;
330}
331
332ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
333 size_t pointerCount = mPointerProperties.size();
334 for (size_t i = 0; i < pointerCount; i++) {
335 if (mPointerProperties.itemAt(i).id == pointerId) {
336 return i;
337 }
338 }
339 return -1;
340}
341
342void MotionEvent::offsetLocation(float xOffset, float yOffset) {
343 mXOffset += xOffset;
344 mYOffset += yOffset;
345}
346
347void MotionEvent::scale(float scaleFactor) {
348 mXOffset *= scaleFactor;
349 mYOffset *= scaleFactor;
350 mXPrecision *= scaleFactor;
351 mYPrecision *= scaleFactor;
352
353 size_t numSamples = mSamplePointerCoords.size();
354 for (size_t i = 0; i < numSamples; i++) {
355 mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
356 }
357}
358
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700359static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
360 // Apply perspective transform like Skia.
361 float newX = matrix[0] * x + matrix[1] * y + matrix[2];
362 float newY = matrix[3] * x + matrix[4] * y + matrix[5];
363 float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
364 if (newZ) {
365 newZ = 1.0f / newZ;
366 }
367 *outX = newX * newZ;
368 *outY = newY * newZ;
369}
370
371static float transformAngle(const float matrix[9], float angleRadians,
372 float originX, float originY) {
Jeff Brown5912f952013-07-01 19:10:31 -0700373 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
374 // Coordinate system: down is increasing Y, right is increasing X.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700375 float x = sinf(angleRadians);
376 float y = -cosf(angleRadians);
377 transformPoint(matrix, x, y, &x, &y);
378 x -= originX;
379 y -= originY;
Jeff Brown5912f952013-07-01 19:10:31 -0700380
381 // Derive the transformed vector's clockwise angle from vertical.
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700382 float result = atan2f(x, -y);
Jeff Brown5912f952013-07-01 19:10:31 -0700383 if (result < - M_PI_2) {
384 result += M_PI;
385 } else if (result > M_PI_2) {
386 result -= M_PI;
387 }
388 return result;
389}
390
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700391void MotionEvent::transform(const float matrix[9]) {
Jeff Brown5912f952013-07-01 19:10:31 -0700392 // The tricky part of this implementation is to preserve the value of
393 // rawX and rawY. So we apply the transformation to the first point
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700394 // then derive an appropriate new X/Y offset that will preserve rawX
395 // and rawY for that point.
396 float oldXOffset = mXOffset;
397 float oldYOffset = mYOffset;
398 float newX, newY;
Jeff Brown5912f952013-07-01 19:10:31 -0700399 float rawX = getRawX(0);
400 float rawY = getRawY(0);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700401 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
402 mXOffset = newX - rawX;
403 mYOffset = newY - rawY;
Jeff Brown5912f952013-07-01 19:10:31 -0700404
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700405 // Determine how the origin is transformed by the matrix so that we
406 // can transform orientation vectors.
407 float originX, originY;
408 transformPoint(matrix, 0, 0, &originX, &originY);
Jeff Brown5912f952013-07-01 19:10:31 -0700409
410 // Apply the transformation to all samples.
411 size_t numSamples = mSamplePointerCoords.size();
412 for (size_t i = 0; i < numSamples; i++) {
413 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
414 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
415 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700416 transformPoint(matrix, x, y, &x, &y);
417 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
418 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
Jeff Brown5912f952013-07-01 19:10:31 -0700419
420 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown5a2f68e2013-07-15 17:28:19 -0700421 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
422 transformAngle(matrix, orientation, originX, originY));
Jeff Brown5912f952013-07-01 19:10:31 -0700423 }
424}
425
Elliott Hughes6071da72015-08-12 15:27:47 -0700426#ifdef __ANDROID__
Jeff Brown5912f952013-07-01 19:10:31 -0700427status_t MotionEvent::readFromParcel(Parcel* parcel) {
428 size_t pointerCount = parcel->readInt32();
429 size_t sampleCount = parcel->readInt32();
Flanker552a8a52015-09-07 15:28:58 +0800430 if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
431 sampleCount == 0 || sampleCount > MAX_SAMPLES) {
Jeff Brown5912f952013-07-01 19:10:31 -0700432 return BAD_VALUE;
433 }
434
435 mDeviceId = parcel->readInt32();
436 mSource = parcel->readInt32();
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800437 mDisplayId = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700438 mAction = parcel->readInt32();
Michael Wright7b159c92015-05-14 14:48:03 +0100439 mActionButton = parcel->readInt32();
Jeff Brown5912f952013-07-01 19:10:31 -0700440 mFlags = parcel->readInt32();
441 mEdgeFlags = parcel->readInt32();
442 mMetaState = parcel->readInt32();
443 mButtonState = parcel->readInt32();
444 mXOffset = parcel->readFloat();
445 mYOffset = parcel->readFloat();
446 mXPrecision = parcel->readFloat();
447 mYPrecision = parcel->readFloat();
448 mDownTime = parcel->readInt64();
449
450 mPointerProperties.clear();
451 mPointerProperties.setCapacity(pointerCount);
452 mSampleEventTimes.clear();
453 mSampleEventTimes.setCapacity(sampleCount);
454 mSamplePointerCoords.clear();
455 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
456
457 for (size_t i = 0; i < pointerCount; i++) {
458 mPointerProperties.push();
459 PointerProperties& properties = mPointerProperties.editTop();
460 properties.id = parcel->readInt32();
461 properties.toolType = parcel->readInt32();
462 }
463
Dan Austinc94fc452015-09-22 14:22:41 -0700464 while (sampleCount > 0) {
465 sampleCount--;
Jeff Brown5912f952013-07-01 19:10:31 -0700466 mSampleEventTimes.push(parcel->readInt64());
467 for (size_t i = 0; i < pointerCount; i++) {
468 mSamplePointerCoords.push();
469 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
470 if (status) {
471 return status;
472 }
473 }
474 }
475 return OK;
476}
477
478status_t MotionEvent::writeToParcel(Parcel* parcel) const {
479 size_t pointerCount = mPointerProperties.size();
480 size_t sampleCount = mSampleEventTimes.size();
481
482 parcel->writeInt32(pointerCount);
483 parcel->writeInt32(sampleCount);
484
485 parcel->writeInt32(mDeviceId);
486 parcel->writeInt32(mSource);
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800487 parcel->writeInt32(mDisplayId);
Jeff Brown5912f952013-07-01 19:10:31 -0700488 parcel->writeInt32(mAction);
Michael Wright7b159c92015-05-14 14:48:03 +0100489 parcel->writeInt32(mActionButton);
Jeff Brown5912f952013-07-01 19:10:31 -0700490 parcel->writeInt32(mFlags);
491 parcel->writeInt32(mEdgeFlags);
492 parcel->writeInt32(mMetaState);
493 parcel->writeInt32(mButtonState);
494 parcel->writeFloat(mXOffset);
495 parcel->writeFloat(mYOffset);
496 parcel->writeFloat(mXPrecision);
497 parcel->writeFloat(mYPrecision);
498 parcel->writeInt64(mDownTime);
499
500 for (size_t i = 0; i < pointerCount; i++) {
501 const PointerProperties& properties = mPointerProperties.itemAt(i);
502 parcel->writeInt32(properties.id);
503 parcel->writeInt32(properties.toolType);
504 }
505
506 const PointerCoords* pc = mSamplePointerCoords.array();
507 for (size_t h = 0; h < sampleCount; h++) {
508 parcel->writeInt64(mSampleEventTimes.itemAt(h));
509 for (size_t i = 0; i < pointerCount; i++) {
510 status_t status = (pc++)->writeToParcel(parcel);
511 if (status) {
512 return status;
513 }
514 }
515 }
516 return OK;
517}
518#endif
519
520bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
521 if (source & AINPUT_SOURCE_CLASS_POINTER) {
522 // Specifically excludes HOVER_MOVE and SCROLL.
523 switch (action & AMOTION_EVENT_ACTION_MASK) {
524 case AMOTION_EVENT_ACTION_DOWN:
525 case AMOTION_EVENT_ACTION_MOVE:
526 case AMOTION_EVENT_ACTION_UP:
527 case AMOTION_EVENT_ACTION_POINTER_DOWN:
528 case AMOTION_EVENT_ACTION_POINTER_UP:
529 case AMOTION_EVENT_ACTION_CANCEL:
530 case AMOTION_EVENT_ACTION_OUTSIDE:
531 return true;
532 }
533 }
534 return false;
535}
536
Michael Wright872db4f2014-04-22 15:03:51 -0700537const char* MotionEvent::getLabel(int32_t axis) {
538 return getAxisLabel(axis);
539}
540
541int32_t MotionEvent::getAxisFromLabel(const char* label) {
542 return getAxisByLabel(label);
543}
544
Jeff Brown5912f952013-07-01 19:10:31 -0700545
546// --- PooledInputEventFactory ---
547
548PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
549 mMaxPoolSize(maxPoolSize) {
550}
551
552PooledInputEventFactory::~PooledInputEventFactory() {
553 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
554 delete mKeyEventPool.itemAt(i);
555 }
556 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
557 delete mMotionEventPool.itemAt(i);
558 }
559}
560
561KeyEvent* PooledInputEventFactory::createKeyEvent() {
562 if (!mKeyEventPool.isEmpty()) {
563 KeyEvent* event = mKeyEventPool.top();
564 mKeyEventPool.pop();
565 return event;
566 }
567 return new KeyEvent();
568}
569
570MotionEvent* PooledInputEventFactory::createMotionEvent() {
571 if (!mMotionEventPool.isEmpty()) {
572 MotionEvent* event = mMotionEventPool.top();
573 mMotionEventPool.pop();
574 return event;
575 }
576 return new MotionEvent();
577}
578
579void PooledInputEventFactory::recycle(InputEvent* event) {
580 switch (event->getType()) {
581 case AINPUT_EVENT_TYPE_KEY:
582 if (mKeyEventPool.size() < mMaxPoolSize) {
583 mKeyEventPool.push(static_cast<KeyEvent*>(event));
584 return;
585 }
586 break;
587 case AINPUT_EVENT_TYPE_MOTION:
588 if (mMotionEventPool.size() < mMaxPoolSize) {
589 mMotionEventPool.push(static_cast<MotionEvent*>(event));
590 return;
591 }
592 break;
593 }
594 delete event;
595}
596
597} // namespace android