1 /*
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 <cutils/compiler.h>
21 #include <limits.h>
22 #include <string.h>
23 
24 #include <input/Input.h>
25 #include <input/InputDevice.h>
26 #include <input/InputEventLabels.h>
27 
28 #ifdef __ANDROID__
29 #include <binder/Parcel.h>
30 #include <sys/random.h>
31 #endif
32 
33 namespace android {
34 
motionClassificationToString(MotionClassification classification)35 const char* motionClassificationToString(MotionClassification classification) {
36     switch (classification) {
37         case MotionClassification::NONE:
38             return "NONE";
39         case MotionClassification::AMBIGUOUS_GESTURE:
40             return "AMBIGUOUS_GESTURE";
41         case MotionClassification::DEEP_PRESS:
42             return "DEEP_PRESS";
43     }
44 }
45 
46 // --- IdGenerator ---
IdGenerator(Source source)47 IdGenerator::IdGenerator(Source source) : mSource(source) {}
48 
nextId() const49 int32_t IdGenerator::nextId() const {
50     constexpr uint32_t SEQUENCE_NUMBER_MASK = ~SOURCE_MASK;
51     int32_t id = 0;
52 
53 // Avoid building against syscall getrandom(2) on host, which will fail build on Mac. Host doesn't
54 // use sequence number so just always return mSource.
55 #ifdef __ANDROID__
56     constexpr size_t BUF_LEN = sizeof(id);
57     size_t totalBytes = 0;
58     while (totalBytes < BUF_LEN) {
59         ssize_t bytes = TEMP_FAILURE_RETRY(getrandom(&id, BUF_LEN, GRND_NONBLOCK));
60         if (CC_UNLIKELY(bytes < 0)) {
61             ALOGW("Failed to fill in random number for sequence number: %s.", strerror(errno));
62             id = 0;
63             break;
64         }
65         totalBytes += bytes;
66     }
67 #endif // __ANDROID__
68 
69     return (id & SEQUENCE_NUMBER_MASK) | static_cast<int32_t>(mSource);
70 }
71 
72 // --- InputEvent ---
73 
inputEventTypeToString(int32_t type)74 const char* inputEventTypeToString(int32_t type) {
75     switch (type) {
76         case AINPUT_EVENT_TYPE_KEY: {
77             return "KEY";
78         }
79         case AINPUT_EVENT_TYPE_MOTION: {
80             return "MOTION";
81         }
82         case AINPUT_EVENT_TYPE_FOCUS: {
83             return "FOCUS";
84         }
85     }
86     return "UNKNOWN";
87 }
88 
verifiedKeyEventFromKeyEvent(const KeyEvent & event)89 VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event) {
90     return {{VerifiedInputEvent::Type::KEY, event.getDeviceId(), event.getEventTime(),
91              event.getSource(), event.getDisplayId()},
92             event.getAction(),
93             event.getDownTime(),
94             event.getFlags() & VERIFIED_KEY_EVENT_FLAGS,
95             event.getKeyCode(),
96             event.getScanCode(),
97             event.getMetaState(),
98             event.getRepeatCount()};
99 }
100 
verifiedMotionEventFromMotionEvent(const MotionEvent & event)101 VerifiedMotionEvent verifiedMotionEventFromMotionEvent(const MotionEvent& event) {
102     return {{VerifiedInputEvent::Type::MOTION, event.getDeviceId(), event.getEventTime(),
103              event.getSource(), event.getDisplayId()},
104             event.getRawX(0),
105             event.getRawY(0),
106             event.getActionMasked(),
107             event.getDownTime(),
108             event.getFlags() & VERIFIED_MOTION_EVENT_FLAGS,
109             event.getMetaState(),
110             event.getButtonState()};
111 }
112 
initialize(int32_t id,int32_t deviceId,uint32_t source,int32_t displayId,std::array<uint8_t,32> hmac)113 void InputEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
114                             std::array<uint8_t, 32> hmac) {
115     mId = id;
116     mDeviceId = deviceId;
117     mSource = source;
118     mDisplayId = displayId;
119     mHmac = hmac;
120 }
121 
initialize(const InputEvent & from)122 void InputEvent::initialize(const InputEvent& from) {
123     mId = from.mId;
124     mDeviceId = from.mDeviceId;
125     mSource = from.mSource;
126     mDisplayId = from.mDisplayId;
127     mHmac = from.mHmac;
128 }
129 
nextId()130 int32_t InputEvent::nextId() {
131     static IdGenerator idGen(IdGenerator::Source::OTHER);
132     return idGen.nextId();
133 }
134 
135 // --- KeyEvent ---
136 
getLabel(int32_t keyCode)137 const char* KeyEvent::getLabel(int32_t keyCode) {
138     return getLabelByKeyCode(keyCode);
139 }
140 
getKeyCodeFromLabel(const char * label)141 int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
142     return getKeyCodeByLabel(label);
143 }
144 
initialize(int32_t id,int32_t deviceId,uint32_t source,int32_t displayId,std::array<uint8_t,32> hmac,int32_t action,int32_t flags,int32_t keyCode,int32_t scanCode,int32_t metaState,int32_t repeatCount,nsecs_t downTime,nsecs_t eventTime)145 void KeyEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
146                           std::array<uint8_t, 32> hmac, int32_t action, int32_t flags,
147                           int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
148                           nsecs_t downTime, nsecs_t eventTime) {
149     InputEvent::initialize(id, deviceId, source, displayId, hmac);
150     mAction = action;
151     mFlags = flags;
152     mKeyCode = keyCode;
153     mScanCode = scanCode;
154     mMetaState = metaState;
155     mRepeatCount = repeatCount;
156     mDownTime = downTime;
157     mEventTime = eventTime;
158 }
159 
initialize(const KeyEvent & from)160 void KeyEvent::initialize(const KeyEvent& from) {
161     InputEvent::initialize(from);
162     mAction = from.mAction;
163     mFlags = from.mFlags;
164     mKeyCode = from.mKeyCode;
165     mScanCode = from.mScanCode;
166     mMetaState = from.mMetaState;
167     mRepeatCount = from.mRepeatCount;
168     mDownTime = from.mDownTime;
169     mEventTime = from.mEventTime;
170 }
171 
actionToString(int32_t action)172 const char* KeyEvent::actionToString(int32_t action) {
173     // Convert KeyEvent action to string
174     switch (action) {
175         case AKEY_EVENT_ACTION_DOWN:
176             return "DOWN";
177         case AKEY_EVENT_ACTION_UP:
178             return "UP";
179         case AKEY_EVENT_ACTION_MULTIPLE:
180             return "MULTIPLE";
181     }
182     return "UNKNOWN";
183 }
184 
185 // --- PointerCoords ---
186 
getAxisValue(int32_t axis) const187 float PointerCoords::getAxisValue(int32_t axis) const {
188     if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
189         return 0;
190     }
191     return values[BitSet64::getIndexOfBit(bits, axis)];
192 }
193 
setAxisValue(int32_t axis,float value)194 status_t PointerCoords::setAxisValue(int32_t axis, float value) {
195     if (axis < 0 || axis > 63) {
196         return NAME_NOT_FOUND;
197     }
198 
199     uint32_t index = BitSet64::getIndexOfBit(bits, axis);
200     if (!BitSet64::hasBit(bits, axis)) {
201         if (value == 0) {
202             return OK; // axes with value 0 do not need to be stored
203         }
204 
205         uint32_t count = BitSet64::count(bits);
206         if (count >= MAX_AXES) {
207             tooManyAxes(axis);
208             return NO_MEMORY;
209         }
210         BitSet64::markBit(bits, axis);
211         for (uint32_t i = count; i > index; i--) {
212             values[i] = values[i - 1];
213         }
214     }
215 
216     values[index] = value;
217     return OK;
218 }
219 
scaleAxisValue(PointerCoords & c,int axis,float scaleFactor)220 static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
221     float value = c.getAxisValue(axis);
222     if (value != 0) {
223         c.setAxisValue(axis, value * scaleFactor);
224     }
225 }
226 
scale(float globalScaleFactor,float windowXScale,float windowYScale)227 void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
228     // No need to scale pressure or size since they are normalized.
229     // No need to scale orientation since it is meaningless to do so.
230 
231     // If there is a global scale factor, it is included in the windowX/YScale
232     // so we don't need to apply it twice to the X/Y axes.
233     // However we don't want to apply any windowXYScale not included in the global scale
234     // to the TOUCH_MAJOR/MINOR coordinates.
235     scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
236     scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
237     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
238     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
239     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
240     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
241 }
242 
scale(float globalScaleFactor)243 void PointerCoords::scale(float globalScaleFactor) {
244     scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
245 }
246 
applyOffset(float xOffset,float yOffset)247 void PointerCoords::applyOffset(float xOffset, float yOffset) {
248     setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
249     setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
250 }
251 
252 #ifdef __ANDROID__
readFromParcel(Parcel * parcel)253 status_t PointerCoords::readFromParcel(Parcel* parcel) {
254     bits = parcel->readInt64();
255 
256     uint32_t count = BitSet64::count(bits);
257     if (count > MAX_AXES) {
258         return BAD_VALUE;
259     }
260 
261     for (uint32_t i = 0; i < count; i++) {
262         values[i] = parcel->readFloat();
263     }
264     return OK;
265 }
266 
writeToParcel(Parcel * parcel) const267 status_t PointerCoords::writeToParcel(Parcel* parcel) const {
268     parcel->writeInt64(bits);
269 
270     uint32_t count = BitSet64::count(bits);
271     for (uint32_t i = 0; i < count; i++) {
272         parcel->writeFloat(values[i]);
273     }
274     return OK;
275 }
276 #endif
277 
tooManyAxes(int axis)278 void PointerCoords::tooManyAxes(int axis) {
279     ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
280             "cannot contain more than %d axis values.", axis, int(MAX_AXES));
281 }
282 
operator ==(const PointerCoords & other) const283 bool PointerCoords::operator==(const PointerCoords& other) const {
284     if (bits != other.bits) {
285         return false;
286     }
287     uint32_t count = BitSet64::count(bits);
288     for (uint32_t i = 0; i < count; i++) {
289         if (values[i] != other.values[i]) {
290             return false;
291         }
292     }
293     return true;
294 }
295 
copyFrom(const PointerCoords & other)296 void PointerCoords::copyFrom(const PointerCoords& other) {
297     bits = other.bits;
298     uint32_t count = BitSet64::count(bits);
299     for (uint32_t i = 0; i < count; i++) {
300         values[i] = other.values[i];
301     }
302 }
303 
304 
305 // --- PointerProperties ---
306 
operator ==(const PointerProperties & other) const307 bool PointerProperties::operator==(const PointerProperties& other) const {
308     return id == other.id
309             && toolType == other.toolType;
310 }
311 
copyFrom(const PointerProperties & other)312 void PointerProperties::copyFrom(const PointerProperties& other) {
313     id = other.id;
314     toolType = other.toolType;
315 }
316 
317 
318 // --- MotionEvent ---
319 
initialize(int32_t id,int32_t deviceId,uint32_t source,int32_t displayId,std::array<uint8_t,32> hmac,int32_t action,int32_t actionButton,int32_t flags,int32_t edgeFlags,int32_t metaState,int32_t buttonState,MotionClassification classification,float xScale,float yScale,float xOffset,float yOffset,float xPrecision,float yPrecision,float rawXCursorPosition,float rawYCursorPosition,nsecs_t downTime,nsecs_t eventTime,size_t pointerCount,const PointerProperties * pointerProperties,const PointerCoords * pointerCoords)320 void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
321                              std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
322                              int32_t flags, int32_t edgeFlags, int32_t metaState,
323                              int32_t buttonState, MotionClassification classification, float xScale,
324                              float yScale, float xOffset, float yOffset, float xPrecision,
325                              float yPrecision, float rawXCursorPosition, float rawYCursorPosition,
326                              nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
327                              const PointerProperties* pointerProperties,
328                              const PointerCoords* pointerCoords) {
329     InputEvent::initialize(id, deviceId, source, displayId, hmac);
330     mAction = action;
331     mActionButton = actionButton;
332     mFlags = flags;
333     mEdgeFlags = edgeFlags;
334     mMetaState = metaState;
335     mButtonState = buttonState;
336     mClassification = classification;
337     mXScale = xScale;
338     mYScale = yScale;
339     mXOffset = xOffset;
340     mYOffset = yOffset;
341     mXPrecision = xPrecision;
342     mYPrecision = yPrecision;
343     mRawXCursorPosition = rawXCursorPosition;
344     mRawYCursorPosition = rawYCursorPosition;
345     mDownTime = downTime;
346     mPointerProperties.clear();
347     mPointerProperties.appendArray(pointerProperties, pointerCount);
348     mSampleEventTimes.clear();
349     mSamplePointerCoords.clear();
350     addSample(eventTime, pointerCoords);
351 }
352 
copyFrom(const MotionEvent * other,bool keepHistory)353 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
354     InputEvent::initialize(other->mId, other->mDeviceId, other->mSource, other->mDisplayId,
355                            other->mHmac);
356     mAction = other->mAction;
357     mActionButton = other->mActionButton;
358     mFlags = other->mFlags;
359     mEdgeFlags = other->mEdgeFlags;
360     mMetaState = other->mMetaState;
361     mButtonState = other->mButtonState;
362     mClassification = other->mClassification;
363     mXScale = other->mXScale;
364     mYScale = other->mYScale;
365     mXOffset = other->mXOffset;
366     mYOffset = other->mYOffset;
367     mXPrecision = other->mXPrecision;
368     mYPrecision = other->mYPrecision;
369     mRawXCursorPosition = other->mRawXCursorPosition;
370     mRawYCursorPosition = other->mRawYCursorPosition;
371     mDownTime = other->mDownTime;
372     mPointerProperties = other->mPointerProperties;
373 
374     if (keepHistory) {
375         mSampleEventTimes = other->mSampleEventTimes;
376         mSamplePointerCoords = other->mSamplePointerCoords;
377     } else {
378         mSampleEventTimes.clear();
379         mSampleEventTimes.push(other->getEventTime());
380         mSamplePointerCoords.clear();
381         size_t pointerCount = other->getPointerCount();
382         size_t historySize = other->getHistorySize();
383         mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
384                 + (historySize * pointerCount), pointerCount);
385     }
386 }
387 
addSample(int64_t eventTime,const PointerCoords * pointerCoords)388 void MotionEvent::addSample(
389         int64_t eventTime,
390         const PointerCoords* pointerCoords) {
391     mSampleEventTimes.push(eventTime);
392     mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
393 }
394 
getXCursorPosition() const395 float MotionEvent::getXCursorPosition() const {
396     const float rawX = getRawXCursorPosition();
397     return rawX * mXScale + mXOffset;
398 }
399 
getYCursorPosition() const400 float MotionEvent::getYCursorPosition() const {
401     const float rawY = getRawYCursorPosition();
402     return rawY * mYScale + mYOffset;
403 }
404 
setCursorPosition(float x,float y)405 void MotionEvent::setCursorPosition(float x, float y) {
406     mRawXCursorPosition = (x - mXOffset) / mXScale;
407     mRawYCursorPosition = (y - mYOffset) / mYScale;
408 }
409 
getRawPointerCoords(size_t pointerIndex) const410 const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
411     return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
412 }
413 
getRawAxisValue(int32_t axis,size_t pointerIndex) const414 float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
415     return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
416 }
417 
getAxisValue(int32_t axis,size_t pointerIndex) const418 float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
419     float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
420     switch (axis) {
421     case AMOTION_EVENT_AXIS_X:
422         return value * mXScale + mXOffset;
423     case AMOTION_EVENT_AXIS_Y:
424         return value * mYScale + mYOffset;
425     }
426     return value;
427 }
428 
getHistoricalRawPointerCoords(size_t pointerIndex,size_t historicalIndex) const429 const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
430         size_t pointerIndex, size_t historicalIndex) const {
431     return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
432 }
433 
getHistoricalRawAxisValue(int32_t axis,size_t pointerIndex,size_t historicalIndex) const434 float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
435         size_t historicalIndex) const {
436     return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
437 }
438 
getHistoricalAxisValue(int32_t axis,size_t pointerIndex,size_t historicalIndex) const439 float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
440         size_t historicalIndex) const {
441     float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
442     switch (axis) {
443     case AMOTION_EVENT_AXIS_X:
444         return value * mXScale + mXOffset;
445     case AMOTION_EVENT_AXIS_Y:
446         return value * mYScale + mYOffset;
447     }
448     return value;
449 }
450 
findPointerIndex(int32_t pointerId) const451 ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
452     size_t pointerCount = mPointerProperties.size();
453     for (size_t i = 0; i < pointerCount; i++) {
454         if (mPointerProperties.itemAt(i).id == pointerId) {
455             return i;
456         }
457     }
458     return -1;
459 }
460 
offsetLocation(float xOffset,float yOffset)461 void MotionEvent::offsetLocation(float xOffset, float yOffset) {
462     mXOffset += xOffset;
463     mYOffset += yOffset;
464 }
465 
scale(float globalScaleFactor)466 void MotionEvent::scale(float globalScaleFactor) {
467     mXOffset *= globalScaleFactor;
468     mYOffset *= globalScaleFactor;
469     mXPrecision *= globalScaleFactor;
470     mYPrecision *= globalScaleFactor;
471 
472     size_t numSamples = mSamplePointerCoords.size();
473     for (size_t i = 0; i < numSamples; i++) {
474         mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
475     }
476 }
477 
transformPoint(const float matrix[9],float x,float y,float * outX,float * outY)478 static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
479     // Apply perspective transform like Skia.
480     float newX = matrix[0] * x + matrix[1] * y + matrix[2];
481     float newY = matrix[3] * x + matrix[4] * y + matrix[5];
482     float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
483     if (newZ) {
484         newZ = 1.0f / newZ;
485     }
486     *outX = newX * newZ;
487     *outY = newY * newZ;
488 }
489 
transformAngle(const float matrix[9],float angleRadians,float originX,float originY)490 static float transformAngle(const float matrix[9], float angleRadians,
491         float originX, float originY) {
492     // Construct and transform a vector oriented at the specified clockwise angle from vertical.
493     // Coordinate system: down is increasing Y, right is increasing X.
494     float x = sinf(angleRadians);
495     float y = -cosf(angleRadians);
496     transformPoint(matrix, x, y, &x, &y);
497     x -= originX;
498     y -= originY;
499 
500     // Derive the transformed vector's clockwise angle from vertical.
501     float result = atan2f(x, -y);
502     if (result < - M_PI_2) {
503         result += M_PI;
504     } else if (result > M_PI_2) {
505         result -= M_PI;
506     }
507     return result;
508 }
509 
transform(const float matrix[9])510 void MotionEvent::transform(const float matrix[9]) {
511     // The tricky part of this implementation is to preserve the value of
512     // rawX and rawY.  So we apply the transformation to the first point
513     // then derive an appropriate new X/Y offset that will preserve rawX
514      // and rawY for that point.
515     float oldXOffset = mXOffset;
516     float oldYOffset = mYOffset;
517     float newX, newY;
518     float scaledRawX = getRawX(0) * mXScale;
519     float scaledRawY = getRawY(0) * mYScale;
520     transformPoint(matrix, scaledRawX + oldXOffset, scaledRawY + oldYOffset, &newX, &newY);
521     mXOffset = newX - scaledRawX;
522     mYOffset = newY - scaledRawY;
523 
524     // Determine how the origin is transformed by the matrix so that we
525     // can transform orientation vectors.
526     float originX, originY;
527     transformPoint(matrix, 0, 0, &originX, &originY);
528 
529     // Apply the transformation to cursor position.
530     if (isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) {
531         float x = mRawXCursorPosition * mXScale + oldXOffset;
532         float y = mRawYCursorPosition * mYScale + oldYOffset;
533         transformPoint(matrix, x, y, &x, &y);
534         mRawXCursorPosition = (x - mXOffset) / mXScale;
535         mRawYCursorPosition = (y - mYOffset) / mYScale;
536     }
537 
538     // Apply the transformation to all samples.
539     size_t numSamples = mSamplePointerCoords.size();
540     for (size_t i = 0; i < numSamples; i++) {
541         PointerCoords& c = mSamplePointerCoords.editItemAt(i);
542         float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) * mXScale + oldXOffset;
543         float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) * mYScale + oldYOffset;
544         transformPoint(matrix, x, y, &x, &y);
545         c.setAxisValue(AMOTION_EVENT_AXIS_X, (x - mXOffset) / mXScale);
546         c.setAxisValue(AMOTION_EVENT_AXIS_Y, (y - mYOffset) / mYScale);
547 
548         float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
549         c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
550                 transformAngle(matrix, orientation, originX, originY));
551     }
552 }
553 
554 #ifdef __ANDROID__
readFromParcel(Parcel * parcel)555 status_t MotionEvent::readFromParcel(Parcel* parcel) {
556     size_t pointerCount = parcel->readInt32();
557     size_t sampleCount = parcel->readInt32();
558     if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
559             sampleCount == 0 || sampleCount > MAX_SAMPLES) {
560         return BAD_VALUE;
561     }
562 
563     mId = parcel->readInt32();
564     mDeviceId = parcel->readInt32();
565     mSource = parcel->readUint32();
566     mDisplayId = parcel->readInt32();
567     std::vector<uint8_t> hmac;
568     status_t result = parcel->readByteVector(&hmac);
569     if (result != OK || hmac.size() != 32) {
570         return BAD_VALUE;
571     }
572     std::move(hmac.begin(), hmac.begin() + hmac.size(), mHmac.begin());
573     mAction = parcel->readInt32();
574     mActionButton = parcel->readInt32();
575     mFlags = parcel->readInt32();
576     mEdgeFlags = parcel->readInt32();
577     mMetaState = parcel->readInt32();
578     mButtonState = parcel->readInt32();
579     mClassification = static_cast<MotionClassification>(parcel->readByte());
580     mXScale = parcel->readFloat();
581     mYScale = parcel->readFloat();
582     mXOffset = parcel->readFloat();
583     mYOffset = parcel->readFloat();
584     mXPrecision = parcel->readFloat();
585     mYPrecision = parcel->readFloat();
586     mRawXCursorPosition = parcel->readFloat();
587     mRawYCursorPosition = parcel->readFloat();
588     mDownTime = parcel->readInt64();
589 
590     mPointerProperties.clear();
591     mPointerProperties.setCapacity(pointerCount);
592     mSampleEventTimes.clear();
593     mSampleEventTimes.setCapacity(sampleCount);
594     mSamplePointerCoords.clear();
595     mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
596 
597     for (size_t i = 0; i < pointerCount; i++) {
598         mPointerProperties.push();
599         PointerProperties& properties = mPointerProperties.editTop();
600         properties.id = parcel->readInt32();
601         properties.toolType = parcel->readInt32();
602     }
603 
604     while (sampleCount > 0) {
605         sampleCount--;
606         mSampleEventTimes.push(parcel->readInt64());
607         for (size_t i = 0; i < pointerCount; i++) {
608             mSamplePointerCoords.push();
609             status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
610             if (status) {
611                 return status;
612             }
613         }
614     }
615     return OK;
616 }
617 
writeToParcel(Parcel * parcel) const618 status_t MotionEvent::writeToParcel(Parcel* parcel) const {
619     size_t pointerCount = mPointerProperties.size();
620     size_t sampleCount = mSampleEventTimes.size();
621 
622     parcel->writeInt32(pointerCount);
623     parcel->writeInt32(sampleCount);
624 
625     parcel->writeInt32(mId);
626     parcel->writeInt32(mDeviceId);
627     parcel->writeUint32(mSource);
628     parcel->writeInt32(mDisplayId);
629     std::vector<uint8_t> hmac(mHmac.begin(), mHmac.end());
630     parcel->writeByteVector(hmac);
631     parcel->writeInt32(mAction);
632     parcel->writeInt32(mActionButton);
633     parcel->writeInt32(mFlags);
634     parcel->writeInt32(mEdgeFlags);
635     parcel->writeInt32(mMetaState);
636     parcel->writeInt32(mButtonState);
637     parcel->writeByte(static_cast<int8_t>(mClassification));
638     parcel->writeFloat(mXScale);
639     parcel->writeFloat(mYScale);
640     parcel->writeFloat(mXOffset);
641     parcel->writeFloat(mYOffset);
642     parcel->writeFloat(mXPrecision);
643     parcel->writeFloat(mYPrecision);
644     parcel->writeFloat(mRawXCursorPosition);
645     parcel->writeFloat(mRawYCursorPosition);
646     parcel->writeInt64(mDownTime);
647 
648     for (size_t i = 0; i < pointerCount; i++) {
649         const PointerProperties& properties = mPointerProperties.itemAt(i);
650         parcel->writeInt32(properties.id);
651         parcel->writeInt32(properties.toolType);
652     }
653 
654     const PointerCoords* pc = mSamplePointerCoords.array();
655     for (size_t h = 0; h < sampleCount; h++) {
656         parcel->writeInt64(mSampleEventTimes.itemAt(h));
657         for (size_t i = 0; i < pointerCount; i++) {
658             status_t status = (pc++)->writeToParcel(parcel);
659             if (status) {
660                 return status;
661             }
662         }
663     }
664     return OK;
665 }
666 #endif
667 
isTouchEvent(uint32_t source,int32_t action)668 bool MotionEvent::isTouchEvent(uint32_t source, int32_t action) {
669     if (source & AINPUT_SOURCE_CLASS_POINTER) {
670         // Specifically excludes HOVER_MOVE and SCROLL.
671         switch (action & AMOTION_EVENT_ACTION_MASK) {
672         case AMOTION_EVENT_ACTION_DOWN:
673         case AMOTION_EVENT_ACTION_MOVE:
674         case AMOTION_EVENT_ACTION_UP:
675         case AMOTION_EVENT_ACTION_POINTER_DOWN:
676         case AMOTION_EVENT_ACTION_POINTER_UP:
677         case AMOTION_EVENT_ACTION_CANCEL:
678         case AMOTION_EVENT_ACTION_OUTSIDE:
679             return true;
680         }
681     }
682     return false;
683 }
684 
getLabel(int32_t axis)685 const char* MotionEvent::getLabel(int32_t axis) {
686     return getAxisLabel(axis);
687 }
688 
getAxisFromLabel(const char * label)689 int32_t MotionEvent::getAxisFromLabel(const char* label) {
690     return getAxisByLabel(label);
691 }
692 
actionToString(int32_t action)693 const char* MotionEvent::actionToString(int32_t action) {
694     // Convert MotionEvent action to string
695     switch (action & AMOTION_EVENT_ACTION_MASK) {
696         case AMOTION_EVENT_ACTION_DOWN:
697             return "DOWN";
698         case AMOTION_EVENT_ACTION_MOVE:
699             return "MOVE";
700         case AMOTION_EVENT_ACTION_UP:
701             return "UP";
702         case AMOTION_EVENT_ACTION_CANCEL:
703             return "CANCEL";
704         case AMOTION_EVENT_ACTION_POINTER_DOWN:
705             return "POINTER_DOWN";
706         case AMOTION_EVENT_ACTION_POINTER_UP:
707             return "POINTER_UP";
708     }
709     return "UNKNOWN";
710 }
711 
712 // --- FocusEvent ---
713 
initialize(int32_t id,bool hasFocus,bool inTouchMode)714 void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
715     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
716                            ADISPLAY_ID_NONE, INVALID_HMAC);
717     mHasFocus = hasFocus;
718     mInTouchMode = inTouchMode;
719 }
720 
initialize(const FocusEvent & from)721 void FocusEvent::initialize(const FocusEvent& from) {
722     InputEvent::initialize(from);
723     mHasFocus = from.mHasFocus;
724     mInTouchMode = from.mInTouchMode;
725 }
726 
727 // --- PooledInputEventFactory ---
728 
PooledInputEventFactory(size_t maxPoolSize)729 PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
730         mMaxPoolSize(maxPoolSize) {
731 }
732 
~PooledInputEventFactory()733 PooledInputEventFactory::~PooledInputEventFactory() {
734 }
735 
createKeyEvent()736 KeyEvent* PooledInputEventFactory::createKeyEvent() {
737     if (mKeyEventPool.empty()) {
738         return new KeyEvent();
739     }
740     KeyEvent* event = mKeyEventPool.front().release();
741     mKeyEventPool.pop();
742     return event;
743 }
744 
createMotionEvent()745 MotionEvent* PooledInputEventFactory::createMotionEvent() {
746     if (mMotionEventPool.empty()) {
747         return new MotionEvent();
748     }
749     MotionEvent* event = mMotionEventPool.front().release();
750     mMotionEventPool.pop();
751     return event;
752 }
753 
createFocusEvent()754 FocusEvent* PooledInputEventFactory::createFocusEvent() {
755     if (mFocusEventPool.empty()) {
756         return new FocusEvent();
757     }
758     FocusEvent* event = mFocusEventPool.front().release();
759     mFocusEventPool.pop();
760     return event;
761 }
762 
recycle(InputEvent * event)763 void PooledInputEventFactory::recycle(InputEvent* event) {
764     switch (event->getType()) {
765     case AINPUT_EVENT_TYPE_KEY:
766         if (mKeyEventPool.size() < mMaxPoolSize) {
767             mKeyEventPool.push(std::unique_ptr<KeyEvent>(static_cast<KeyEvent*>(event)));
768             return;
769         }
770         break;
771     case AINPUT_EVENT_TYPE_MOTION:
772         if (mMotionEventPool.size() < mMaxPoolSize) {
773             mMotionEventPool.push(std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event)));
774             return;
775         }
776         break;
777     case AINPUT_EVENT_TYPE_FOCUS:
778         if (mFocusEventPool.size() < mMaxPoolSize) {
779             mFocusEventPool.push(std::unique_ptr<FocusEvent>(static_cast<FocusEvent*>(event)));
780             return;
781         }
782         break;
783     }
784     delete event;
785 }
786 
787 } // namespace android
788