summaryrefslogtreecommitdiff
path: root/libs/input/Input.cpp
diff options
context:
space:
mode:
author Xin Li <delphij@google.com> 2020-09-10 17:22:18 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2020-09-10 17:22:18 +0000
commitcdb6b16dec3a541b455be99d075004cb2f0a0cd7 (patch)
treef7110d50445c67a337105034b1f2db3946a88fef /libs/input/Input.cpp
parent171cac1b603e4bb83412eb596d05a500af5d7a76 (diff)
parentac07d0f5ab16bb9e8bbbabb589d1c7d36817baa9 (diff)
Merge "Merge Android R"
Diffstat (limited to 'libs/input/Input.cpp')
-rw-r--r--libs/input/Input.cpp306
1 files changed, 235 insertions, 71 deletions
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 9fd25f9cb7..31aa685391 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -17,14 +17,17 @@
#define LOG_TAG "Input"
//#define LOG_NDEBUG 0
-#include <math.h>
+#include <cutils/compiler.h>
#include <limits.h>
+#include <string.h>
#include <input/Input.h>
+#include <input/InputDevice.h>
#include <input/InputEventLabels.h>
#ifdef __ANDROID__
#include <binder/Parcel.h>
+#include <sys/random.h>
#endif
namespace android {
@@ -40,18 +43,93 @@ const char* motionClassificationToString(MotionClassification classification) {
}
}
+// --- IdGenerator ---
+IdGenerator::IdGenerator(Source source) : mSource(source) {}
+
+int32_t IdGenerator::nextId() const {
+ constexpr uint32_t SEQUENCE_NUMBER_MASK = ~SOURCE_MASK;
+ int32_t id = 0;
+
+// Avoid building against syscall getrandom(2) on host, which will fail build on Mac. Host doesn't
+// use sequence number so just always return mSource.
+#ifdef __ANDROID__
+ constexpr size_t BUF_LEN = sizeof(id);
+ size_t totalBytes = 0;
+ while (totalBytes < BUF_LEN) {
+ ssize_t bytes = TEMP_FAILURE_RETRY(getrandom(&id, BUF_LEN, GRND_NONBLOCK));
+ if (CC_UNLIKELY(bytes < 0)) {
+ ALOGW("Failed to fill in random number for sequence number: %s.", strerror(errno));
+ id = 0;
+ break;
+ }
+ totalBytes += bytes;
+ }
+#endif // __ANDROID__
+
+ return (id & SEQUENCE_NUMBER_MASK) | static_cast<int32_t>(mSource);
+}
+
// --- InputEvent ---
-void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
+const char* inputEventTypeToString(int32_t type) {
+ switch (type) {
+ case AINPUT_EVENT_TYPE_KEY: {
+ return "KEY";
+ }
+ case AINPUT_EVENT_TYPE_MOTION: {
+ return "MOTION";
+ }
+ case AINPUT_EVENT_TYPE_FOCUS: {
+ return "FOCUS";
+ }
+ }
+ return "UNKNOWN";
+}
+
+VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event) {
+ return {{VerifiedInputEvent::Type::KEY, event.getDeviceId(), event.getEventTime(),
+ event.getSource(), event.getDisplayId()},
+ event.getAction(),
+ event.getDownTime(),
+ event.getFlags() & VERIFIED_KEY_EVENT_FLAGS,
+ event.getKeyCode(),
+ event.getScanCode(),
+ event.getMetaState(),
+ event.getRepeatCount()};
+}
+
+VerifiedMotionEvent verifiedMotionEventFromMotionEvent(const MotionEvent& event) {
+ return {{VerifiedInputEvent::Type::MOTION, event.getDeviceId(), event.getEventTime(),
+ event.getSource(), event.getDisplayId()},
+ event.getRawX(0),
+ event.getRawY(0),
+ event.getActionMasked(),
+ event.getDownTime(),
+ event.getFlags() & VERIFIED_MOTION_EVENT_FLAGS,
+ event.getMetaState(),
+ event.getButtonState()};
+}
+
+void InputEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
+ std::array<uint8_t, 32> hmac) {
+ mId = id;
mDeviceId = deviceId;
mSource = source;
mDisplayId = displayId;
+ mHmac = hmac;
}
void InputEvent::initialize(const InputEvent& from) {
+ mId = from.mId;
mDeviceId = from.mDeviceId;
mSource = from.mSource;
mDisplayId = from.mDisplayId;
+ mHmac = from.mHmac;
+}
+
+int32_t InputEvent::nextId() {
+ static IdGenerator idGen(IdGenerator::Source::OTHER);
+ return idGen.nextId();
}
// --- KeyEvent ---
@@ -64,19 +142,11 @@ int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
return getKeyCodeByLabel(label);
}
-void KeyEvent::initialize(
- int32_t deviceId,
- int32_t source,
- int32_t displayId,
- int32_t action,
- int32_t flags,
- int32_t keyCode,
- int32_t scanCode,
- int32_t metaState,
- int32_t repeatCount,
- nsecs_t downTime,
- nsecs_t eventTime) {
- InputEvent::initialize(deviceId, source, displayId);
+void KeyEvent::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) {
+ InputEvent::initialize(id, deviceId, source, displayId, hmac);
mAction = action;
mFlags = flags;
mKeyCode = keyCode;
@@ -99,6 +169,18 @@ void KeyEvent::initialize(const KeyEvent& from) {
mEventTime = from.mEventTime;
}
+const char* KeyEvent::actionToString(int32_t action) {
+ // Convert KeyEvent action to string
+ switch (action) {
+ case AKEY_EVENT_ACTION_DOWN:
+ return "DOWN";
+ case AKEY_EVENT_ACTION_UP:
+ return "UP";
+ case AKEY_EVENT_ACTION_MULTIPLE:
+ return "MULTIPLE";
+ }
+ return "UNKNOWN";
+}
// --- PointerCoords ---
@@ -235,27 +317,16 @@ void PointerProperties::copyFrom(const PointerProperties& other) {
// --- MotionEvent ---
-void MotionEvent::initialize(
- int32_t deviceId,
- int32_t source,
- int32_t displayId,
- int32_t action,
- int32_t actionButton,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- MotionClassification classification,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- size_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords) {
- InputEvent::initialize(deviceId, source, displayId);
+void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
+ std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
+ int32_t flags, int32_t edgeFlags, int32_t metaState,
+ int32_t buttonState, MotionClassification classification, float xScale,
+ float yScale, float xOffset, float yOffset, float xPrecision,
+ float yPrecision, float rawXCursorPosition, float rawYCursorPosition,
+ nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
+ const PointerProperties* pointerProperties,
+ const PointerCoords* pointerCoords) {
+ InputEvent::initialize(id, deviceId, source, displayId, hmac);
mAction = action;
mActionButton = actionButton;
mFlags = flags;
@@ -263,10 +334,14 @@ void MotionEvent::initialize(
mMetaState = metaState;
mButtonState = buttonState;
mClassification = classification;
+ mXScale = xScale;
+ mYScale = yScale;
mXOffset = xOffset;
mYOffset = yOffset;
mXPrecision = xPrecision;
mYPrecision = yPrecision;
+ mRawXCursorPosition = rawXCursorPosition;
+ mRawYCursorPosition = rawYCursorPosition;
mDownTime = downTime;
mPointerProperties.clear();
mPointerProperties.appendArray(pointerProperties, pointerCount);
@@ -276,7 +351,8 @@ void MotionEvent::initialize(
}
void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
- InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId);
+ InputEvent::initialize(other->mId, other->mDeviceId, other->mSource, other->mDisplayId,
+ other->mHmac);
mAction = other->mAction;
mActionButton = other->mActionButton;
mFlags = other->mFlags;
@@ -284,10 +360,14 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
mMetaState = other->mMetaState;
mButtonState = other->mButtonState;
mClassification = other->mClassification;
+ mXScale = other->mXScale;
+ mYScale = other->mYScale;
mXOffset = other->mXOffset;
mYOffset = other->mYOffset;
mXPrecision = other->mXPrecision;
mYPrecision = other->mYPrecision;
+ mRawXCursorPosition = other->mRawXCursorPosition;
+ mRawYCursorPosition = other->mRawYCursorPosition;
mDownTime = other->mDownTime;
mPointerProperties = other->mPointerProperties;
@@ -312,6 +392,21 @@ void MotionEvent::addSample(
mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
}
+float MotionEvent::getXCursorPosition() const {
+ const float rawX = getRawXCursorPosition();
+ return rawX * mXScale + mXOffset;
+}
+
+float MotionEvent::getYCursorPosition() const {
+ const float rawY = getRawYCursorPosition();
+ return rawY * mYScale + mYOffset;
+}
+
+void MotionEvent::setCursorPosition(float x, float y) {
+ mRawXCursorPosition = (x - mXOffset) / mXScale;
+ mRawYCursorPosition = (y - mYOffset) / mYScale;
+}
+
const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
}
@@ -324,9 +419,9 @@ float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
switch (axis) {
case AMOTION_EVENT_AXIS_X:
- return value + mXOffset;
+ return value * mXScale + mXOffset;
case AMOTION_EVENT_AXIS_Y:
- return value + mYOffset;
+ return value * mYScale + mYOffset;
}
return value;
}
@@ -346,9 +441,9 @@ float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
switch (axis) {
case AMOTION_EVENT_AXIS_X:
- return value + mXOffset;
+ return value * mXScale + mXOffset;
case AMOTION_EVENT_AXIS_Y:
- return value + mYOffset;
+ return value * mYScale + mYOffset;
}
return value;
}
@@ -420,26 +515,35 @@ void MotionEvent::transform(const float matrix[9]) {
float oldXOffset = mXOffset;
float oldYOffset = mYOffset;
float newX, newY;
- float rawX = getRawX(0);
- float rawY = getRawY(0);
- transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
- mXOffset = newX - rawX;
- mYOffset = newY - rawY;
+ float scaledRawX = getRawX(0) * mXScale;
+ float scaledRawY = getRawY(0) * mYScale;
+ transformPoint(matrix, scaledRawX + oldXOffset, scaledRawY + oldYOffset, &newX, &newY);
+ mXOffset = newX - scaledRawX;
+ mYOffset = newY - scaledRawY;
// Determine how the origin is transformed by the matrix so that we
// can transform orientation vectors.
float originX, originY;
transformPoint(matrix, 0, 0, &originX, &originY);
+ // Apply the transformation to cursor position.
+ if (isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) {
+ float x = mRawXCursorPosition * mXScale + oldXOffset;
+ float y = mRawYCursorPosition * mYScale + oldYOffset;
+ transformPoint(matrix, x, y, &x, &y);
+ mRawXCursorPosition = (x - mXOffset) / mXScale;
+ mRawYCursorPosition = (y - mYOffset) / mYScale;
+ }
+
// Apply the transformation to all samples.
size_t numSamples = mSamplePointerCoords.size();
for (size_t i = 0; i < numSamples; i++) {
PointerCoords& c = mSamplePointerCoords.editItemAt(i);
- float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
- float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
+ float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) * mXScale + oldXOffset;
+ float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) * mYScale + oldYOffset;
transformPoint(matrix, x, y, &x, &y);
- c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
- c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
+ c.setAxisValue(AMOTION_EVENT_AXIS_X, (x - mXOffset) / mXScale);
+ c.setAxisValue(AMOTION_EVENT_AXIS_Y, (y - mYOffset) / mYScale);
float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
@@ -456,9 +560,16 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) {
return BAD_VALUE;
}
+ mId = parcel->readInt32();
mDeviceId = parcel->readInt32();
- mSource = parcel->readInt32();
+ mSource = parcel->readUint32();
mDisplayId = parcel->readInt32();
+ std::vector<uint8_t> hmac;
+ status_t result = parcel->readByteVector(&hmac);
+ if (result != OK || hmac.size() != 32) {
+ return BAD_VALUE;
+ }
+ std::move(hmac.begin(), hmac.begin() + hmac.size(), mHmac.begin());
mAction = parcel->readInt32();
mActionButton = parcel->readInt32();
mFlags = parcel->readInt32();
@@ -466,10 +577,14 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) {
mMetaState = parcel->readInt32();
mButtonState = parcel->readInt32();
mClassification = static_cast<MotionClassification>(parcel->readByte());
+ mXScale = parcel->readFloat();
+ mYScale = parcel->readFloat();
mXOffset = parcel->readFloat();
mYOffset = parcel->readFloat();
mXPrecision = parcel->readFloat();
mYPrecision = parcel->readFloat();
+ mRawXCursorPosition = parcel->readFloat();
+ mRawYCursorPosition = parcel->readFloat();
mDownTime = parcel->readInt64();
mPointerProperties.clear();
@@ -507,9 +622,12 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {
parcel->writeInt32(pointerCount);
parcel->writeInt32(sampleCount);
+ parcel->writeInt32(mId);
parcel->writeInt32(mDeviceId);
- parcel->writeInt32(mSource);
+ parcel->writeUint32(mSource);
parcel->writeInt32(mDisplayId);
+ std::vector<uint8_t> hmac(mHmac.begin(), mHmac.end());
+ parcel->writeByteVector(hmac);
parcel->writeInt32(mAction);
parcel->writeInt32(mActionButton);
parcel->writeInt32(mFlags);
@@ -517,10 +635,14 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {
parcel->writeInt32(mMetaState);
parcel->writeInt32(mButtonState);
parcel->writeByte(static_cast<int8_t>(mClassification));
+ parcel->writeFloat(mXScale);
+ parcel->writeFloat(mYScale);
parcel->writeFloat(mXOffset);
parcel->writeFloat(mYOffset);
parcel->writeFloat(mXPrecision);
parcel->writeFloat(mYPrecision);
+ parcel->writeFloat(mRawXCursorPosition);
+ parcel->writeFloat(mRawYCursorPosition);
parcel->writeInt64(mDownTime);
for (size_t i = 0; i < pointerCount; i++) {
@@ -543,7 +665,7 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {
}
#endif
-bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
+bool MotionEvent::isTouchEvent(uint32_t source, int32_t action) {
if (source & AINPUT_SOURCE_CLASS_POINTER) {
// Specifically excludes HOVER_MOVE and SCROLL.
switch (action & AMOTION_EVENT_ACTION_MASK) {
@@ -568,6 +690,39 @@ int32_t MotionEvent::getAxisFromLabel(const char* label) {
return getAxisByLabel(label);
}
+const char* MotionEvent::actionToString(int32_t action) {
+ // Convert MotionEvent action to string
+ switch (action & AMOTION_EVENT_ACTION_MASK) {
+ case AMOTION_EVENT_ACTION_DOWN:
+ return "DOWN";
+ case AMOTION_EVENT_ACTION_MOVE:
+ return "MOVE";
+ case AMOTION_EVENT_ACTION_UP:
+ return "UP";
+ case AMOTION_EVENT_ACTION_CANCEL:
+ return "CANCEL";
+ case AMOTION_EVENT_ACTION_POINTER_DOWN:
+ return "POINTER_DOWN";
+ case AMOTION_EVENT_ACTION_POINTER_UP:
+ return "POINTER_UP";
+ }
+ return "UNKNOWN";
+}
+
+// --- FocusEvent ---
+
+void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
+ InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
+ ADISPLAY_ID_NONE, INVALID_HMAC);
+ mHasFocus = hasFocus;
+ mInTouchMode = inTouchMode;
+}
+
+void FocusEvent::initialize(const FocusEvent& from) {
+ InputEvent::initialize(from);
+ mHasFocus = from.mHasFocus;
+ mInTouchMode = from.mInTouchMode;
+}
// --- PooledInputEventFactory ---
@@ -576,43 +731,52 @@ PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
}
PooledInputEventFactory::~PooledInputEventFactory() {
- for (size_t i = 0; i < mKeyEventPool.size(); i++) {
- delete mKeyEventPool.itemAt(i);
- }
- for (size_t i = 0; i < mMotionEventPool.size(); i++) {
- delete mMotionEventPool.itemAt(i);
- }
}
KeyEvent* PooledInputEventFactory::createKeyEvent() {
- if (!mKeyEventPool.isEmpty()) {
- KeyEvent* event = mKeyEventPool.top();
- mKeyEventPool.pop();
- return event;
+ if (mKeyEventPool.empty()) {
+ return new KeyEvent();
}
- return new KeyEvent();
+ KeyEvent* event = mKeyEventPool.front().release();
+ mKeyEventPool.pop();
+ return event;
}
MotionEvent* PooledInputEventFactory::createMotionEvent() {
- if (!mMotionEventPool.isEmpty()) {
- MotionEvent* event = mMotionEventPool.top();
- mMotionEventPool.pop();
- return event;
+ if (mMotionEventPool.empty()) {
+ return new MotionEvent();
}
- return new MotionEvent();
+ MotionEvent* event = mMotionEventPool.front().release();
+ mMotionEventPool.pop();
+ return event;
+}
+
+FocusEvent* PooledInputEventFactory::createFocusEvent() {
+ if (mFocusEventPool.empty()) {
+ return new FocusEvent();
+ }
+ FocusEvent* event = mFocusEventPool.front().release();
+ mFocusEventPool.pop();
+ return event;
}
void PooledInputEventFactory::recycle(InputEvent* event) {
switch (event->getType()) {
case AINPUT_EVENT_TYPE_KEY:
if (mKeyEventPool.size() < mMaxPoolSize) {
- mKeyEventPool.push(static_cast<KeyEvent*>(event));
+ mKeyEventPool.push(std::unique_ptr<KeyEvent>(static_cast<KeyEvent*>(event)));
return;
}
break;
case AINPUT_EVENT_TYPE_MOTION:
if (mMotionEventPool.size() < mMaxPoolSize) {
- mMotionEventPool.push(static_cast<MotionEvent*>(event));
+ mMotionEventPool.push(std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event)));
+ return;
+ }
+ break;
+ case AINPUT_EVENT_TYPE_FOCUS:
+ if (mFocusEventPool.size() < mMaxPoolSize) {
+ mFocusEventPool.push(std::unique_ptr<FocusEvent>(static_cast<FocusEvent*>(event)));
return;
}
break;