• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <attestation/HmacKeyManager.h>
21 #include <cutils/compiler.h>
22 #include <inttypes.h>
23 #include <limits.h>
24 #include <string.h>
25 
26 #include <android-base/properties.h>
27 #include <android-base/stringprintf.h>
28 #include <input/Input.h>
29 #include <input/InputDevice.h>
30 #include <input/InputEventLabels.h>
31 
32 #ifdef __linux__
33 #include <binder/Parcel.h>
34 #endif
35 #ifdef __ANDROID__
36 #include <sys/random.h>
37 #endif
38 
39 using android::base::StringPrintf;
40 
41 namespace android {
42 
43 namespace {
44 
45 // When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
46 // coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
isPerWindowInputRotationEnabled()47 bool isPerWindowInputRotationEnabled() {
48     static const bool PER_WINDOW_INPUT_ROTATION =
49             base::GetBoolProperty("persist.debug.per_window_input_rotation", false);
50 
51     return PER_WINDOW_INPUT_ROTATION;
52 }
53 
transformAngle(const ui::Transform & transform,float angleRadians)54 float transformAngle(const ui::Transform& transform, float angleRadians) {
55     // Construct and transform a vector oriented at the specified clockwise angle from vertical.
56     // Coordinate system: down is increasing Y, right is increasing X.
57     float x = sinf(angleRadians);
58     float y = -cosf(angleRadians);
59     vec2 transformedPoint = transform.transform(x, y);
60 
61     // Determine how the origin is transformed by the matrix so that we
62     // can transform orientation vectors.
63     const vec2 origin = transform.transform(0, 0);
64 
65     transformedPoint.x -= origin.x;
66     transformedPoint.y -= origin.y;
67 
68     // Derive the transformed vector's clockwise angle from vertical.
69     float result = atan2f(transformedPoint.x, -transformedPoint.y);
70     if (result < -M_PI_2) {
71         result += M_PI;
72     } else if (result > M_PI_2) {
73         result -= M_PI;
74     }
75     return result;
76 }
77 
78 // Rotates the given point to the transform's orientation. If the display width and height are
79 // provided, the point is rotated in the screen space. Otherwise, the point is rotated about the
80 // origin. This helper is used to avoid the extra overhead of creating new Transforms.
rotatePoint(const ui::Transform & transform,float x,float y,int32_t displayWidth=0,int32_t displayHeight=0)81 vec2 rotatePoint(const ui::Transform& transform, float x, float y, int32_t displayWidth = 0,
82                  int32_t displayHeight = 0) {
83     // 0x7 encapsulates all 3 rotations (see ui::Transform::RotationFlags)
84     static const int ALL_ROTATIONS_MASK = 0x7;
85     const uint32_t orientation = (transform.getOrientation() & ALL_ROTATIONS_MASK);
86     if (orientation == ui::Transform::ROT_0) {
87         return {x, y};
88     }
89 
90     vec2 xy(x, y);
91     if (orientation == ui::Transform::ROT_90) {
92         xy.x = displayHeight - y;
93         xy.y = x;
94     } else if (orientation == ui::Transform::ROT_180) {
95         xy.x = displayWidth - x;
96         xy.y = displayHeight - y;
97     } else if (orientation == ui::Transform::ROT_270) {
98         xy.x = y;
99         xy.y = displayWidth - x;
100     }
101     return xy;
102 }
103 
104 } // namespace
105 
motionClassificationToString(MotionClassification classification)106 const char* motionClassificationToString(MotionClassification classification) {
107     switch (classification) {
108         case MotionClassification::NONE:
109             return "NONE";
110         case MotionClassification::AMBIGUOUS_GESTURE:
111             return "AMBIGUOUS_GESTURE";
112         case MotionClassification::DEEP_PRESS:
113             return "DEEP_PRESS";
114     }
115 }
116 
117 // --- IdGenerator ---
IdGenerator(Source source)118 IdGenerator::IdGenerator(Source source) : mSource(source) {}
119 
nextId() const120 int32_t IdGenerator::nextId() const {
121     constexpr uint32_t SEQUENCE_NUMBER_MASK = ~SOURCE_MASK;
122     int32_t id = 0;
123 
124 // Avoid building against syscall getrandom(2) on host, which will fail build on Mac. Host doesn't
125 // use sequence number so just always return mSource.
126 #ifdef __ANDROID__
127     constexpr size_t BUF_LEN = sizeof(id);
128     size_t totalBytes = 0;
129     while (totalBytes < BUF_LEN) {
130         ssize_t bytes = TEMP_FAILURE_RETRY(getrandom(&id, BUF_LEN, GRND_NONBLOCK));
131         if (CC_UNLIKELY(bytes < 0)) {
132             ALOGW("Failed to fill in random number for sequence number: %s.", strerror(errno));
133             id = 0;
134             break;
135         }
136         totalBytes += bytes;
137     }
138 #endif // __ANDROID__
139 
140     return (id & SEQUENCE_NUMBER_MASK) | static_cast<int32_t>(mSource);
141 }
142 
143 // --- InputEvent ---
144 
inputEventTypeToString(int32_t type)145 const char* inputEventTypeToString(int32_t type) {
146     switch (type) {
147         case AINPUT_EVENT_TYPE_KEY: {
148             return "KEY";
149         }
150         case AINPUT_EVENT_TYPE_MOTION: {
151             return "MOTION";
152         }
153         case AINPUT_EVENT_TYPE_FOCUS: {
154             return "FOCUS";
155         }
156         case AINPUT_EVENT_TYPE_CAPTURE: {
157             return "CAPTURE";
158         }
159         case AINPUT_EVENT_TYPE_DRAG: {
160             return "DRAG";
161         }
162     }
163     return "UNKNOWN";
164 }
165 
verifiedKeyEventFromKeyEvent(const KeyEvent & event)166 VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event) {
167     return {{VerifiedInputEvent::Type::KEY, event.getDeviceId(), event.getEventTime(),
168              event.getSource(), event.getDisplayId()},
169             event.getAction(),
170             event.getDownTime(),
171             event.getFlags() & VERIFIED_KEY_EVENT_FLAGS,
172             event.getKeyCode(),
173             event.getScanCode(),
174             event.getMetaState(),
175             event.getRepeatCount()};
176 }
177 
verifiedMotionEventFromMotionEvent(const MotionEvent & event)178 VerifiedMotionEvent verifiedMotionEventFromMotionEvent(const MotionEvent& event) {
179     return {{VerifiedInputEvent::Type::MOTION, event.getDeviceId(), event.getEventTime(),
180              event.getSource(), event.getDisplayId()},
181             event.getRawX(0),
182             event.getRawY(0),
183             event.getActionMasked(),
184             event.getDownTime(),
185             event.getFlags() & VERIFIED_MOTION_EVENT_FLAGS,
186             event.getMetaState(),
187             event.getButtonState()};
188 }
189 
initialize(int32_t id,int32_t deviceId,uint32_t source,int32_t displayId,std::array<uint8_t,32> hmac)190 void InputEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
191                             std::array<uint8_t, 32> hmac) {
192     mId = id;
193     mDeviceId = deviceId;
194     mSource = source;
195     mDisplayId = displayId;
196     mHmac = hmac;
197 }
198 
initialize(const InputEvent & from)199 void InputEvent::initialize(const InputEvent& from) {
200     mId = from.mId;
201     mDeviceId = from.mDeviceId;
202     mSource = from.mSource;
203     mDisplayId = from.mDisplayId;
204     mHmac = from.mHmac;
205 }
206 
nextId()207 int32_t InputEvent::nextId() {
208     static IdGenerator idGen(IdGenerator::Source::OTHER);
209     return idGen.nextId();
210 }
211 
212 // --- KeyEvent ---
213 
getLabel(int32_t keyCode)214 const char* KeyEvent::getLabel(int32_t keyCode) {
215     return InputEventLookup::getLabelByKeyCode(keyCode);
216 }
217 
getKeyCodeFromLabel(const char * label)218 int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
219     return InputEventLookup::getKeyCodeByLabel(label);
220 }
221 
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)222 void KeyEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
223                           std::array<uint8_t, 32> hmac, int32_t action, int32_t flags,
224                           int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
225                           nsecs_t downTime, nsecs_t eventTime) {
226     InputEvent::initialize(id, deviceId, source, displayId, hmac);
227     mAction = action;
228     mFlags = flags;
229     mKeyCode = keyCode;
230     mScanCode = scanCode;
231     mMetaState = metaState;
232     mRepeatCount = repeatCount;
233     mDownTime = downTime;
234     mEventTime = eventTime;
235 }
236 
initialize(const KeyEvent & from)237 void KeyEvent::initialize(const KeyEvent& from) {
238     InputEvent::initialize(from);
239     mAction = from.mAction;
240     mFlags = from.mFlags;
241     mKeyCode = from.mKeyCode;
242     mScanCode = from.mScanCode;
243     mMetaState = from.mMetaState;
244     mRepeatCount = from.mRepeatCount;
245     mDownTime = from.mDownTime;
246     mEventTime = from.mEventTime;
247 }
248 
actionToString(int32_t action)249 const char* KeyEvent::actionToString(int32_t action) {
250     // Convert KeyEvent action to string
251     switch (action) {
252         case AKEY_EVENT_ACTION_DOWN:
253             return "DOWN";
254         case AKEY_EVENT_ACTION_UP:
255             return "UP";
256         case AKEY_EVENT_ACTION_MULTIPLE:
257             return "MULTIPLE";
258     }
259     return "UNKNOWN";
260 }
261 
262 // --- PointerCoords ---
263 
getAxisValue(int32_t axis) const264 float PointerCoords::getAxisValue(int32_t axis) const {
265     if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
266         return 0;
267     }
268     return values[BitSet64::getIndexOfBit(bits, axis)];
269 }
270 
setAxisValue(int32_t axis,float value)271 status_t PointerCoords::setAxisValue(int32_t axis, float value) {
272     if (axis < 0 || axis > 63) {
273         return NAME_NOT_FOUND;
274     }
275 
276     uint32_t index = BitSet64::getIndexOfBit(bits, axis);
277     if (!BitSet64::hasBit(bits, axis)) {
278         if (value == 0) {
279             return OK; // axes with value 0 do not need to be stored
280         }
281 
282         uint32_t count = BitSet64::count(bits);
283         if (count >= MAX_AXES) {
284             tooManyAxes(axis);
285             return NO_MEMORY;
286         }
287         BitSet64::markBit(bits, axis);
288         for (uint32_t i = count; i > index; i--) {
289             values[i] = values[i - 1];
290         }
291     }
292 
293     values[index] = value;
294     return OK;
295 }
296 
scaleAxisValue(PointerCoords & c,int axis,float scaleFactor)297 static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
298     float value = c.getAxisValue(axis);
299     if (value != 0) {
300         c.setAxisValue(axis, value * scaleFactor);
301     }
302 }
303 
scale(float globalScaleFactor,float windowXScale,float windowYScale)304 void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
305     // No need to scale pressure or size since they are normalized.
306     // No need to scale orientation since it is meaningless to do so.
307 
308     // If there is a global scale factor, it is included in the windowX/YScale
309     // so we don't need to apply it twice to the X/Y axes.
310     // However we don't want to apply any windowXYScale not included in the global scale
311     // to the TOUCH_MAJOR/MINOR coordinates.
312     scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
313     scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
314     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
315     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
316     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
317     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
318 }
319 
scale(float globalScaleFactor)320 void PointerCoords::scale(float globalScaleFactor) {
321     scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
322 }
323 
applyOffset(float xOffset,float yOffset)324 void PointerCoords::applyOffset(float xOffset, float yOffset) {
325     setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
326     setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
327 }
328 
329 #ifdef __linux__
readFromParcel(Parcel * parcel)330 status_t PointerCoords::readFromParcel(Parcel* parcel) {
331     bits = parcel->readInt64();
332 
333     uint32_t count = BitSet64::count(bits);
334     if (count > MAX_AXES) {
335         return BAD_VALUE;
336     }
337 
338     for (uint32_t i = 0; i < count; i++) {
339         values[i] = parcel->readFloat();
340     }
341     return OK;
342 }
343 
writeToParcel(Parcel * parcel) const344 status_t PointerCoords::writeToParcel(Parcel* parcel) const {
345     parcel->writeInt64(bits);
346 
347     uint32_t count = BitSet64::count(bits);
348     for (uint32_t i = 0; i < count; i++) {
349         parcel->writeFloat(values[i]);
350     }
351     return OK;
352 }
353 #endif
354 
tooManyAxes(int axis)355 void PointerCoords::tooManyAxes(int axis) {
356     ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
357             "cannot contain more than %d axis values.", axis, int(MAX_AXES));
358 }
359 
operator ==(const PointerCoords & other) const360 bool PointerCoords::operator==(const PointerCoords& other) const {
361     if (bits != other.bits) {
362         return false;
363     }
364     uint32_t count = BitSet64::count(bits);
365     for (uint32_t i = 0; i < count; i++) {
366         if (values[i] != other.values[i]) {
367             return false;
368         }
369     }
370     return true;
371 }
372 
copyFrom(const PointerCoords & other)373 void PointerCoords::copyFrom(const PointerCoords& other) {
374     bits = other.bits;
375     uint32_t count = BitSet64::count(bits);
376     for (uint32_t i = 0; i < count; i++) {
377         values[i] = other.values[i];
378     }
379 }
380 
transform(const ui::Transform & transform)381 void PointerCoords::transform(const ui::Transform& transform) {
382     const vec2 xy = transform.transform(getXYValue());
383     setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
384     setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
385 
386     if (BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_ORIENTATION)) {
387         const float val = getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
388         setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(transform, val));
389     }
390 }
391 
392 // --- PointerProperties ---
393 
operator ==(const PointerProperties & other) const394 bool PointerProperties::operator==(const PointerProperties& other) const {
395     return id == other.id
396             && toolType == other.toolType;
397 }
398 
copyFrom(const PointerProperties & other)399 void PointerProperties::copyFrom(const PointerProperties& other) {
400     id = other.id;
401     toolType = other.toolType;
402 }
403 
404 
405 // --- MotionEvent ---
406 
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,const ui::Transform & transform,float xPrecision,float yPrecision,float rawXCursorPosition,float rawYCursorPosition,int32_t displayWidth,int32_t displayHeight,nsecs_t downTime,nsecs_t eventTime,size_t pointerCount,const PointerProperties * pointerProperties,const PointerCoords * pointerCoords)407 void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
408                              std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
409                              int32_t flags, int32_t edgeFlags, int32_t metaState,
410                              int32_t buttonState, MotionClassification classification,
411                              const ui::Transform& transform, float xPrecision, float yPrecision,
412                              float rawXCursorPosition, float rawYCursorPosition,
413                              int32_t displayWidth, int32_t displayHeight, nsecs_t downTime,
414                              nsecs_t eventTime, size_t pointerCount,
415                              const PointerProperties* pointerProperties,
416                              const PointerCoords* pointerCoords) {
417     InputEvent::initialize(id, deviceId, source, displayId, hmac);
418     mAction = action;
419     mActionButton = actionButton;
420     mFlags = flags;
421     mEdgeFlags = edgeFlags;
422     mMetaState = metaState;
423     mButtonState = buttonState;
424     mClassification = classification;
425     mTransform = transform;
426     mXPrecision = xPrecision;
427     mYPrecision = yPrecision;
428     mRawXCursorPosition = rawXCursorPosition;
429     mRawYCursorPosition = rawYCursorPosition;
430     mDisplayWidth = displayWidth;
431     mDisplayHeight = displayHeight;
432     mDownTime = downTime;
433     mPointerProperties.clear();
434     mPointerProperties.appendArray(pointerProperties, pointerCount);
435     mSampleEventTimes.clear();
436     mSamplePointerCoords.clear();
437     addSample(eventTime, pointerCoords);
438 }
439 
copyFrom(const MotionEvent * other,bool keepHistory)440 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
441     InputEvent::initialize(other->mId, other->mDeviceId, other->mSource, other->mDisplayId,
442                            other->mHmac);
443     mAction = other->mAction;
444     mActionButton = other->mActionButton;
445     mFlags = other->mFlags;
446     mEdgeFlags = other->mEdgeFlags;
447     mMetaState = other->mMetaState;
448     mButtonState = other->mButtonState;
449     mClassification = other->mClassification;
450     mTransform = other->mTransform;
451     mXPrecision = other->mXPrecision;
452     mYPrecision = other->mYPrecision;
453     mRawXCursorPosition = other->mRawXCursorPosition;
454     mRawYCursorPosition = other->mRawYCursorPosition;
455     mDisplayWidth = other->mDisplayWidth;
456     mDisplayHeight = other->mDisplayHeight;
457     mDownTime = other->mDownTime;
458     mPointerProperties = other->mPointerProperties;
459 
460     if (keepHistory) {
461         mSampleEventTimes = other->mSampleEventTimes;
462         mSamplePointerCoords = other->mSamplePointerCoords;
463     } else {
464         mSampleEventTimes.clear();
465         mSampleEventTimes.push_back(other->getEventTime());
466         mSamplePointerCoords.clear();
467         size_t pointerCount = other->getPointerCount();
468         size_t historySize = other->getHistorySize();
469         mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
470                 + (historySize * pointerCount), pointerCount);
471     }
472 }
473 
addSample(int64_t eventTime,const PointerCoords * pointerCoords)474 void MotionEvent::addSample(
475         int64_t eventTime,
476         const PointerCoords* pointerCoords) {
477     mSampleEventTimes.push_back(eventTime);
478     mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
479 }
480 
getXCursorPosition() const481 float MotionEvent::getXCursorPosition() const {
482     vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
483     return vals.x;
484 }
485 
getYCursorPosition() const486 float MotionEvent::getYCursorPosition() const {
487     vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
488     return vals.y;
489 }
490 
setCursorPosition(float x,float y)491 void MotionEvent::setCursorPosition(float x, float y) {
492     ui::Transform inverse = mTransform.inverse();
493     vec2 vals = inverse.transform(x, y);
494     mRawXCursorPosition = vals.x;
495     mRawYCursorPosition = vals.y;
496 }
497 
getRawPointerCoords(size_t pointerIndex) const498 const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
499     return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
500 }
501 
getRawAxisValue(int32_t axis,size_t pointerIndex) const502 float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
503     return getHistoricalRawAxisValue(axis, pointerIndex, getHistorySize());
504 }
505 
getAxisValue(int32_t axis,size_t pointerIndex) const506 float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
507     return getHistoricalAxisValue(axis, pointerIndex, getHistorySize());
508 }
509 
getHistoricalRawPointerCoords(size_t pointerIndex,size_t historicalIndex) const510 const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
511         size_t pointerIndex, size_t historicalIndex) const {
512     return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
513 }
514 
getHistoricalRawAxisValue(int32_t axis,size_t pointerIndex,size_t historicalIndex) const515 float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
516                                              size_t historicalIndex) const {
517     const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
518 
519     if (!isPerWindowInputRotationEnabled()) return coords->getAxisValue(axis);
520 
521     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
522         // For compatibility, convert raw coordinates into "oriented screen space". Once app
523         // developers are educated about getRaw, we can consider removing this.
524         const vec2 xy = rotatePoint(mTransform, coords->getX(), coords->getY(), mDisplayWidth,
525                                     mDisplayHeight);
526         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
527         return xy[axis];
528     }
529 
530     return coords->getAxisValue(axis);
531 }
532 
getHistoricalAxisValue(int32_t axis,size_t pointerIndex,size_t historicalIndex) const533 float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
534         size_t historicalIndex) const {
535     const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
536 
537     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
538         const vec2 xy = mTransform.transform(coords->getXYValue());
539         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
540         return xy[axis];
541     }
542 
543     return coords->getAxisValue(axis);
544 }
545 
findPointerIndex(int32_t pointerId) const546 ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
547     size_t pointerCount = mPointerProperties.size();
548     for (size_t i = 0; i < pointerCount; i++) {
549         if (mPointerProperties.itemAt(i).id == pointerId) {
550             return i;
551         }
552     }
553     return -1;
554 }
555 
offsetLocation(float xOffset,float yOffset)556 void MotionEvent::offsetLocation(float xOffset, float yOffset) {
557     float currXOffset = mTransform.tx();
558     float currYOffset = mTransform.ty();
559     mTransform.set(currXOffset + xOffset, currYOffset + yOffset);
560 }
561 
scale(float globalScaleFactor)562 void MotionEvent::scale(float globalScaleFactor) {
563     mTransform.set(mTransform.tx() * globalScaleFactor, mTransform.ty() * globalScaleFactor);
564     mXPrecision *= globalScaleFactor;
565     mYPrecision *= globalScaleFactor;
566 
567     size_t numSamples = mSamplePointerCoords.size();
568     for (size_t i = 0; i < numSamples; i++) {
569         mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor, globalScaleFactor,
570                                                  globalScaleFactor);
571     }
572 }
573 
transform(const std::array<float,9> & matrix)574 void MotionEvent::transform(const std::array<float, 9>& matrix) {
575     // We want to preserve the raw axes values stored in the PointerCoords, so we just update the
576     // transform using the values passed in.
577     ui::Transform newTransform;
578     newTransform.set(matrix);
579     mTransform = newTransform * mTransform;
580 
581     // We need to update the AXIS_ORIENTATION value here to maintain the old behavior where the
582     // orientation angle is not affected by the initial transformation set in the MotionEvent.
583     std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(),
584                   [&newTransform](PointerCoords& c) {
585                       float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
586                       c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
587                                      transformAngle(newTransform, orientation));
588                   });
589 }
590 
applyTransform(const std::array<float,9> & matrix)591 void MotionEvent::applyTransform(const std::array<float, 9>& matrix) {
592     ui::Transform transform;
593     transform.set(matrix);
594 
595     // Apply the transformation to all samples.
596     std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(),
597                   [&transform](PointerCoords& c) { c.transform(transform); });
598 }
599 
600 #ifdef __linux__
readFromParcel(ui::Transform & transform,const Parcel & parcel)601 static status_t readFromParcel(ui::Transform& transform, const Parcel& parcel) {
602     float dsdx, dtdx, tx, dtdy, dsdy, ty;
603     status_t status = parcel.readFloat(&dsdx);
604     status |= parcel.readFloat(&dtdx);
605     status |= parcel.readFloat(&tx);
606     status |= parcel.readFloat(&dtdy);
607     status |= parcel.readFloat(&dsdy);
608     status |= parcel.readFloat(&ty);
609 
610     transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
611     return status;
612 }
613 
writeToParcel(const ui::Transform & transform,Parcel & parcel)614 static status_t writeToParcel(const ui::Transform& transform, Parcel& parcel) {
615     status_t status = parcel.writeFloat(transform.dsdx());
616     status |= parcel.writeFloat(transform.dtdx());
617     status |= parcel.writeFloat(transform.tx());
618     status |= parcel.writeFloat(transform.dtdy());
619     status |= parcel.writeFloat(transform.dsdy());
620     status |= parcel.writeFloat(transform.ty());
621     return status;
622 }
623 
readFromParcel(Parcel * parcel)624 status_t MotionEvent::readFromParcel(Parcel* parcel) {
625     size_t pointerCount = parcel->readInt32();
626     size_t sampleCount = parcel->readInt32();
627     if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
628             sampleCount == 0 || sampleCount > MAX_SAMPLES) {
629         return BAD_VALUE;
630     }
631 
632     mId = parcel->readInt32();
633     mDeviceId = parcel->readInt32();
634     mSource = parcel->readUint32();
635     mDisplayId = parcel->readInt32();
636     std::vector<uint8_t> hmac;
637     status_t result = parcel->readByteVector(&hmac);
638     if (result != OK || hmac.size() != 32) {
639         return BAD_VALUE;
640     }
641     std::move(hmac.begin(), hmac.begin() + hmac.size(), mHmac.begin());
642     mAction = parcel->readInt32();
643     mActionButton = parcel->readInt32();
644     mFlags = parcel->readInt32();
645     mEdgeFlags = parcel->readInt32();
646     mMetaState = parcel->readInt32();
647     mButtonState = parcel->readInt32();
648     mClassification = static_cast<MotionClassification>(parcel->readByte());
649 
650     result = android::readFromParcel(mTransform, *parcel);
651     if (result != OK) {
652         return result;
653     }
654     mXPrecision = parcel->readFloat();
655     mYPrecision = parcel->readFloat();
656     mRawXCursorPosition = parcel->readFloat();
657     mRawYCursorPosition = parcel->readFloat();
658     mDisplayWidth = parcel->readInt32();
659     mDisplayHeight = parcel->readInt32();
660     mDownTime = parcel->readInt64();
661 
662     mPointerProperties.clear();
663     mPointerProperties.setCapacity(pointerCount);
664     mSampleEventTimes.clear();
665     mSampleEventTimes.reserve(sampleCount);
666     mSamplePointerCoords.clear();
667     mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
668 
669     for (size_t i = 0; i < pointerCount; i++) {
670         mPointerProperties.push();
671         PointerProperties& properties = mPointerProperties.editTop();
672         properties.id = parcel->readInt32();
673         properties.toolType = parcel->readInt32();
674     }
675 
676     while (sampleCount > 0) {
677         sampleCount--;
678         mSampleEventTimes.push_back(parcel->readInt64());
679         for (size_t i = 0; i < pointerCount; i++) {
680             mSamplePointerCoords.push();
681             status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
682             if (status) {
683                 return status;
684             }
685         }
686     }
687     return OK;
688 }
689 
writeToParcel(Parcel * parcel) const690 status_t MotionEvent::writeToParcel(Parcel* parcel) const {
691     size_t pointerCount = mPointerProperties.size();
692     size_t sampleCount = mSampleEventTimes.size();
693 
694     parcel->writeInt32(pointerCount);
695     parcel->writeInt32(sampleCount);
696 
697     parcel->writeInt32(mId);
698     parcel->writeInt32(mDeviceId);
699     parcel->writeUint32(mSource);
700     parcel->writeInt32(mDisplayId);
701     std::vector<uint8_t> hmac(mHmac.begin(), mHmac.end());
702     parcel->writeByteVector(hmac);
703     parcel->writeInt32(mAction);
704     parcel->writeInt32(mActionButton);
705     parcel->writeInt32(mFlags);
706     parcel->writeInt32(mEdgeFlags);
707     parcel->writeInt32(mMetaState);
708     parcel->writeInt32(mButtonState);
709     parcel->writeByte(static_cast<int8_t>(mClassification));
710 
711     status_t result = android::writeToParcel(mTransform, *parcel);
712     if (result != OK) {
713         return result;
714     }
715     parcel->writeFloat(mXPrecision);
716     parcel->writeFloat(mYPrecision);
717     parcel->writeFloat(mRawXCursorPosition);
718     parcel->writeFloat(mRawYCursorPosition);
719     parcel->writeInt32(mDisplayWidth);
720     parcel->writeInt32(mDisplayHeight);
721     parcel->writeInt64(mDownTime);
722 
723     for (size_t i = 0; i < pointerCount; i++) {
724         const PointerProperties& properties = mPointerProperties.itemAt(i);
725         parcel->writeInt32(properties.id);
726         parcel->writeInt32(properties.toolType);
727     }
728 
729     const PointerCoords* pc = mSamplePointerCoords.array();
730     for (size_t h = 0; h < sampleCount; h++) {
731         parcel->writeInt64(mSampleEventTimes[h]);
732         for (size_t i = 0; i < pointerCount; i++) {
733             status_t status = (pc++)->writeToParcel(parcel);
734             if (status) {
735                 return status;
736             }
737         }
738     }
739     return OK;
740 }
741 #endif
742 
isTouchEvent(uint32_t source,int32_t action)743 bool MotionEvent::isTouchEvent(uint32_t source, int32_t action) {
744     if (source & AINPUT_SOURCE_CLASS_POINTER) {
745         // Specifically excludes HOVER_MOVE and SCROLL.
746         switch (action & AMOTION_EVENT_ACTION_MASK) {
747         case AMOTION_EVENT_ACTION_DOWN:
748         case AMOTION_EVENT_ACTION_MOVE:
749         case AMOTION_EVENT_ACTION_UP:
750         case AMOTION_EVENT_ACTION_POINTER_DOWN:
751         case AMOTION_EVENT_ACTION_POINTER_UP:
752         case AMOTION_EVENT_ACTION_CANCEL:
753         case AMOTION_EVENT_ACTION_OUTSIDE:
754             return true;
755         }
756     }
757     return false;
758 }
759 
getLabel(int32_t axis)760 const char* MotionEvent::getLabel(int32_t axis) {
761     return InputEventLookup::getAxisLabel(axis);
762 }
763 
getAxisFromLabel(const char * label)764 int32_t MotionEvent::getAxisFromLabel(const char* label) {
765     return InputEventLookup::getAxisByLabel(label);
766 }
767 
actionToString(int32_t action)768 std::string MotionEvent::actionToString(int32_t action) {
769     // Convert MotionEvent action to string
770     switch (action & AMOTION_EVENT_ACTION_MASK) {
771         case AMOTION_EVENT_ACTION_DOWN:
772             return "DOWN";
773         case AMOTION_EVENT_ACTION_UP:
774             return "UP";
775         case AMOTION_EVENT_ACTION_MOVE:
776             return "MOVE";
777         case AMOTION_EVENT_ACTION_CANCEL:
778             return "CANCEL";
779         case AMOTION_EVENT_ACTION_OUTSIDE:
780             return "OUTSIDE";
781         case AMOTION_EVENT_ACTION_POINTER_DOWN:
782             return "POINTER_DOWN";
783         case AMOTION_EVENT_ACTION_POINTER_UP:
784             return "POINTER_UP";
785         case AMOTION_EVENT_ACTION_HOVER_MOVE:
786             return "HOVER_MOVE";
787         case AMOTION_EVENT_ACTION_SCROLL:
788             return "SCROLL";
789         case AMOTION_EVENT_ACTION_HOVER_ENTER:
790             return "HOVER_ENTER";
791         case AMOTION_EVENT_ACTION_HOVER_EXIT:
792             return "HOVER_EXIT";
793         case AMOTION_EVENT_ACTION_BUTTON_PRESS:
794             return "BUTTON_PRESS";
795         case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
796             return "BUTTON_RELEASE";
797     }
798     return android::base::StringPrintf("%" PRId32, action);
799 }
800 
801 // --- FocusEvent ---
802 
initialize(int32_t id,bool hasFocus,bool inTouchMode)803 void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
804     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
805                            ADISPLAY_ID_NONE, INVALID_HMAC);
806     mHasFocus = hasFocus;
807     mInTouchMode = inTouchMode;
808 }
809 
initialize(const FocusEvent & from)810 void FocusEvent::initialize(const FocusEvent& from) {
811     InputEvent::initialize(from);
812     mHasFocus = from.mHasFocus;
813     mInTouchMode = from.mInTouchMode;
814 }
815 
816 // --- CaptureEvent ---
817 
initialize(int32_t id,bool pointerCaptureEnabled)818 void CaptureEvent::initialize(int32_t id, bool pointerCaptureEnabled) {
819     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
820                            ADISPLAY_ID_NONE, INVALID_HMAC);
821     mPointerCaptureEnabled = pointerCaptureEnabled;
822 }
823 
initialize(const CaptureEvent & from)824 void CaptureEvent::initialize(const CaptureEvent& from) {
825     InputEvent::initialize(from);
826     mPointerCaptureEnabled = from.mPointerCaptureEnabled;
827 }
828 
829 // --- DragEvent ---
830 
initialize(int32_t id,float x,float y,bool isExiting)831 void DragEvent::initialize(int32_t id, float x, float y, bool isExiting) {
832     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
833                            ADISPLAY_ID_NONE, INVALID_HMAC);
834     mIsExiting = isExiting;
835     mX = x;
836     mY = y;
837 }
838 
initialize(const DragEvent & from)839 void DragEvent::initialize(const DragEvent& from) {
840     InputEvent::initialize(from);
841     mIsExiting = from.mIsExiting;
842     mX = from.mX;
843     mY = from.mY;
844 }
845 
846 // --- PooledInputEventFactory ---
847 
PooledInputEventFactory(size_t maxPoolSize)848 PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
849         mMaxPoolSize(maxPoolSize) {
850 }
851 
~PooledInputEventFactory()852 PooledInputEventFactory::~PooledInputEventFactory() {
853 }
854 
createKeyEvent()855 KeyEvent* PooledInputEventFactory::createKeyEvent() {
856     if (mKeyEventPool.empty()) {
857         return new KeyEvent();
858     }
859     KeyEvent* event = mKeyEventPool.front().release();
860     mKeyEventPool.pop();
861     return event;
862 }
863 
createMotionEvent()864 MotionEvent* PooledInputEventFactory::createMotionEvent() {
865     if (mMotionEventPool.empty()) {
866         return new MotionEvent();
867     }
868     MotionEvent* event = mMotionEventPool.front().release();
869     mMotionEventPool.pop();
870     return event;
871 }
872 
createFocusEvent()873 FocusEvent* PooledInputEventFactory::createFocusEvent() {
874     if (mFocusEventPool.empty()) {
875         return new FocusEvent();
876     }
877     FocusEvent* event = mFocusEventPool.front().release();
878     mFocusEventPool.pop();
879     return event;
880 }
881 
createCaptureEvent()882 CaptureEvent* PooledInputEventFactory::createCaptureEvent() {
883     if (mCaptureEventPool.empty()) {
884         return new CaptureEvent();
885     }
886     CaptureEvent* event = mCaptureEventPool.front().release();
887     mCaptureEventPool.pop();
888     return event;
889 }
890 
createDragEvent()891 DragEvent* PooledInputEventFactory::createDragEvent() {
892     if (mDragEventPool.empty()) {
893         return new DragEvent();
894     }
895     DragEvent* event = mDragEventPool.front().release();
896     mDragEventPool.pop();
897     return event;
898 }
899 
recycle(InputEvent * event)900 void PooledInputEventFactory::recycle(InputEvent* event) {
901     switch (event->getType()) {
902     case AINPUT_EVENT_TYPE_KEY:
903         if (mKeyEventPool.size() < mMaxPoolSize) {
904             mKeyEventPool.push(std::unique_ptr<KeyEvent>(static_cast<KeyEvent*>(event)));
905             return;
906         }
907         break;
908     case AINPUT_EVENT_TYPE_MOTION:
909         if (mMotionEventPool.size() < mMaxPoolSize) {
910             mMotionEventPool.push(std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event)));
911             return;
912         }
913         break;
914     case AINPUT_EVENT_TYPE_FOCUS:
915         if (mFocusEventPool.size() < mMaxPoolSize) {
916             mFocusEventPool.push(std::unique_ptr<FocusEvent>(static_cast<FocusEvent*>(event)));
917             return;
918         }
919         break;
920     case AINPUT_EVENT_TYPE_CAPTURE:
921         if (mCaptureEventPool.size() < mMaxPoolSize) {
922             mCaptureEventPool.push(
923                     std::unique_ptr<CaptureEvent>(static_cast<CaptureEvent*>(event)));
924             return;
925         }
926         break;
927     case AINPUT_EVENT_TYPE_DRAG:
928         if (mDragEventPool.size() < mMaxPoolSize) {
929             mDragEventPool.push(std::unique_ptr<DragEvent>(static_cast<DragEvent*>(event)));
930             return;
931         }
932         break;
933     }
934     delete event;
935 }
936 
937 } // namespace android
938