• 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 <string.h>
24 #include <optional>
25 
26 #include <android-base/file.h>
27 #include <android-base/logging.h>
28 #include <android-base/stringprintf.h>
29 #include <cutils/compiler.h>
30 #include <gui/constants.h>
31 #include <input/DisplayViewport.h>
32 #include <input/Input.h>
33 #include <input/InputDevice.h>
34 #include <input/InputEventLabels.h>
35 
36 #ifdef __linux__
37 #include <binder/Parcel.h>
38 #endif
39 #if defined(__ANDROID__)
40 #include <sys/random.h>
41 #endif
42 
43 using android::base::StringPrintf;
44 
45 namespace android {
46 
47 namespace {
48 
shouldDisregardTransformation(uint32_t source)49 bool shouldDisregardTransformation(uint32_t source) {
50     // Do not apply any transformations to axes from joysticks, touchpads, or relative mice.
51     return isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK) ||
52             isFromSource(source, AINPUT_SOURCE_CLASS_POSITION) ||
53             isFromSource(source, AINPUT_SOURCE_MOUSE_RELATIVE);
54 }
55 
shouldDisregardOffset(uint32_t source)56 bool shouldDisregardOffset(uint32_t source) {
57     // Pointer events are the only type of events that refer to absolute coordinates on the display,
58     // so we should apply the entire window transform. For other types of events, we should make
59     // sure to not apply the window translation/offset.
60     return !isFromSource(source, AINPUT_SOURCE_CLASS_POINTER);
61 }
62 
63 } // namespace
64 
motionClassificationToString(MotionClassification classification)65 const char* motionClassificationToString(MotionClassification classification) {
66     switch (classification) {
67         case MotionClassification::NONE:
68             return "NONE";
69         case MotionClassification::AMBIGUOUS_GESTURE:
70             return "AMBIGUOUS_GESTURE";
71         case MotionClassification::DEEP_PRESS:
72             return "DEEP_PRESS";
73         case MotionClassification::TWO_FINGER_SWIPE:
74             return "TWO_FINGER_SWIPE";
75         case MotionClassification::MULTI_FINGER_SWIPE:
76             return "MULTI_FINGER_SWIPE";
77         case MotionClassification::PINCH:
78             return "PINCH";
79     }
80 }
81 
82 // --- IdGenerator ---
83 #if defined(__ANDROID__)
84 [[maybe_unused]]
85 #endif
86 static status_t
getRandomBytes(uint8_t * data,size_t size)87 getRandomBytes(uint8_t* data, size_t size) {
88     int ret = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
89     if (ret == -1) {
90         return -errno;
91     }
92 
93     base::unique_fd fd(ret);
94     if (!base::ReadFully(fd, data, size)) {
95         return -errno;
96     }
97     return OK;
98 }
99 
IdGenerator(Source source)100 IdGenerator::IdGenerator(Source source) : mSource(source) {}
101 
nextId() const102 int32_t IdGenerator::nextId() const {
103     constexpr uint32_t SEQUENCE_NUMBER_MASK = ~SOURCE_MASK;
104     int32_t id = 0;
105 
106 #if defined(__ANDROID__)
107     // On device, prefer 'getrandom' to '/dev/urandom' because it's faster.
108     constexpr size_t BUF_LEN = sizeof(id);
109     size_t totalBytes = 0;
110     while (totalBytes < BUF_LEN) {
111         ssize_t bytes = TEMP_FAILURE_RETRY(getrandom(&id, BUF_LEN, GRND_NONBLOCK));
112         if (CC_UNLIKELY(bytes < 0)) {
113             ALOGW("Failed to fill in random number for sequence number: %s.", strerror(errno));
114             id = 0;
115             break;
116         }
117         totalBytes += bytes;
118     }
119 #else
120 #if defined(__linux__)
121     // On host, <sys/random.h> / GRND_NONBLOCK is not available
122     while (true) {
123         status_t result = getRandomBytes(reinterpret_cast<uint8_t*>(&id), sizeof(id));
124         if (result == OK) {
125             break;
126         }
127     }
128 #endif // __linux__
129 #endif // __ANDROID__
130     return (id & SEQUENCE_NUMBER_MASK) | static_cast<int32_t>(mSource);
131 }
132 
133 // --- InputEvent ---
134 
135 // Due to precision limitations when working with floating points, transforming - namely
136 // scaling - floating points can lead to minute errors. We round transformed values to approximately
137 // three decimal places so that values like 0.99997 show up as 1.0.
roundTransformedCoords(float val)138 inline float roundTransformedCoords(float val) {
139     // Use a power to two to approximate three decimal places to potentially reduce some cycles.
140     // This should be at least as precise as MotionEvent::ROUNDING_PRECISION.
141     return std::round(val * 1024.f) / 1024.f;
142 }
143 
roundTransformedCoords(vec2 p)144 inline vec2 roundTransformedCoords(vec2 p) {
145     return {roundTransformedCoords(p.x), roundTransformedCoords(p.y)};
146 }
147 
transformWithoutTranslation(const ui::Transform & transform,const vec2 & xy)148 vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy) {
149     const vec2 transformedXy = transform.transform(xy);
150     const vec2 transformedOrigin = transform.transform(0, 0);
151     return roundTransformedCoords(transformedXy - transformedOrigin);
152 }
153 
transformAngle(const ui::Transform & transform,float angleRadians)154 float transformAngle(const ui::Transform& transform, float angleRadians) {
155     // Construct and transform a vector oriented at the specified clockwise angle from vertical.
156     // Coordinate system: down is increasing Y, right is increasing X.
157     float x = sinf(angleRadians);
158     float y = -cosf(angleRadians);
159     vec2 transformedPoint = transform.transform(x, y);
160 
161     // Determine how the origin is transformed by the matrix so that we
162     // can transform orientation vectors.
163     const vec2 origin = transform.transform(0, 0);
164 
165     transformedPoint.x -= origin.x;
166     transformedPoint.y -= origin.y;
167 
168     // Derive the transformed vector's clockwise angle from vertical.
169     // The return value of atan2f is in range [-pi, pi] which conforms to the orientation API.
170     return atan2f(transformedPoint.x, -transformedPoint.y);
171 }
172 
inputEventSourceToString(int32_t source)173 std::string inputEventSourceToString(int32_t source) {
174     if (source == AINPUT_SOURCE_UNKNOWN) {
175         return "UNKNOWN";
176     }
177     if (source == static_cast<int32_t>(AINPUT_SOURCE_ANY)) {
178         return "ANY";
179     }
180     static const std::map<int32_t, const char*> SOURCES{
181             {AINPUT_SOURCE_KEYBOARD, "KEYBOARD"},
182             {AINPUT_SOURCE_DPAD, "DPAD"},
183             {AINPUT_SOURCE_GAMEPAD, "GAMEPAD"},
184             {AINPUT_SOURCE_TOUCHSCREEN, "TOUCHSCREEN"},
185             {AINPUT_SOURCE_MOUSE, "MOUSE"},
186             {AINPUT_SOURCE_STYLUS, "STYLUS"},
187             {AINPUT_SOURCE_BLUETOOTH_STYLUS, "BLUETOOTH_STYLUS"},
188             {AINPUT_SOURCE_TRACKBALL, "TRACKBALL"},
189             {AINPUT_SOURCE_MOUSE_RELATIVE, "MOUSE_RELATIVE"},
190             {AINPUT_SOURCE_TOUCHPAD, "TOUCHPAD"},
191             {AINPUT_SOURCE_TOUCH_NAVIGATION, "TOUCH_NAVIGATION"},
192             {AINPUT_SOURCE_JOYSTICK, "JOYSTICK"},
193             {AINPUT_SOURCE_HDMI, "HDMI"},
194             {AINPUT_SOURCE_SENSOR, "SENSOR"},
195             {AINPUT_SOURCE_ROTARY_ENCODER, "ROTARY_ENCODER"},
196     };
197     std::string result;
198     for (const auto& [source_entry, str] : SOURCES) {
199         if ((source & source_entry) == source_entry) {
200             if (!result.empty()) {
201                 result += " | ";
202             }
203             result += str;
204         }
205     }
206     if (result.empty()) {
207         result = StringPrintf("0x%08x", source);
208     }
209     return result;
210 }
211 
isFromSource(uint32_t source,uint32_t test)212 bool isFromSource(uint32_t source, uint32_t test) {
213     return (source & test) == test;
214 }
215 
isStylusToolType(ToolType toolType)216 bool isStylusToolType(ToolType toolType) {
217     return toolType == ToolType::STYLUS || toolType == ToolType::ERASER;
218 }
219 
verifiedKeyEventFromKeyEvent(const KeyEvent & event)220 VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event) {
221     return {{VerifiedInputEvent::Type::KEY, event.getDeviceId(), event.getEventTime(),
222              event.getSource(), event.getDisplayId()},
223             event.getAction(),
224             event.getFlags() & VERIFIED_KEY_EVENT_FLAGS,
225             event.getDownTime(),
226             event.getKeyCode(),
227             event.getScanCode(),
228             event.getMetaState(),
229             event.getRepeatCount()};
230 }
231 
verifiedMotionEventFromMotionEvent(const MotionEvent & event)232 VerifiedMotionEvent verifiedMotionEventFromMotionEvent(const MotionEvent& event) {
233     return {{VerifiedInputEvent::Type::MOTION, event.getDeviceId(), event.getEventTime(),
234              event.getSource(), event.getDisplayId()},
235             event.getRawX(0),
236             event.getRawY(0),
237             event.getActionMasked(),
238             event.getFlags() & VERIFIED_MOTION_EVENT_FLAGS,
239             event.getDownTime(),
240             event.getMetaState(),
241             event.getButtonState()};
242 }
243 
initialize(int32_t id,int32_t deviceId,uint32_t source,int32_t displayId,std::array<uint8_t,32> hmac)244 void InputEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
245                             std::array<uint8_t, 32> hmac) {
246     mId = id;
247     mDeviceId = deviceId;
248     mSource = source;
249     mDisplayId = displayId;
250     mHmac = hmac;
251 }
252 
initialize(const InputEvent & from)253 void InputEvent::initialize(const InputEvent& from) {
254     mId = from.mId;
255     mDeviceId = from.mDeviceId;
256     mSource = from.mSource;
257     mDisplayId = from.mDisplayId;
258     mHmac = from.mHmac;
259 }
260 
nextId()261 int32_t InputEvent::nextId() {
262     static IdGenerator idGen(IdGenerator::Source::OTHER);
263     return idGen.nextId();
264 }
265 
operator <<(std::ostream & out,const InputEvent & event)266 std::ostream& operator<<(std::ostream& out, const InputEvent& event) {
267     switch (event.getType()) {
268         case InputEventType::KEY: {
269             const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
270             out << keyEvent;
271             return out;
272         }
273         case InputEventType::MOTION: {
274             const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
275             out << motionEvent;
276             return out;
277         }
278         case InputEventType::FOCUS: {
279             out << "FocusEvent";
280             return out;
281         }
282         case InputEventType::CAPTURE: {
283             out << "CaptureEvent";
284             return out;
285         }
286         case InputEventType::DRAG: {
287             out << "DragEvent";
288             return out;
289         }
290         case InputEventType::TOUCH_MODE: {
291             out << "TouchModeEvent";
292             return out;
293         }
294     }
295 }
296 
297 // --- KeyEvent ---
298 
getLabel(int32_t keyCode)299 const char* KeyEvent::getLabel(int32_t keyCode) {
300     return InputEventLookup::getLabelByKeyCode(keyCode);
301 }
302 
getKeyCodeFromLabel(const char * label)303 std::optional<int> KeyEvent::getKeyCodeFromLabel(const char* label) {
304     return InputEventLookup::getKeyCodeByLabel(label);
305 }
306 
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)307 void KeyEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
308                           std::array<uint8_t, 32> hmac, int32_t action, int32_t flags,
309                           int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
310                           nsecs_t downTime, nsecs_t eventTime) {
311     InputEvent::initialize(id, deviceId, source, displayId, hmac);
312     mAction = action;
313     mFlags = flags;
314     mKeyCode = keyCode;
315     mScanCode = scanCode;
316     mMetaState = metaState;
317     mRepeatCount = repeatCount;
318     mDownTime = downTime;
319     mEventTime = eventTime;
320 }
321 
initialize(const KeyEvent & from)322 void KeyEvent::initialize(const KeyEvent& from) {
323     InputEvent::initialize(from);
324     mAction = from.mAction;
325     mFlags = from.mFlags;
326     mKeyCode = from.mKeyCode;
327     mScanCode = from.mScanCode;
328     mMetaState = from.mMetaState;
329     mRepeatCount = from.mRepeatCount;
330     mDownTime = from.mDownTime;
331     mEventTime = from.mEventTime;
332 }
333 
actionToString(int32_t action)334 const char* KeyEvent::actionToString(int32_t action) {
335     // Convert KeyEvent action to string
336     switch (action) {
337         case AKEY_EVENT_ACTION_DOWN:
338             return "DOWN";
339         case AKEY_EVENT_ACTION_UP:
340             return "UP";
341         case AKEY_EVENT_ACTION_MULTIPLE:
342             return "MULTIPLE";
343     }
344     return "UNKNOWN";
345 }
346 
operator <<(std::ostream & out,const KeyEvent & event)347 std::ostream& operator<<(std::ostream& out, const KeyEvent& event) {
348     out << "KeyEvent { action=" << KeyEvent::actionToString(event.getAction());
349 
350     out << ", keycode=" << event.getKeyCode() << "(" << KeyEvent::getLabel(event.getKeyCode())
351         << ")";
352 
353     if (event.getMetaState() != 0) {
354         out << ", metaState=" << event.getMetaState();
355     }
356 
357     out << ", eventTime=" << event.getEventTime();
358     out << ", downTime=" << event.getDownTime();
359     out << ", flags=" << std::hex << event.getFlags() << std::dec;
360     out << ", repeatCount=" << event.getRepeatCount();
361     out << ", deviceId=" << event.getDeviceId();
362     out << ", source=" << inputEventSourceToString(event.getSource());
363     out << ", displayId=" << event.getDisplayId();
364     out << ", eventId=" << event.getId();
365     out << "}";
366     return out;
367 }
368 
369 // --- PointerCoords ---
370 
getAxisValue(int32_t axis) const371 float PointerCoords::getAxisValue(int32_t axis) const {
372     if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
373         return 0;
374     }
375     return values[BitSet64::getIndexOfBit(bits, axis)];
376 }
377 
setAxisValue(int32_t axis,float value)378 status_t PointerCoords::setAxisValue(int32_t axis, float value) {
379     if (axis < 0 || axis > 63) {
380         return NAME_NOT_FOUND;
381     }
382 
383     uint32_t index = BitSet64::getIndexOfBit(bits, axis);
384     if (!BitSet64::hasBit(bits, axis)) {
385         if (value == 0) {
386             return OK; // axes with value 0 do not need to be stored
387         }
388 
389         uint32_t count = BitSet64::count(bits);
390         if (count >= MAX_AXES) {
391             tooManyAxes(axis);
392             return NO_MEMORY;
393         }
394         BitSet64::markBit(bits, axis);
395         for (uint32_t i = count; i > index; i--) {
396             values[i] = values[i - 1];
397         }
398     }
399 
400     values[index] = value;
401     return OK;
402 }
403 
scaleAxisValue(PointerCoords & c,int axis,float scaleFactor)404 static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
405     float value = c.getAxisValue(axis);
406     if (value != 0) {
407         c.setAxisValue(axis, value * scaleFactor);
408     }
409 }
410 
scale(float globalScaleFactor,float windowXScale,float windowYScale)411 void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
412     // No need to scale pressure or size since they are normalized.
413     // No need to scale orientation since it is meaningless to do so.
414 
415     // If there is a global scale factor, it is included in the windowX/YScale
416     // so we don't need to apply it twice to the X/Y axes.
417     // However we don't want to apply any windowXYScale not included in the global scale
418     // to the TOUCH_MAJOR/MINOR coordinates.
419     scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
420     scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
421     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
422     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
423     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
424     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
425     scaleAxisValue(*this, AMOTION_EVENT_AXIS_RELATIVE_X, windowXScale);
426     scaleAxisValue(*this, AMOTION_EVENT_AXIS_RELATIVE_Y, windowYScale);
427 }
428 
429 #ifdef __linux__
readFromParcel(Parcel * parcel)430 status_t PointerCoords::readFromParcel(Parcel* parcel) {
431     bits = parcel->readInt64();
432 
433     uint32_t count = BitSet64::count(bits);
434     if (count > MAX_AXES) {
435         return BAD_VALUE;
436     }
437 
438     for (uint32_t i = 0; i < count; i++) {
439         values[i] = parcel->readFloat();
440     }
441 
442     isResampled = parcel->readBool();
443     return OK;
444 }
445 
writeToParcel(Parcel * parcel) const446 status_t PointerCoords::writeToParcel(Parcel* parcel) const {
447     parcel->writeInt64(bits);
448 
449     uint32_t count = BitSet64::count(bits);
450     for (uint32_t i = 0; i < count; i++) {
451         parcel->writeFloat(values[i]);
452     }
453 
454     parcel->writeBool(isResampled);
455     return OK;
456 }
457 #endif
458 
tooManyAxes(int axis)459 void PointerCoords::tooManyAxes(int axis) {
460     ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
461             "cannot contain more than %d axis values.", axis, int(MAX_AXES));
462 }
463 
operator ==(const PointerCoords & other) const464 bool PointerCoords::operator==(const PointerCoords& other) const {
465     if (bits != other.bits) {
466         return false;
467     }
468     uint32_t count = BitSet64::count(bits);
469     for (uint32_t i = 0; i < count; i++) {
470         if (values[i] != other.values[i]) {
471             return false;
472         }
473     }
474     if (isResampled != other.isResampled) {
475         return false;
476     }
477     return true;
478 }
479 
transform(const ui::Transform & transform)480 void PointerCoords::transform(const ui::Transform& transform) {
481     const vec2 xy = transform.transform(getXYValue());
482     setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
483     setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
484 
485     if (BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_RELATIVE_X) ||
486         BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_RELATIVE_Y)) {
487         const ui::Transform rotation(transform.getOrientation());
488         const vec2 relativeXy = rotation.transform(getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
489                                                    getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
490         setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, relativeXy.x);
491         setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, relativeXy.y);
492     }
493 
494     if (BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_ORIENTATION)) {
495         const float val = getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
496         setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(transform, val));
497     }
498 }
499 
500 // --- PointerProperties ---
501 
operator ==(const PointerProperties & other) const502 bool PointerProperties::operator==(const PointerProperties& other) const {
503     return id == other.id
504             && toolType == other.toolType;
505 }
506 
copyFrom(const PointerProperties & other)507 void PointerProperties::copyFrom(const PointerProperties& other) {
508     id = other.id;
509     toolType = other.toolType;
510 }
511 
512 
513 // --- MotionEvent ---
514 
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,const ui::Transform & rawTransform,nsecs_t downTime,nsecs_t eventTime,size_t pointerCount,const PointerProperties * pointerProperties,const PointerCoords * pointerCoords)515 void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
516                              std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
517                              int32_t flags, int32_t edgeFlags, int32_t metaState,
518                              int32_t buttonState, MotionClassification classification,
519                              const ui::Transform& transform, float xPrecision, float yPrecision,
520                              float rawXCursorPosition, float rawYCursorPosition,
521                              const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
522                              size_t pointerCount, const PointerProperties* pointerProperties,
523                              const PointerCoords* pointerCoords) {
524     InputEvent::initialize(id, deviceId, source, displayId, hmac);
525     mAction = action;
526     mActionButton = actionButton;
527     mFlags = flags;
528     mEdgeFlags = edgeFlags;
529     mMetaState = metaState;
530     mButtonState = buttonState;
531     mClassification = classification;
532     mTransform = transform;
533     mXPrecision = xPrecision;
534     mYPrecision = yPrecision;
535     mRawXCursorPosition = rawXCursorPosition;
536     mRawYCursorPosition = rawYCursorPosition;
537     mRawTransform = rawTransform;
538     mDownTime = downTime;
539     mPointerProperties.clear();
540     mPointerProperties.insert(mPointerProperties.end(), &pointerProperties[0],
541                               &pointerProperties[pointerCount]);
542     mSampleEventTimes.clear();
543     mSamplePointerCoords.clear();
544     addSample(eventTime, pointerCoords);
545 }
546 
copyFrom(const MotionEvent * other,bool keepHistory)547 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
548     InputEvent::initialize(other->mId, other->mDeviceId, other->mSource, other->mDisplayId,
549                            other->mHmac);
550     mAction = other->mAction;
551     mActionButton = other->mActionButton;
552     mFlags = other->mFlags;
553     mEdgeFlags = other->mEdgeFlags;
554     mMetaState = other->mMetaState;
555     mButtonState = other->mButtonState;
556     mClassification = other->mClassification;
557     mTransform = other->mTransform;
558     mXPrecision = other->mXPrecision;
559     mYPrecision = other->mYPrecision;
560     mRawXCursorPosition = other->mRawXCursorPosition;
561     mRawYCursorPosition = other->mRawYCursorPosition;
562     mRawTransform = other->mRawTransform;
563     mDownTime = other->mDownTime;
564     mPointerProperties = other->mPointerProperties;
565 
566     if (keepHistory) {
567         mSampleEventTimes = other->mSampleEventTimes;
568         mSamplePointerCoords = other->mSamplePointerCoords;
569     } else {
570         mSampleEventTimes.clear();
571         mSampleEventTimes.push_back(other->getEventTime());
572         mSamplePointerCoords.clear();
573         size_t pointerCount = other->getPointerCount();
574         size_t historySize = other->getHistorySize();
575         mSamplePointerCoords
576                 .insert(mSamplePointerCoords.end(),
577                         &other->mSamplePointerCoords[historySize * pointerCount],
578                         &other->mSamplePointerCoords[historySize * pointerCount + pointerCount]);
579     }
580 }
581 
addSample(int64_t eventTime,const PointerCoords * pointerCoords)582 void MotionEvent::addSample(
583         int64_t eventTime,
584         const PointerCoords* pointerCoords) {
585     mSampleEventTimes.push_back(eventTime);
586     mSamplePointerCoords.insert(mSamplePointerCoords.end(), &pointerCoords[0],
587                                 &pointerCoords[getPointerCount()]);
588 }
589 
getSurfaceRotation() const590 std::optional<ui::Rotation> MotionEvent::getSurfaceRotation() const {
591     // The surface rotation is the rotation from the window's coordinate space to that of the
592     // display. Since the event's transform takes display space coordinates to window space, the
593     // returned surface rotation is the inverse of the rotation for the surface.
594     switch (mTransform.getOrientation()) {
595         case ui::Transform::ROT_0:
596             return ui::ROTATION_0;
597         case ui::Transform::ROT_90:
598             return ui::ROTATION_270;
599         case ui::Transform::ROT_180:
600             return ui::ROTATION_180;
601         case ui::Transform::ROT_270:
602             return ui::ROTATION_90;
603         default:
604             return std::nullopt;
605     }
606 }
607 
getXCursorPosition() const608 float MotionEvent::getXCursorPosition() const {
609     vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
610     return roundTransformedCoords(vals.x);
611 }
612 
getYCursorPosition() const613 float MotionEvent::getYCursorPosition() const {
614     vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
615     return roundTransformedCoords(vals.y);
616 }
617 
setCursorPosition(float x,float y)618 void MotionEvent::setCursorPosition(float x, float y) {
619     ui::Transform inverse = mTransform.inverse();
620     vec2 vals = inverse.transform(x, y);
621     mRawXCursorPosition = vals.x;
622     mRawYCursorPosition = vals.y;
623 }
624 
getRawPointerCoords(size_t pointerIndex) const625 const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
626     if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) {
627         LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this;
628     }
629     const size_t position = getHistorySize() * getPointerCount() + pointerIndex;
630     if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) {
631         LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this;
632     }
633     return &mSamplePointerCoords[position];
634 }
635 
getRawAxisValue(int32_t axis,size_t pointerIndex) const636 float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
637     return getHistoricalRawAxisValue(axis, pointerIndex, getHistorySize());
638 }
639 
getAxisValue(int32_t axis,size_t pointerIndex) const640 float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
641     return getHistoricalAxisValue(axis, pointerIndex, getHistorySize());
642 }
643 
getHistoricalRawPointerCoords(size_t pointerIndex,size_t historicalIndex) const644 const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
645         size_t pointerIndex, size_t historicalIndex) const {
646     if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) {
647         LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this;
648     }
649     if (CC_UNLIKELY(historicalIndex < 0 || historicalIndex > getHistorySize())) {
650         LOG(FATAL) << __func__ << ": Invalid historical index " << historicalIndex << " for "
651                    << *this;
652     }
653     const size_t position = historicalIndex * getPointerCount() + pointerIndex;
654     if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) {
655         LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this;
656     }
657     return &mSamplePointerCoords[position];
658 }
659 
getHistoricalRawAxisValue(int32_t axis,size_t pointerIndex,size_t historicalIndex) const660 float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
661                                              size_t historicalIndex) const {
662     const PointerCoords& coords = *getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
663     return calculateTransformedAxisValue(axis, mSource, mRawTransform, coords);
664 }
665 
getHistoricalAxisValue(int32_t axis,size_t pointerIndex,size_t historicalIndex) const666 float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
667                                           size_t historicalIndex) const {
668     const PointerCoords& coords = *getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
669     return calculateTransformedAxisValue(axis, mSource, mTransform, coords);
670 }
671 
findPointerIndex(int32_t pointerId) const672 ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
673     size_t pointerCount = mPointerProperties.size();
674     for (size_t i = 0; i < pointerCount; i++) {
675         if (mPointerProperties[i].id == pointerId) {
676             return i;
677         }
678     }
679     return -1;
680 }
681 
offsetLocation(float xOffset,float yOffset)682 void MotionEvent::offsetLocation(float xOffset, float yOffset) {
683     float currXOffset = mTransform.tx();
684     float currYOffset = mTransform.ty();
685     mTransform.set(currXOffset + xOffset, currYOffset + yOffset);
686 }
687 
scale(float globalScaleFactor)688 void MotionEvent::scale(float globalScaleFactor) {
689     mTransform.set(mTransform.tx() * globalScaleFactor, mTransform.ty() * globalScaleFactor);
690     mRawTransform.set(mRawTransform.tx() * globalScaleFactor,
691                       mRawTransform.ty() * globalScaleFactor);
692     mXPrecision *= globalScaleFactor;
693     mYPrecision *= globalScaleFactor;
694 
695     size_t numSamples = mSamplePointerCoords.size();
696     for (size_t i = 0; i < numSamples; i++) {
697         mSamplePointerCoords[i].scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
698     }
699 }
700 
transform(const std::array<float,9> & matrix)701 void MotionEvent::transform(const std::array<float, 9>& matrix) {
702     // We want to preserve the raw axes values stored in the PointerCoords, so we just update the
703     // transform using the values passed in.
704     ui::Transform newTransform;
705     newTransform.set(matrix);
706     mTransform = newTransform * mTransform;
707 }
708 
applyTransform(const std::array<float,9> & matrix)709 void MotionEvent::applyTransform(const std::array<float, 9>& matrix) {
710     ui::Transform transform;
711     transform.set(matrix);
712 
713     // Apply the transformation to all samples.
714     std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(),
715                   [&transform](PointerCoords& c) { c.transform(transform); });
716 
717     if (mRawXCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
718         mRawYCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
719         const vec2 cursor = transform.transform(mRawXCursorPosition, mRawYCursorPosition);
720         mRawXCursorPosition = cursor.x;
721         mRawYCursorPosition = cursor.y;
722     }
723 }
724 
725 #ifdef __linux__
readFromParcel(ui::Transform & transform,const Parcel & parcel)726 static status_t readFromParcel(ui::Transform& transform, const Parcel& parcel) {
727     float dsdx, dtdx, tx, dtdy, dsdy, ty;
728     status_t status = parcel.readFloat(&dsdx);
729     status |= parcel.readFloat(&dtdx);
730     status |= parcel.readFloat(&tx);
731     status |= parcel.readFloat(&dtdy);
732     status |= parcel.readFloat(&dsdy);
733     status |= parcel.readFloat(&ty);
734 
735     transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
736     return status;
737 }
738 
writeToParcel(const ui::Transform & transform,Parcel & parcel)739 static status_t writeToParcel(const ui::Transform& transform, Parcel& parcel) {
740     status_t status = parcel.writeFloat(transform.dsdx());
741     status |= parcel.writeFloat(transform.dtdx());
742     status |= parcel.writeFloat(transform.tx());
743     status |= parcel.writeFloat(transform.dtdy());
744     status |= parcel.writeFloat(transform.dsdy());
745     status |= parcel.writeFloat(transform.ty());
746     return status;
747 }
748 
readFromParcel(Parcel * parcel)749 status_t MotionEvent::readFromParcel(Parcel* parcel) {
750     size_t pointerCount = parcel->readInt32();
751     size_t sampleCount = parcel->readInt32();
752     if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
753             sampleCount == 0 || sampleCount > MAX_SAMPLES) {
754         return BAD_VALUE;
755     }
756 
757     mId = parcel->readInt32();
758     mDeviceId = parcel->readInt32();
759     mSource = parcel->readUint32();
760     mDisplayId = parcel->readInt32();
761     std::vector<uint8_t> hmac;
762     status_t result = parcel->readByteVector(&hmac);
763     if (result != OK || hmac.size() != 32) {
764         return BAD_VALUE;
765     }
766     std::move(hmac.begin(), hmac.begin() + hmac.size(), mHmac.begin());
767     mAction = parcel->readInt32();
768     mActionButton = parcel->readInt32();
769     mFlags = parcel->readInt32();
770     mEdgeFlags = parcel->readInt32();
771     mMetaState = parcel->readInt32();
772     mButtonState = parcel->readInt32();
773     mClassification = static_cast<MotionClassification>(parcel->readByte());
774 
775     result = android::readFromParcel(mTransform, *parcel);
776     if (result != OK) {
777         return result;
778     }
779     mXPrecision = parcel->readFloat();
780     mYPrecision = parcel->readFloat();
781     mRawXCursorPosition = parcel->readFloat();
782     mRawYCursorPosition = parcel->readFloat();
783 
784     result = android::readFromParcel(mRawTransform, *parcel);
785     if (result != OK) {
786         return result;
787     }
788     mDownTime = parcel->readInt64();
789 
790     mPointerProperties.clear();
791     mPointerProperties.reserve(pointerCount);
792     mSampleEventTimes.clear();
793     mSampleEventTimes.reserve(sampleCount);
794     mSamplePointerCoords.clear();
795     mSamplePointerCoords.reserve(sampleCount * pointerCount);
796 
797     for (size_t i = 0; i < pointerCount; i++) {
798         mPointerProperties.push_back({});
799         PointerProperties& properties = mPointerProperties.back();
800         properties.id = parcel->readInt32();
801         properties.toolType = static_cast<ToolType>(parcel->readInt32());
802     }
803 
804     while (sampleCount > 0) {
805         sampleCount--;
806         mSampleEventTimes.push_back(parcel->readInt64());
807         for (size_t i = 0; i < pointerCount; i++) {
808             mSamplePointerCoords.push_back({});
809             status_t status = mSamplePointerCoords.back().readFromParcel(parcel);
810             if (status) {
811                 return status;
812             }
813         }
814     }
815     return OK;
816 }
817 
writeToParcel(Parcel * parcel) const818 status_t MotionEvent::writeToParcel(Parcel* parcel) const {
819     size_t pointerCount = mPointerProperties.size();
820     size_t sampleCount = mSampleEventTimes.size();
821 
822     parcel->writeInt32(pointerCount);
823     parcel->writeInt32(sampleCount);
824 
825     parcel->writeInt32(mId);
826     parcel->writeInt32(mDeviceId);
827     parcel->writeUint32(mSource);
828     parcel->writeInt32(mDisplayId);
829     std::vector<uint8_t> hmac(mHmac.begin(), mHmac.end());
830     parcel->writeByteVector(hmac);
831     parcel->writeInt32(mAction);
832     parcel->writeInt32(mActionButton);
833     parcel->writeInt32(mFlags);
834     parcel->writeInt32(mEdgeFlags);
835     parcel->writeInt32(mMetaState);
836     parcel->writeInt32(mButtonState);
837     parcel->writeByte(static_cast<int8_t>(mClassification));
838 
839     status_t result = android::writeToParcel(mTransform, *parcel);
840     if (result != OK) {
841         return result;
842     }
843     parcel->writeFloat(mXPrecision);
844     parcel->writeFloat(mYPrecision);
845     parcel->writeFloat(mRawXCursorPosition);
846     parcel->writeFloat(mRawYCursorPosition);
847 
848     result = android::writeToParcel(mRawTransform, *parcel);
849     if (result != OK) {
850         return result;
851     }
852     parcel->writeInt64(mDownTime);
853 
854     for (size_t i = 0; i < pointerCount; i++) {
855         const PointerProperties& properties = mPointerProperties[i];
856         parcel->writeInt32(properties.id);
857         parcel->writeInt32(static_cast<int32_t>(properties.toolType));
858     }
859 
860     const PointerCoords* pc = mSamplePointerCoords.data();
861     for (size_t h = 0; h < sampleCount; h++) {
862         parcel->writeInt64(mSampleEventTimes[h]);
863         for (size_t i = 0; i < pointerCount; i++) {
864             status_t status = (pc++)->writeToParcel(parcel);
865             if (status) {
866                 return status;
867             }
868         }
869     }
870     return OK;
871 }
872 #endif
873 
isTouchEvent(uint32_t source,int32_t action)874 bool MotionEvent::isTouchEvent(uint32_t source, int32_t action) {
875     if (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER)) {
876         // Specifically excludes HOVER_MOVE and SCROLL.
877         switch (action & AMOTION_EVENT_ACTION_MASK) {
878         case AMOTION_EVENT_ACTION_DOWN:
879         case AMOTION_EVENT_ACTION_MOVE:
880         case AMOTION_EVENT_ACTION_UP:
881         case AMOTION_EVENT_ACTION_POINTER_DOWN:
882         case AMOTION_EVENT_ACTION_POINTER_UP:
883         case AMOTION_EVENT_ACTION_CANCEL:
884         case AMOTION_EVENT_ACTION_OUTSIDE:
885             return true;
886         }
887     }
888     return false;
889 }
890 
getLabel(int32_t axis)891 const char* MotionEvent::getLabel(int32_t axis) {
892     return InputEventLookup::getAxisLabel(axis);
893 }
894 
getAxisFromLabel(const char * label)895 std::optional<int> MotionEvent::getAxisFromLabel(const char* label) {
896     return InputEventLookup::getAxisByLabel(label);
897 }
898 
actionToString(int32_t action)899 std::string MotionEvent::actionToString(int32_t action) {
900     // Convert MotionEvent action to string
901     switch (action & AMOTION_EVENT_ACTION_MASK) {
902         case AMOTION_EVENT_ACTION_DOWN:
903             return "DOWN";
904         case AMOTION_EVENT_ACTION_UP:
905             return "UP";
906         case AMOTION_EVENT_ACTION_MOVE:
907             return "MOVE";
908         case AMOTION_EVENT_ACTION_CANCEL:
909             return "CANCEL";
910         case AMOTION_EVENT_ACTION_OUTSIDE:
911             return "OUTSIDE";
912         case AMOTION_EVENT_ACTION_POINTER_DOWN:
913             return StringPrintf("POINTER_DOWN(%" PRId32 ")", MotionEvent::getActionIndex(action));
914         case AMOTION_EVENT_ACTION_POINTER_UP:
915             return StringPrintf("POINTER_UP(%" PRId32 ")", MotionEvent::getActionIndex(action));
916         case AMOTION_EVENT_ACTION_HOVER_MOVE:
917             return "HOVER_MOVE";
918         case AMOTION_EVENT_ACTION_SCROLL:
919             return "SCROLL";
920         case AMOTION_EVENT_ACTION_HOVER_ENTER:
921             return "HOVER_ENTER";
922         case AMOTION_EVENT_ACTION_HOVER_EXIT:
923             return "HOVER_EXIT";
924         case AMOTION_EVENT_ACTION_BUTTON_PRESS:
925             return "BUTTON_PRESS";
926         case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
927             return "BUTTON_RELEASE";
928     }
929     return android::base::StringPrintf("%" PRId32, action);
930 }
931 
932 // Apply the given transformation to the point without checking whether the entire transform
933 // should be disregarded altogether for the provided source.
calculateTransformedXYUnchecked(uint32_t source,const ui::Transform & transform,const vec2 & xy)934 static inline vec2 calculateTransformedXYUnchecked(uint32_t source, const ui::Transform& transform,
935                                                    const vec2& xy) {
936     return shouldDisregardOffset(source) ? transformWithoutTranslation(transform, xy)
937                                          : roundTransformedCoords(transform.transform(xy));
938 }
939 
calculateTransformedXY(uint32_t source,const ui::Transform & transform,const vec2 & xy)940 vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& transform,
941                                          const vec2& xy) {
942     if (shouldDisregardTransformation(source)) {
943         return xy;
944     }
945     return calculateTransformedXYUnchecked(source, transform, xy);
946 }
947 
948 // Keep in sync with calculateTransformedCoords.
calculateTransformedAxisValue(int32_t axis,uint32_t source,const ui::Transform & transform,const PointerCoords & coords)949 float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
950                                                  const ui::Transform& transform,
951                                                  const PointerCoords& coords) {
952     if (shouldDisregardTransformation(source)) {
953         return coords.getAxisValue(axis);
954     }
955 
956     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
957         const vec2 xy = calculateTransformedXYUnchecked(source, transform, coords.getXYValue());
958         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
959         return xy[axis];
960     }
961 
962     if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
963         const vec2 relativeXy =
964                 transformWithoutTranslation(transform,
965                                             {coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
966                                              coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
967         return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
968     }
969 
970     if (axis == AMOTION_EVENT_AXIS_ORIENTATION) {
971         return transformAngle(transform, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
972     }
973 
974     return coords.getAxisValue(axis);
975 }
976 
977 // Keep in sync with calculateTransformedAxisValue. This is an optimization of
978 // calculateTransformedAxisValue for all PointerCoords axes.
calculateTransformedCoords(uint32_t source,const ui::Transform & transform,const PointerCoords & coords)979 PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
980                                                       const ui::Transform& transform,
981                                                       const PointerCoords& coords) {
982     if (shouldDisregardTransformation(source)) {
983         return coords;
984     }
985     PointerCoords out = coords;
986 
987     const vec2 xy = calculateTransformedXYUnchecked(source, transform, coords.getXYValue());
988     out.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
989     out.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
990 
991     const vec2 relativeXy =
992             transformWithoutTranslation(transform,
993                                         {coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
994                                          coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
995     out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, relativeXy.x);
996     out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, relativeXy.y);
997 
998     out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
999                      transformAngle(transform,
1000                                     coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)));
1001 
1002     return out;
1003 }
1004 
operator <<(std::ostream & out,const MotionEvent & event)1005 std::ostream& operator<<(std::ostream& out, const MotionEvent& event) {
1006     out << "MotionEvent { action=" << MotionEvent::actionToString(event.getAction());
1007     if (event.getActionButton() != 0) {
1008         out << ", actionButton=" << std::to_string(event.getActionButton());
1009     }
1010     const size_t pointerCount = event.getPointerCount();
1011     LOG_ALWAYS_FATAL_IF(pointerCount > MAX_POINTERS, "Too many pointers : pointerCount = %zu",
1012                         pointerCount);
1013     for (size_t i = 0; i < pointerCount; i++) {
1014         out << ", id[" << i << "]=" << event.getPointerId(i);
1015         float x = event.getX(i);
1016         float y = event.getY(i);
1017         if (x != 0 || y != 0) {
1018             out << ", x[" << i << "]=" << x;
1019             out << ", y[" << i << "]=" << y;
1020         }
1021         ToolType toolType = event.getToolType(i);
1022         if (toolType != ToolType::FINGER) {
1023             out << ", toolType[" << i << "]=" << ftl::enum_string(toolType);
1024         }
1025     }
1026     if (event.getButtonState() != 0) {
1027         out << ", buttonState=" << event.getButtonState();
1028     }
1029     if (event.getClassification() != MotionClassification::NONE) {
1030         out << ", classification=" << motionClassificationToString(event.getClassification());
1031     }
1032     if (event.getMetaState() != 0) {
1033         out << ", metaState=" << event.getMetaState();
1034     }
1035     if (event.getEdgeFlags() != 0) {
1036         out << ", edgeFlags=" << event.getEdgeFlags();
1037     }
1038     if (pointerCount != 1) {
1039         out << ", pointerCount=" << pointerCount;
1040     }
1041     if (event.getHistorySize() != 0) {
1042         out << ", historySize=" << event.getHistorySize();
1043     }
1044     out << ", eventTime=" << event.getEventTime();
1045     out << ", downTime=" << event.getDownTime();
1046     out << ", deviceId=" << event.getDeviceId();
1047     out << ", source=" << inputEventSourceToString(event.getSource());
1048     out << ", displayId=" << event.getDisplayId();
1049     out << ", eventId=" << event.getId();
1050     out << "}";
1051     return out;
1052 }
1053 
1054 // --- FocusEvent ---
1055 
initialize(int32_t id,bool hasFocus)1056 void FocusEvent::initialize(int32_t id, bool hasFocus) {
1057     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
1058                            ADISPLAY_ID_NONE, INVALID_HMAC);
1059     mHasFocus = hasFocus;
1060 }
1061 
initialize(const FocusEvent & from)1062 void FocusEvent::initialize(const FocusEvent& from) {
1063     InputEvent::initialize(from);
1064     mHasFocus = from.mHasFocus;
1065 }
1066 
1067 // --- CaptureEvent ---
1068 
initialize(int32_t id,bool pointerCaptureEnabled)1069 void CaptureEvent::initialize(int32_t id, bool pointerCaptureEnabled) {
1070     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
1071                            ADISPLAY_ID_NONE, INVALID_HMAC);
1072     mPointerCaptureEnabled = pointerCaptureEnabled;
1073 }
1074 
initialize(const CaptureEvent & from)1075 void CaptureEvent::initialize(const CaptureEvent& from) {
1076     InputEvent::initialize(from);
1077     mPointerCaptureEnabled = from.mPointerCaptureEnabled;
1078 }
1079 
1080 // --- DragEvent ---
1081 
initialize(int32_t id,float x,float y,bool isExiting)1082 void DragEvent::initialize(int32_t id, float x, float y, bool isExiting) {
1083     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
1084                            ADISPLAY_ID_NONE, INVALID_HMAC);
1085     mIsExiting = isExiting;
1086     mX = x;
1087     mY = y;
1088 }
1089 
initialize(const DragEvent & from)1090 void DragEvent::initialize(const DragEvent& from) {
1091     InputEvent::initialize(from);
1092     mIsExiting = from.mIsExiting;
1093     mX = from.mX;
1094     mY = from.mY;
1095 }
1096 
1097 // --- TouchModeEvent ---
1098 
initialize(int32_t id,bool isInTouchMode)1099 void TouchModeEvent::initialize(int32_t id, bool isInTouchMode) {
1100     InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
1101                            ADISPLAY_ID_NONE, INVALID_HMAC);
1102     mIsInTouchMode = isInTouchMode;
1103 }
1104 
initialize(const TouchModeEvent & from)1105 void TouchModeEvent::initialize(const TouchModeEvent& from) {
1106     InputEvent::initialize(from);
1107     mIsInTouchMode = from.mIsInTouchMode;
1108 }
1109 
1110 // --- PooledInputEventFactory ---
1111 
PooledInputEventFactory(size_t maxPoolSize)1112 PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
1113         mMaxPoolSize(maxPoolSize) {
1114 }
1115 
~PooledInputEventFactory()1116 PooledInputEventFactory::~PooledInputEventFactory() {
1117 }
1118 
createKeyEvent()1119 KeyEvent* PooledInputEventFactory::createKeyEvent() {
1120     if (mKeyEventPool.empty()) {
1121         return new KeyEvent();
1122     }
1123     KeyEvent* event = mKeyEventPool.front().release();
1124     mKeyEventPool.pop();
1125     return event;
1126 }
1127 
createMotionEvent()1128 MotionEvent* PooledInputEventFactory::createMotionEvent() {
1129     if (mMotionEventPool.empty()) {
1130         return new MotionEvent();
1131     }
1132     MotionEvent* event = mMotionEventPool.front().release();
1133     mMotionEventPool.pop();
1134     return event;
1135 }
1136 
createFocusEvent()1137 FocusEvent* PooledInputEventFactory::createFocusEvent() {
1138     if (mFocusEventPool.empty()) {
1139         return new FocusEvent();
1140     }
1141     FocusEvent* event = mFocusEventPool.front().release();
1142     mFocusEventPool.pop();
1143     return event;
1144 }
1145 
createCaptureEvent()1146 CaptureEvent* PooledInputEventFactory::createCaptureEvent() {
1147     if (mCaptureEventPool.empty()) {
1148         return new CaptureEvent();
1149     }
1150     CaptureEvent* event = mCaptureEventPool.front().release();
1151     mCaptureEventPool.pop();
1152     return event;
1153 }
1154 
createDragEvent()1155 DragEvent* PooledInputEventFactory::createDragEvent() {
1156     if (mDragEventPool.empty()) {
1157         return new DragEvent();
1158     }
1159     DragEvent* event = mDragEventPool.front().release();
1160     mDragEventPool.pop();
1161     return event;
1162 }
1163 
createTouchModeEvent()1164 TouchModeEvent* PooledInputEventFactory::createTouchModeEvent() {
1165     if (mTouchModeEventPool.empty()) {
1166         return new TouchModeEvent();
1167     }
1168     TouchModeEvent* event = mTouchModeEventPool.front().release();
1169     mTouchModeEventPool.pop();
1170     return event;
1171 }
1172 
recycle(InputEvent * event)1173 void PooledInputEventFactory::recycle(InputEvent* event) {
1174     switch (event->getType()) {
1175         case InputEventType::KEY: {
1176             if (mKeyEventPool.size() < mMaxPoolSize) {
1177                 mKeyEventPool.push(std::unique_ptr<KeyEvent>(static_cast<KeyEvent*>(event)));
1178                 return;
1179             }
1180             break;
1181         }
1182         case InputEventType::MOTION: {
1183             if (mMotionEventPool.size() < mMaxPoolSize) {
1184                 mMotionEventPool.push(
1185                         std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event)));
1186                 return;
1187             }
1188             break;
1189         }
1190         case InputEventType::FOCUS: {
1191             if (mFocusEventPool.size() < mMaxPoolSize) {
1192                 mFocusEventPool.push(std::unique_ptr<FocusEvent>(static_cast<FocusEvent*>(event)));
1193                 return;
1194             }
1195             break;
1196         }
1197         case InputEventType::CAPTURE: {
1198             if (mCaptureEventPool.size() < mMaxPoolSize) {
1199                 mCaptureEventPool.push(
1200                         std::unique_ptr<CaptureEvent>(static_cast<CaptureEvent*>(event)));
1201                 return;
1202             }
1203             break;
1204         }
1205         case InputEventType::DRAG: {
1206             if (mDragEventPool.size() < mMaxPoolSize) {
1207                 mDragEventPool.push(std::unique_ptr<DragEvent>(static_cast<DragEvent*>(event)));
1208                 return;
1209             }
1210             break;
1211         }
1212         case InputEventType::TOUCH_MODE: {
1213             if (mTouchModeEventPool.size() < mMaxPoolSize) {
1214                 mTouchModeEventPool.push(
1215                         std::unique_ptr<TouchModeEvent>(static_cast<TouchModeEvent*>(event)));
1216                 return;
1217             }
1218             break;
1219         }
1220     }
1221     delete event;
1222 }
1223 
1224 } // namespace android
1225