diff options
| -rw-r--r-- | include/input/Input.h | 5 | ||||
| -rw-r--r-- | include/input/InputTransport.h | 4 | ||||
| -rw-r--r-- | libs/input/Input.cpp | 11 | ||||
| -rw-r--r-- | libs/input/InputTransport.cpp | 12 | ||||
| -rw-r--r-- | libs/input/tests/InputChannel_test.cpp | 34 | ||||
| -rw-r--r-- | libs/input/tests/InputEvent_test.cpp | 34 | ||||
| -rw-r--r-- | libs/input/tests/InputPublisherAndConsumer_test.cpp | 15 | ||||
| -rw-r--r-- | libs/input/tests/StructLayout_test.cpp | 3 | ||||
| -rw-r--r-- | services/inputflinger/InputDispatcher.cpp | 31 | ||||
| -rw-r--r-- | services/inputflinger/InputDispatcher.h | 6 |
10 files changed, 123 insertions, 32 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index 2c4a511e82..805957a5ca 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -241,6 +241,11 @@ enum class MotionClassification : uint8_t { DEEP_PRESS = 2, }; +/** + * String representation of MotionClassification + */ +const char* motionClassificationToString(MotionClassification classification); + /* * Pointer coordinate data. */ diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index dddbfb04da..63606e5911 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -105,8 +105,9 @@ struct InputMessage { int32_t flags; int32_t metaState; int32_t buttonState; + MotionClassification classification; // base type: uint8_t + uint8_t empty2[3]; int32_t edgeFlags; - uint32_t empty2; nsecs_t downTime __attribute__((aligned(8))); float xOffset; float yOffset; @@ -271,6 +272,7 @@ public: int32_t edgeFlags, int32_t metaState, int32_t buttonState, + MotionClassification classification, float xOffset, float yOffset, float xPrecision, diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index db86c8ea30..9fd25f9cb7 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -29,6 +29,17 @@ namespace android { +const char* motionClassificationToString(MotionClassification classification) { + switch (classification) { + case MotionClassification::NONE: + return "NONE"; + case MotionClassification::AMBIGUOUS_GESTURE: + return "AMBIGUOUS_GESTURE"; + case MotionClassification::DEEP_PRESS: + return "DEEP_PRESS"; + } +} + // --- InputEvent --- void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) { diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 0ddee44c9c..0f7a1f04e5 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -157,6 +157,8 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const { msg->body.motion.metaState = body.motion.metaState; // int32_t buttonState msg->body.motion.buttonState = body.motion.buttonState; + // MotionClassification classification + msg->body.motion.classification = body.motion.classification; // int32_t edgeFlags msg->body.motion.edgeFlags = body.motion.edgeFlags; // nsecs_t downTime @@ -448,6 +450,7 @@ status_t InputPublisher::publishMotionEvent( int32_t edgeFlags, int32_t metaState, int32_t buttonState, + MotionClassification classification, float xOffset, float yOffset, float xPrecision, @@ -461,13 +464,13 @@ status_t InputPublisher::publishMotionEvent( ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, " "displayId=%" PRId32 ", " "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, " - "metaState=0x%x, buttonState=0x%x, xOffset=%f, yOffset=%f, " + "metaState=0x%x, buttonState=0x%x, classification=%s, xOffset=%f, yOffset=%f, " "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", " "pointerCount=%" PRIu32, mChannel->getName().c_str(), seq, deviceId, source, displayId, action, actionButton, flags, edgeFlags, metaState, - buttonState, xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, - pointerCount); + buttonState, motionClassificationToString(classification), + xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount); #endif if (!seq) { @@ -493,6 +496,7 @@ status_t InputPublisher::publishMotionEvent( msg.body.motion.edgeFlags = edgeFlags; msg.body.motion.metaState = metaState; msg.body.motion.buttonState = buttonState; + msg.body.motion.classification = classification; msg.body.motion.xOffset = xOffset; msg.body.motion.yOffset = yOffset; msg.body.motion.xPrecision = xPrecision; @@ -1112,7 +1116,7 @@ void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage msg->body.motion.edgeFlags, msg->body.motion.metaState, msg->body.motion.buttonState, - MotionClassification::NONE, + msg->body.motion.classification, msg->body.motion.xOffset, msg->body.motion.yOffset, msg->body.motion.xPrecision, diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp index 96c165cac2..f1675c0d36 100644 --- a/libs/input/tests/InputChannel_test.cpp +++ b/libs/input/tests/InputChannel_test.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include <array> + #include "TestHelpers.h" #include <unistd.h> @@ -155,5 +157,37 @@ TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) { << "sendMessage should have returned DEAD_OBJECT"; } +TEST_F(InputChannelTest, SendAndReceive_MotionClassification) { + sp<InputChannel> serverChannel, clientChannel; + status_t result = InputChannel::openInputChannelPair("channel name", + serverChannel, clientChannel); + ASSERT_EQ(OK, result) + << "should have successfully opened a channel pair"; + + std::array<MotionClassification, 3> classifications = { + MotionClassification::NONE, + MotionClassification::AMBIGUOUS_GESTURE, + MotionClassification::DEEP_PRESS, + }; + + InputMessage serverMsg = {}, clientMsg; + serverMsg.header.type = InputMessage::TYPE_MOTION; + serverMsg.body.motion.seq = 1; + serverMsg.body.motion.pointerCount = 1; + + for (MotionClassification classification : classifications) { + // Send and receive a message with classification + serverMsg.body.motion.classification = classification; + EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg)) + << "server channel should be able to send message to client channel"; + + EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg)) + << "client channel should be able to receive message from server channel"; + EXPECT_EQ(serverMsg.header.type, clientMsg.header.type); + EXPECT_EQ(classification, clientMsg.body.motion.classification) << + "Expected to receive " << motionClassificationToString(classification); + } +} + } // namespace android diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp index e4c1514889..2b75c82bb1 100644 --- a/libs/input/tests/InputEvent_test.cpp +++ b/libs/input/tests/InputEvent_test.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <array> #include <math.h> #include <binder/Parcel.h> @@ -25,11 +26,7 @@ namespace android { // Default display id. static constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT; -class BaseTest : public testing::Test { -protected: - virtual void SetUp() { } - virtual void TearDown() { } -}; +class BaseTest : public testing::Test { }; // --- PointerCoordsTest --- @@ -316,6 +313,7 @@ void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) { ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags()); ASSERT_EQ(AMETA_ALT_ON, event->getMetaState()); ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState()); + ASSERT_EQ(MotionClassification::NONE, event->getClassification()); ASSERT_EQ(X_OFFSET, event->getXOffset()); ASSERT_EQ(Y_OFFSET, event->getYOffset()); ASSERT_EQ(2.0f, event->getXPrecision()); @@ -609,4 +607,30 @@ TEST_F(MotionEventTest, Transform) { ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001); } +TEST_F(MotionEventTest, Initialize_SetsClassification) { + std::array<MotionClassification, 3> classifications = { + MotionClassification::NONE, + MotionClassification::AMBIGUOUS_GESTURE, + MotionClassification::DEEP_PRESS, + }; + + MotionEvent event; + constexpr size_t pointerCount = 1; + PointerProperties pointerProperties[pointerCount]; + PointerCoords pointerCoords[pointerCount]; + for (size_t i = 0; i < pointerCount; i++) { + pointerProperties[i].clear(); + pointerProperties[i].id = i; + pointerCoords[i].clear(); + } + + for (MotionClassification classification : classifications) { + event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, + AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, + classification, 0, 0, 0, 0, 0 /*downTime*/, 0 /*eventTime*/, + pointerCount, pointerProperties, pointerCoords); + ASSERT_EQ(classification, event.getClassification()); + } +} + } // namespace android diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp index 0788c89b2a..f2cd1be33f 100644 --- a/libs/input/tests/InputPublisherAndConsumer_test.cpp +++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp @@ -141,6 +141,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP; constexpr int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON; constexpr int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY; + constexpr MotionClassification classification = MotionClassification::AMBIGUOUS_GESTURE; constexpr float xOffset = -10; constexpr float yOffset = -20; constexpr float xPrecision = 0.25; @@ -168,8 +169,8 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { } status = mPublisher->publishMotionEvent(seq, deviceId, source, displayId, action, actionButton, - flags, edgeFlags, metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision, - downTime, eventTime, pointerCount, + flags, edgeFlags, metaState, buttonState, classification, + xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount, pointerProperties, pointerCoords); ASSERT_EQ(OK, status) << "publisher publishMotionEvent should return OK"; @@ -195,6 +196,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags()); EXPECT_EQ(metaState, motionEvent->getMetaState()); EXPECT_EQ(buttonState, motionEvent->getButtonState()); + EXPECT_EQ(classification, motionEvent->getClassification()); EXPECT_EQ(xPrecision, motionEvent->getXPrecision()); EXPECT_EQ(yPrecision, motionEvent->getYPrecision()); EXPECT_EQ(downTime, motionEvent->getDownTime()); @@ -264,7 +266,8 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenSequenceNumberIsZer pointerCoords[i].clear(); } - status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + MotionClassification::NONE, 0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords); ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE"; @@ -276,7 +279,8 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessTha PointerProperties pointerProperties[pointerCount]; PointerCoords pointerCoords[pointerCount]; - status = mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + status = mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + MotionClassification::NONE, 0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords); ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE"; @@ -293,7 +297,8 @@ TEST_F(InputPublisherAndConsumerTest, pointerCoords[i].clear(); } - status = mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + status = mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + MotionClassification::NONE, 0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords); ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE"; diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp index 12a67828ac..62023fb328 100644 --- a/libs/input/tests/StructLayout_test.cpp +++ b/libs/input/tests/StructLayout_test.cpp @@ -57,7 +57,8 @@ void TestInputMessageAlignment() { CHECK_OFFSET(InputMessage::Body::Motion, flags, 36); CHECK_OFFSET(InputMessage::Body::Motion, metaState, 40); CHECK_OFFSET(InputMessage::Body::Motion, buttonState, 44); - CHECK_OFFSET(InputMessage::Body::Motion, edgeFlags, 48); + CHECK_OFFSET(InputMessage::Body::Motion, classification, 48); + CHECK_OFFSET(InputMessage::Body::Motion, edgeFlags, 52); CHECK_OFFSET(InputMessage::Body::Motion, downTime, 56); CHECK_OFFSET(InputMessage::Body::Motion, xOffset, 64); CHECK_OFFSET(InputMessage::Body::Motion, yOffset, 68); diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index 9af189ae2b..9d92435323 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -2155,7 +2155,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, motionEntry->deviceId, motionEntry->source, motionEntry->displayId, dispatchEntry->resolvedAction, motionEntry->actionButton, dispatchEntry->resolvedFlags, motionEntry->edgeFlags, - motionEntry->metaState, motionEntry->buttonState, + motionEntry->metaState, motionEntry->buttonState, motionEntry->classification, xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision, motionEntry->downTime, motionEntry->eventTime, motionEntry->pointerCount, motionEntry->pointerProperties, @@ -2491,6 +2491,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet originalMotionEntry->flags, originalMotionEntry->metaState, originalMotionEntry->buttonState, + originalMotionEntry->classification, originalMotionEntry->edgeFlags, originalMotionEntry->xPrecision, originalMotionEntry->yPrecision, @@ -2707,7 +2708,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { MotionEntry* newEntry = new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source, args->displayId, policyFlags, args->action, args->actionButton, args->flags, - args->metaState, args->buttonState, + args->metaState, args->buttonState, args->classification, args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime, args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0); @@ -2845,7 +2846,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, policyFlags, action, actionButton, motionEvent->getFlags(), motionEvent->getMetaState(), motionEvent->getButtonState(), - motionEvent->getEdgeFlags(), + motionEvent->getClassification(), motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), uint32_t(pointerCount), pointerProperties, samplePointerCoords, @@ -2860,7 +2861,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, motionEvent->getDisplayId(), policyFlags, action, actionButton, motionEvent->getFlags(), motionEvent->getMetaState(), motionEvent->getButtonState(), - motionEvent->getEdgeFlags(), + motionEvent->getClassification(), motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), uint32_t(pointerCount), pointerProperties, samplePointerCoords, @@ -4404,8 +4405,8 @@ void InputDispatcher::KeyEntry::recycle() { InputDispatcher::MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton, - int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags, - float xPrecision, float yPrecision, nsecs_t downTime, + int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification, + int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, float xOffset, float yOffset) : @@ -4413,7 +4414,8 @@ InputDispatcher::MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTim eventTime(eventTime), deviceId(deviceId), source(source), displayId(displayId), action(action), actionButton(actionButton), flags(flags), metaState(metaState), buttonState(buttonState), - edgeFlags(edgeFlags), xPrecision(xPrecision), yPrecision(yPrecision), + classification(classification), edgeFlags(edgeFlags), + xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime), pointerCount(pointerCount) { for (uint32_t i = 0; i < pointerCount; i++) { this->pointerProperties[i].copyFrom(pointerProperties[i]); @@ -4430,9 +4432,10 @@ InputDispatcher::MotionEntry::~MotionEntry() { void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const { msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, " - "edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, pointers=[", + "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, pointers=[", deviceId, source, displayId, motionActionToString(action).c_str(), actionButton, flags, - metaState, buttonState, edgeFlags, xPrecision, yPrecision); + metaState, buttonState, motionClassificationToString(classification), edgeFlags, + xPrecision, yPrecision); for (uint32_t i = 0; i < pointerCount; i++) { if (i) { @@ -4733,15 +4736,15 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim for (size_t i = 0; i < mMotionMementos.size(); i++) { const MotionMemento& memento = mMotionMementos.itemAt(i); if (shouldCancelMotion(memento, options)) { + const int32_t action = memento.hovering ? + AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL; outEvents.push(new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId, memento.source, memento.displayId, memento.policyFlags, - memento.hovering - ? AMOTION_EVENT_ACTION_HOVER_EXIT - : AMOTION_EVENT_ACTION_CANCEL, - memento.flags, 0, 0, 0, 0, + action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/, + MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision, memento.yPrecision, memento.downTime, memento.pointerCount, memento.pointerProperties, memento.pointerCoords, - 0, 0)); + 0 /*xOffset*/, 0 /*yOffset*/)); } } } diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h index 49de6f35cc..327dbbd9b1 100644 --- a/services/inputflinger/InputDispatcher.h +++ b/services/inputflinger/InputDispatcher.h @@ -535,6 +535,7 @@ private: int32_t flags; int32_t metaState; int32_t buttonState; + MotionClassification classification; int32_t edgeFlags; float xPrecision; float yPrecision; @@ -546,8 +547,9 @@ private: MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton, int32_t flags, - int32_t metaState, int32_t buttonState, int32_t edgeFlags, - float xPrecision, float yPrecision, nsecs_t downTime, uint32_t pointerCount, + int32_t metaState, int32_t buttonState, MotionClassification classification, + int32_t edgeFlags, float xPrecision, float yPrecision, + nsecs_t downTime, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, float xOffset, float yOffset); virtual void appendDescription(std::string& msg) const; |