Merge "Propagate MotionClassification to InputDispatcher"
diff --git a/include/input/Input.h b/include/input/Input.h
index 2c4a511..805957a 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -241,6 +241,11 @@
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 dddbfb0..63606e5 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -105,8 +105,9 @@
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 @@
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 db86c8e..9fd25f9 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 0ddee44..0f7a1f0 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -157,6 +157,8 @@
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 @@
int32_t edgeFlags,
int32_t metaState,
int32_t buttonState,
+ MotionClassification classification,
float xOffset,
float yOffset,
float xPrecision,
@@ -461,13 +464,13 @@
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 @@
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 @@
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 96c165c..f1675c0 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 @@
<< "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 e4c1514..2b75c82 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 @@
// 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 @@
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 @@
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 0788c89..f2cd1be 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -141,6 +141,7 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 12a6782..62023fb 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -57,7 +57,8 @@
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 9af189a..9d92435 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2155,7 +2155,7 @@
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 @@
originalMotionEntry->flags,
originalMotionEntry->metaState,
originalMotionEntry->buttonState,
+ originalMotionEntry->classification,
originalMotionEntry->edgeFlags,
originalMotionEntry->xPrecision,
originalMotionEntry->yPrecision,
@@ -2707,7 +2708,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 49de6f3..327dbbd 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -535,6 +535,7 @@
int32_t flags;
int32_t metaState;
int32_t buttonState;
+ MotionClassification classification;
int32_t edgeFlags;
float xPrecision;
float yPrecision;
@@ -546,8 +547,9 @@
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;