Let InputFlinger generate event IDs.
Also send event IDs via InputMessage and add some atrace calls to form a
complete chain of input event processing.
Bug: 144889238
Test: systrace shows correct event IDs.
Test: atest inputflinger_tests
Change-Id: I3c561b03b0ba75c22115ae020e6b41855686ab64
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 06fd3bb..8ca178c 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -82,7 +82,7 @@
union Body {
struct Key {
uint32_t seq;
- uint32_t empty1;
+ int32_t eventId;
nsecs_t eventTime __attribute__((aligned(8)));
int32_t deviceId;
int32_t source;
@@ -102,7 +102,7 @@
struct Motion {
uint32_t seq;
- uint32_t empty1;
+ int32_t eventId;
nsecs_t eventTime __attribute__((aligned(8)));
int32_t deviceId;
int32_t source;
@@ -159,6 +159,8 @@
struct Focus {
uint32_t seq;
+ int32_t eventId;
+ uint32_t empty1;
// The following two fields take up 4 bytes total
uint16_t hasFocus; // actually a bool
uint16_t inTouchMode; // actually a bool, but we must maintain 8-byte alignment
@@ -276,9 +278,9 @@
* Returns BAD_VALUE if seq is 0.
* Other errors probably indicate that the channel is broken.
*/
- status_t publishKeyEvent(uint32_t seq, int32_t deviceId, int32_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,
+ status_t publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_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);
/* Publishes a motion event to the input channel.
@@ -289,14 +291,15 @@
* Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
* Other errors probably indicate that the channel is broken.
*/
- status_t publishMotionEvent(uint32_t seq, int32_t deviceId, int32_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 xCursorPosition,
- float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
+ status_t publishMotionEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_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 xCursorPosition, float yCursorPosition, nsecs_t downTime,
+ nsecs_t eventTime, uint32_t pointerCount,
+ const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords);
/* Publishes a focus event to the input channel.
@@ -306,7 +309,7 @@
* Returns DEAD_OBJECT if the channel's peer has been closed.
* Other errors probably indicate that the channel is broken.
*/
- status_t publishFocusEvent(uint32_t seq, bool hasFocus, bool inTouchMode);
+ status_t publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus, bool inTouchMode);
/* Receives the finished signal from the consumer in reply to the original dispatch signal.
* If a signal was received, returns the message sequence number,
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index eda01c5..7335b30 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -63,10 +63,6 @@
// far into the future. This time is further bounded by 50% of the last time delta.
static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
-// A placeholder sequence number used to initialize native input events before InputFlinger is
-// migrated to new sequence number system.
-static constexpr int32_t INPUT_FLINGER_SEQUENCE_NUM = 0;
-
/**
* System property for enabling / disabling touch resampling.
* Resampling extrapolates / interpolates the reported touch event coordinates to better
@@ -143,6 +139,8 @@
case InputMessage::Type::KEY: {
// uint32_t seq
msg->body.key.seq = body.key.seq;
+ // int32_t eventId
+ msg->body.key.eventId = body.key.eventId;
// nsecs_t eventTime
msg->body.key.eventTime = body.key.eventTime;
// int32_t deviceId
@@ -172,6 +170,8 @@
case InputMessage::Type::MOTION: {
// uint32_t seq
msg->body.motion.seq = body.motion.seq;
+ // int32_t eventId
+ msg->body.motion.eventId = body.motion.eventId;
// nsecs_t eventTime
msg->body.motion.eventTime = body.motion.eventTime;
// int32_t deviceId
@@ -238,6 +238,7 @@
}
case InputMessage::Type::FOCUS: {
msg->body.focus.seq = body.focus.seq;
+ msg->body.focus.eventId = body.focus.eventId;
msg->body.focus.hasFocus = body.focus.hasFocus;
msg->body.focus.inTouchMode = body.focus.inTouchMode;
break;
@@ -436,11 +437,12 @@
InputPublisher::~InputPublisher() {
}
-status_t InputPublisher::publishKeyEvent(uint32_t seq, int32_t deviceId, int32_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) {
+status_t InputPublisher::publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId,
+ int32_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) {
if (ATRACE_ENABLED()) {
std::string message = StringPrintf("publishKeyEvent(inputChannel=%s, keyCode=%" PRId32 ")",
mChannel->getName().c_str(), keyCode);
@@ -462,6 +464,7 @@
InputMessage msg;
msg.header.type = InputMessage::Type::KEY;
msg.body.key.seq = seq;
+ msg.body.key.eventId = eventId;
msg.body.key.deviceId = deviceId;
msg.body.key.source = source;
msg.body.key.displayId = displayId;
@@ -478,7 +481,7 @@
}
status_t InputPublisher::publishMotionEvent(
- uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId,
+ uint32_t seq, int32_t eventId, int32_t deviceId, int32_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,
@@ -519,6 +522,7 @@
InputMessage msg;
msg.header.type = InputMessage::Type::MOTION;
msg.body.motion.seq = seq;
+ msg.body.motion.eventId = eventId;
msg.body.motion.deviceId = deviceId;
msg.body.motion.source = source;
msg.body.motion.displayId = displayId;
@@ -549,7 +553,8 @@
return mChannel->sendMessage(&msg);
}
-status_t InputPublisher::publishFocusEvent(uint32_t seq, bool hasFocus, bool inTouchMode) {
+status_t InputPublisher::publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus,
+ bool inTouchMode) {
if (ATRACE_ENABLED()) {
std::string message =
StringPrintf("publishFocusEvent(inputChannel=%s, hasFocus=%s, inTouchMode=%s)",
@@ -561,6 +566,7 @@
InputMessage msg;
msg.header.type = InputMessage::Type::FOCUS;
msg.body.focus.seq = seq;
+ msg.body.focus.eventId = eventId;
msg.body.focus.hasFocus = hasFocus ? 1 : 0;
msg.body.focus.inTouchMode = inTouchMode ? 1 : 0;
return mChannel->sendMessage(&msg);
@@ -1146,7 +1152,7 @@
}
void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
- event->initialize(INPUT_FLINGER_SEQUENCE_NUM, msg->body.key.deviceId, msg->body.key.source,
+ event->initialize(msg->body.key.eventId, msg->body.key.deviceId, msg->body.key.source,
msg->body.key.displayId, msg->body.key.hmac, msg->body.key.action,
msg->body.key.flags, msg->body.key.keyCode, msg->body.key.scanCode,
msg->body.key.metaState, msg->body.key.repeatCount, msg->body.key.downTime,
@@ -1154,7 +1160,7 @@
}
void InputConsumer::initializeFocusEvent(FocusEvent* event, const InputMessage* msg) {
- event->initialize(INPUT_FLINGER_SEQUENCE_NUM, msg->body.focus.hasFocus == 1,
+ event->initialize(msg->body.focus.eventId, msg->body.focus.hasFocus == 1,
msg->body.focus.inTouchMode == 1);
}
@@ -1167,17 +1173,16 @@
pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
}
- event->initialize(INPUT_FLINGER_SEQUENCE_NUM, msg->body.motion.deviceId,
- msg->body.motion.source, msg->body.motion.displayId, msg->body.motion.hmac,
- msg->body.motion.action, msg->body.motion.actionButton,
- msg->body.motion.flags, msg->body.motion.edgeFlags,
- msg->body.motion.metaState, msg->body.motion.buttonState,
- msg->body.motion.classification, msg->body.motion.xScale,
- msg->body.motion.yScale, msg->body.motion.xOffset, msg->body.motion.yOffset,
- msg->body.motion.xPrecision, msg->body.motion.yPrecision,
- msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
- msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
- pointerProperties, pointerCoords);
+ event->initialize(msg->body.motion.eventId, msg->body.motion.deviceId, msg->body.motion.source,
+ msg->body.motion.displayId, msg->body.motion.hmac, msg->body.motion.action,
+ msg->body.motion.actionButton, msg->body.motion.flags,
+ msg->body.motion.edgeFlags, msg->body.motion.metaState,
+ msg->body.motion.buttonState, msg->body.motion.classification,
+ msg->body.motion.xScale, msg->body.motion.yScale, msg->body.motion.xOffset,
+ msg->body.motion.yOffset, msg->body.motion.xPrecision,
+ msg->body.motion.yPrecision, msg->body.motion.xCursorPosition,
+ msg->body.motion.yCursorPosition, msg->body.motion.downTime,
+ msg->body.motion.eventTime, pointerCount, pointerProperties, pointerCoords);
}
void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index 885196f..8e2eec8 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -73,6 +73,7 @@
status_t status;
constexpr uint32_t seq = 15;
+ int32_t eventId = InputEvent::nextId();
constexpr int32_t deviceId = 1;
constexpr uint32_t source = AINPUT_SOURCE_KEYBOARD;
constexpr int32_t displayId = ADISPLAY_ID_DEFAULT;
@@ -88,8 +89,8 @@
constexpr nsecs_t downTime = 3;
constexpr nsecs_t eventTime = 4;
- status = mPublisher->publishKeyEvent(seq, deviceId, source, displayId, hmac, action, flags,
- keyCode, scanCode, metaState, repeatCount, downTime,
+ status = mPublisher->publishKeyEvent(seq, eventId, deviceId, source, displayId, hmac, action,
+ flags, keyCode, scanCode, metaState, repeatCount, downTime,
eventTime);
ASSERT_EQ(OK, status)
<< "publisher publishKeyEvent should return OK";
@@ -107,6 +108,7 @@
KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
EXPECT_EQ(seq, consumeSeq);
+ EXPECT_EQ(eventId, keyEvent->getId());
EXPECT_EQ(deviceId, keyEvent->getDeviceId());
EXPECT_EQ(source, keyEvent->getSource());
EXPECT_EQ(displayId, keyEvent->getDisplayId());
@@ -139,6 +141,7 @@
status_t status;
constexpr uint32_t seq = 15;
+ int32_t eventId = InputEvent::nextId();
constexpr int32_t deviceId = 1;
constexpr uint32_t source = AINPUT_SOURCE_TOUCHSCREEN;
constexpr int32_t displayId = ADISPLAY_ID_DEFAULT;
@@ -182,7 +185,7 @@
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
}
- status = mPublisher->publishMotionEvent(seq, deviceId, source, displayId, hmac, action,
+ status = mPublisher->publishMotionEvent(seq, eventId, deviceId, source, displayId, hmac, action,
actionButton, flags, edgeFlags, metaState, buttonState,
classification, xScale, yScale, xOffset, yOffset,
xPrecision, yPrecision, xCursorPosition,
@@ -204,6 +207,7 @@
MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
EXPECT_EQ(seq, consumeSeq);
+ EXPECT_EQ(eventId, motionEvent->getId());
EXPECT_EQ(deviceId, motionEvent->getDeviceId());
EXPECT_EQ(source, motionEvent->getSource());
EXPECT_EQ(displayId, motionEvent->getDisplayId());
@@ -277,10 +281,11 @@
status_t status;
constexpr uint32_t seq = 15;
+ int32_t eventId = InputEvent::nextId();
constexpr bool hasFocus = true;
constexpr bool inTouchMode = true;
- status = mPublisher->publishFocusEvent(seq, hasFocus, inTouchMode);
+ status = mPublisher->publishFocusEvent(seq, eventId, hasFocus, inTouchMode);
ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK";
uint32_t consumeSeq;
@@ -294,6 +299,7 @@
FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
EXPECT_EQ(seq, consumeSeq);
+ EXPECT_EQ(eventId, focusEvent->getId());
EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
@@ -332,8 +338,8 @@
pointerCoords[i].clear();
}
- status = mPublisher->publishMotionEvent(0, 0, 0, 0, INVALID_HMAC, 0, 0, 0, 0, 0, 0,
- MotionClassification::NONE, 1 /* xScale */,
+ status = mPublisher->publishMotionEvent(0, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
+ 0, 0, 0, MotionClassification::NONE, 1 /* xScale */,
1 /* yScale */, 0, 0, 0, 0,
AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
@@ -348,8 +354,8 @@
PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
- status = mPublisher->publishMotionEvent(1, 0, 0, 0, INVALID_HMAC, 0, 0, 0, 0, 0, 0,
- MotionClassification::NONE, 1 /* xScale */,
+ status = mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
+ 0, 0, 0, MotionClassification::NONE, 1 /* xScale */,
1 /* yScale */, 0, 0, 0, 0,
AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
@@ -369,8 +375,8 @@
pointerCoords[i].clear();
}
- status = mPublisher->publishMotionEvent(1, 0, 0, 0, INVALID_HMAC, 0, 0, 0, 0, 0, 0,
- MotionClassification::NONE, 1 /* xScale */,
+ status = mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
+ 0, 0, 0, MotionClassification::NONE, 1 /* xScale */,
1 /* yScale */, 0, 0, 0, 0,
AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index dd127fc..1fe7bb9 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -35,6 +35,7 @@
CHECK_OFFSET(InputMessage, body, 8);
CHECK_OFFSET(InputMessage::Body::Key, seq, 0);
+ CHECK_OFFSET(InputMessage::Body::Key, eventId, 4);
CHECK_OFFSET(InputMessage::Body::Key, eventTime, 8);
CHECK_OFFSET(InputMessage::Body::Key, deviceId, 16);
CHECK_OFFSET(InputMessage::Body::Key, source, 20);
@@ -49,6 +50,7 @@
CHECK_OFFSET(InputMessage::Body::Key, downTime, 88);
CHECK_OFFSET(InputMessage::Body::Motion, seq, 0);
+ CHECK_OFFSET(InputMessage::Body::Motion, eventId, 4);
CHECK_OFFSET(InputMessage::Body::Motion, eventTime, 8);
CHECK_OFFSET(InputMessage::Body::Motion, deviceId, 16);
CHECK_OFFSET(InputMessage::Body::Motion, source, 20);
@@ -74,8 +76,9 @@
CHECK_OFFSET(InputMessage::Body::Motion, pointers, 136);
CHECK_OFFSET(InputMessage::Body::Focus, seq, 0);
- CHECK_OFFSET(InputMessage::Body::Focus, hasFocus, 4);
- CHECK_OFFSET(InputMessage::Body::Focus, inTouchMode, 6);
+ CHECK_OFFSET(InputMessage::Body::Focus, eventId, 4);
+ CHECK_OFFSET(InputMessage::Body::Focus, hasFocus, 12);
+ CHECK_OFFSET(InputMessage::Body::Focus, inTouchMode, 14);
CHECK_OFFSET(InputMessage::Body::Finished, seq, 0);
CHECK_OFFSET(InputMessage::Body::Finished, handled, 4);
@@ -95,7 +98,7 @@
offsetof(InputMessage::Body::Motion, pointers) +
sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
static_assert(sizeof(InputMessage::Body::Finished) == 8);
- static_assert(sizeof(InputMessage::Body::Focus) == 8);
+ static_assert(sizeof(InputMessage::Body::Focus) == 16);
}
// --- VerifiedInputEvent ---
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 439d9bf..4ec4e25 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -108,6 +108,7 @@
srcs: [":libinputflinger_base_sources"],
shared_libs: [
"libbase",
+ "libcutils",
"libinput",
"liblog",
"libutils",
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index e91e803..84838ec 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -16,12 +16,18 @@
#define LOG_TAG "InputListener"
+#define ATRACE_TAG ATRACE_TAG_INPUT
+
//#define LOG_NDEBUG 0
#include "InputListener.h"
+#include <android-base/stringprintf.h>
#include <android/log.h>
#include <math.h>
+#include <utils/Trace.h>
+
+using android::base::StringPrintf;
namespace android {
@@ -228,6 +234,13 @@
// --- QueuedInputListener ---
+static inline void traceEvent(const char* functionName, int32_t id) {
+ if (ATRACE_ENABLED()) {
+ std::string message = StringPrintf("%s(id=0x%" PRIx32 ")", functionName, id);
+ ATRACE_NAME(message.c_str());
+ }
+}
+
QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
mInnerListener(innerListener) {
}
@@ -241,22 +254,27 @@
void QueuedInputListener::notifyConfigurationChanged(
const NotifyConfigurationChangedArgs* args) {
+ traceEvent(__func__, args->id);
mArgsQueue.push_back(new NotifyConfigurationChangedArgs(*args));
}
void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
+ traceEvent(__func__, args->id);
mArgsQueue.push_back(new NotifyKeyArgs(*args));
}
void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
+ traceEvent(__func__, args->id);
mArgsQueue.push_back(new NotifyMotionArgs(*args));
}
void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) {
+ traceEvent(__func__, args->id);
mArgsQueue.push_back(new NotifySwitchArgs(*args));
}
void QueuedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
+ traceEvent(__func__, args->id);
mArgsQueue.push_back(new NotifyDeviceResetArgs(*args));
}
diff --git a/services/inputflinger/dispatcher/Connection.cpp b/services/inputflinger/dispatcher/Connection.cpp
index 6f82f4f..188212b 100644
--- a/services/inputflinger/dispatcher/Connection.cpp
+++ b/services/inputflinger/dispatcher/Connection.cpp
@@ -20,11 +20,13 @@
namespace android::inputdispatcher {
-Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor)
+Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor,
+ const IdGenerator& idGenerator)
: status(STATUS_NORMAL),
inputChannel(inputChannel),
monitor(monitor),
inputPublisher(inputChannel),
+ inputState(idGenerator),
inputPublisherBlocked(false) {}
Connection::~Connection() {}
diff --git a/services/inputflinger/dispatcher/Connection.h b/services/inputflinger/dispatcher/Connection.h
index 8423010..bb3f2fe 100644
--- a/services/inputflinger/dispatcher/Connection.h
+++ b/services/inputflinger/dispatcher/Connection.h
@@ -58,7 +58,7 @@
// yet received a "finished" response from the application.
std::deque<DispatchEntry*> waitQueue;
- explicit Connection(const sp<InputChannel>& inputChannel, bool monitor);
+ Connection(const sp<InputChannel>& inputChannel, bool monitor, const IdGenerator& idGenerator);
inline const std::string getInputChannelName() const { return inputChannel->getName(); }
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index c58ae23..ab481bd 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -29,9 +29,6 @@
namespace android::inputdispatcher {
-// Sequence number for synthesized or injected events.
-constexpr int32_t SYNTHESIZED_EVENT_ID = 0;
-
struct EventEntry {
enum class Type {
CONFIGURATION_CHANGED,
@@ -78,7 +75,9 @@
* Key repeat is a synthesized event, because it is related to an actual hardware state
* (a key is currently pressed), but the repeat itself is generated by the framework.
*/
- inline bool isSynthesized() const { return isInjected() || id == SYNTHESIZED_EVENT_ID; }
+ inline bool isSynthesized() const {
+ return isInjected() || IdGenerator::getSource(id) != IdGenerator::Source::INPUT_READER;
+ }
void release();
@@ -199,7 +198,8 @@
float windowYScale = 1.0f;
nsecs_t deliveryTime; // time when the event was actually delivered
- // Set to the resolved action and flags when the event is enqueued.
+ // Set to the resolved ID, action and flags when the event is enqueued.
+ int32_t resolvedEventId;
int32_t resolvedAction;
int32_t resolvedFlags;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 2f7b5ad..308d19b 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -383,6 +383,7 @@
: mPolicy(policy),
mPendingEvent(nullptr),
mLastDropReason(DropReason::NOT_DROPPED),
+ mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
mAppSwitchSawKeyDown(false),
mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(nullptr),
@@ -925,12 +926,13 @@
(POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
if (entry->refCount == 1) {
entry->recycle();
+ entry->id = mIdGenerator.nextId();
entry->eventTime = currentTime;
entry->policyFlags = policyFlags;
entry->repeatCount += 1;
} else {
KeyEntry* newEntry =
- new KeyEntry(SYNTHESIZED_EVENT_ID, currentTime, entry->deviceId, entry->source,
+ new KeyEntry(mIdGenerator.nextId(), currentTime, entry->deviceId, entry->source,
entry->displayId, policyFlags, entry->action, entry->flags,
entry->keyCode, entry->scanCode, entry->metaState,
entry->repeatCount + 1, entry->downTime);
@@ -981,7 +983,7 @@
void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
FocusEntry* focusEntry =
- new FocusEntry(SYNTHESIZED_EVENT_ID, now(), window.getToken(), hasFocus);
+ new FocusEntry(mIdGenerator.nextId(), now(), window.getToken(), hasFocus);
enqueueInboundEventLocked(focusEntry);
}
@@ -2188,7 +2190,7 @@
const InputTarget& inputTarget) {
if (ATRACE_ENABLED()) {
std::string message =
- StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=%" PRIx32 ")",
+ StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
connection->getInputChannelName().c_str(), eventEntry->id);
ATRACE_NAME(message.c_str());
}
@@ -2244,7 +2246,7 @@
const InputTarget& inputTarget) {
if (ATRACE_ENABLED()) {
std::string message =
- StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=%" PRIx32 ")",
+ StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
connection->getInputChannelName().c_str(), eventEntry->id);
ATRACE_NAME(message.c_str());
}
@@ -2299,6 +2301,7 @@
switch (newEntry->type) {
case EventEntry::Type::KEY: {
const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
+ dispatchEntry->resolvedEventId = keyEntry.id;
dispatchEntry->resolvedAction = keyEntry.action;
dispatchEntry->resolvedFlags = keyEntry.flags;
@@ -2315,6 +2318,11 @@
case EventEntry::Type::MOTION: {
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
+ // Assign a default value to dispatchEntry that will never be generated by InputReader,
+ // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
+ constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
+ static_cast<int32_t>(IdGenerator::Source::OTHER);
+ dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
} else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
@@ -2327,6 +2335,7 @@
dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
} else {
dispatchEntry->resolvedAction = motionEntry.action;
+ dispatchEntry->resolvedEventId = motionEntry.id;
}
if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
!connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
@@ -2357,6 +2366,17 @@
return; // skip the inconsistent event
}
+ dispatchEntry->resolvedEventId =
+ dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
+ ? mIdGenerator.nextId()
+ : motionEntry.id;
+ if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
+ std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
+ ") to MotionEvent(id=0x%" PRIx32 ").",
+ motionEntry.id, dispatchEntry->resolvedEventId);
+ ATRACE_NAME(message.c_str());
+ }
+
dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
inputTarget.inputChannel->getConnectionToken());
@@ -2438,14 +2458,16 @@
std::array<uint8_t, 32> hmac = mHmacKeyManager.sign(verifiedEvent);
// Publish the key event.
- status = connection->inputPublisher
- .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
- keyEntry->source, keyEntry->displayId,
- std::move(hmac), dispatchEntry->resolvedAction,
- dispatchEntry->resolvedFlags, keyEntry->keyCode,
- keyEntry->scanCode, keyEntry->metaState,
- keyEntry->repeatCount, keyEntry->downTime,
- keyEntry->eventTime);
+ status =
+ connection->inputPublisher
+ .publishKeyEvent(dispatchEntry->seq, dispatchEntry->resolvedEventId,
+ keyEntry->deviceId, keyEntry->source,
+ keyEntry->displayId, std::move(hmac),
+ dispatchEntry->resolvedAction,
+ dispatchEntry->resolvedFlags, keyEntry->keyCode,
+ keyEntry->scanCode, keyEntry->metaState,
+ keyEntry->repeatCount, keyEntry->downTime,
+ keyEntry->eventTime);
break;
}
@@ -2494,9 +2516,11 @@
// Publish the motion event.
status = connection->inputPublisher
- .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
- motionEntry->source, motionEntry->displayId,
- std::move(hmac), dispatchEntry->resolvedAction,
+ .publishMotionEvent(dispatchEntry->seq,
+ dispatchEntry->resolvedEventId,
+ motionEntry->deviceId, motionEntry->source,
+ motionEntry->displayId, std::move(hmac),
+ dispatchEntry->resolvedAction,
motionEntry->actionButton,
dispatchEntry->resolvedFlags,
motionEntry->edgeFlags, motionEntry->metaState,
@@ -2515,6 +2539,7 @@
case EventEntry::Type::FOCUS: {
FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
+ focusEntry->id,
focusEntry->hasFocus,
mInTouchMode);
break;
@@ -2920,10 +2945,17 @@
}
}
+ int32_t newId = mIdGenerator.nextId();
+ if (ATRACE_ENABLED()) {
+ std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
+ ") to MotionEvent(id=0x%" PRIx32 ").",
+ originalMotionEntry.id, newId);
+ ATRACE_NAME(message.c_str());
+ }
MotionEntry* splitMotionEntry =
- new MotionEntry(originalMotionEntry.id, originalMotionEntry.eventTime,
- originalMotionEntry.deviceId, originalMotionEntry.source,
- originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
+ new MotionEntry(newId, originalMotionEntry.eventTime, originalMotionEntry.deviceId,
+ originalMotionEntry.source, originalMotionEntry.displayId,
+ originalMotionEntry.policyFlags, action,
originalMotionEntry.actionButton, originalMotionEntry.flags,
originalMotionEntry.metaState, originalMotionEntry.buttonState,
originalMotionEntry.classification, originalMotionEntry.edgeFlags,
@@ -4225,7 +4257,7 @@
return BAD_VALUE;
}
- sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
+ sp<Connection> connection = new Connection(inputChannel, false /*monitor*/, mIdGenerator);
int fd = inputChannel->getFd();
mConnectionsByFd[fd] = connection;
@@ -4254,7 +4286,7 @@
return BAD_VALUE;
}
- sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
+ sp<Connection> connection = new Connection(inputChannel, true /*monitor*/, mIdGenerator);
const int fd = inputChannel->getFd();
mConnectionsByFd[fd] = connection;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 482133e..4aa47f8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -156,6 +156,8 @@
DropReason mLastDropReason GUARDED_BY(mLock);
+ const IdGenerator mIdGenerator;
+
// With each iteration, InputDispatcher nominally processes one queued event,
// a timeout, or a response from an input consumer.
// This method should only be called on the input dispatcher's own thread.
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index 7fa9e09..386056d 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -16,9 +16,11 @@
#include "InputState.h"
+#include "InputDispatcher.h"
+
namespace android::inputdispatcher {
-InputState::InputState() {}
+InputState::InputState(const IdGenerator& idGenerator) : mIdGenerator(idGenerator) {}
InputState::~InputState() {}
@@ -268,7 +270,7 @@
std::vector<EventEntry*> events;
for (KeyMemento& memento : mKeyMementos) {
if (shouldCancelKey(memento, options)) {
- events.push_back(new KeyEntry(SYNTHESIZED_EVENT_ID, currentTime, memento.deviceId,
+ events.push_back(new KeyEntry(mIdGenerator.nextId(), currentTime, memento.deviceId,
memento.source, memento.displayId, memento.policyFlags,
AKEY_EVENT_ACTION_UP,
memento.flags | AKEY_EVENT_FLAG_CANCELED, memento.keyCode,
@@ -281,7 +283,7 @@
if (shouldCancelMotion(memento, options)) {
const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT
: AMOTION_EVENT_ACTION_CANCEL;
- events.push_back(new MotionEntry(SYNTHESIZED_EVENT_ID, currentTime, memento.deviceId,
+ events.push_back(new MotionEntry(mIdGenerator.nextId(), currentTime, memento.deviceId,
memento.source, memento.displayId, memento.policyFlags,
action, 0 /*actionButton*/, memento.flags, AMETA_NONE,
0 /*buttonState*/, MotionClassification::NONE,
@@ -331,7 +333,7 @@
: AMOTION_EVENT_ACTION_POINTER_DOWN
| (i << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
- events.push_back(new MotionEntry(SYNTHESIZED_EVENT_ID, currentTime, memento.deviceId,
+ events.push_back(new MotionEntry(mIdGenerator.nextId(), currentTime, memento.deviceId,
memento.source, memento.displayId, memento.policyFlags,
action, 0 /*actionButton*/, memento.flags, AMETA_NONE,
0 /*buttonState*/, MotionClassification::NONE,
diff --git a/services/inputflinger/dispatcher/InputState.h b/services/inputflinger/dispatcher/InputState.h
index 08266ae..d97a664 100644
--- a/services/inputflinger/dispatcher/InputState.h
+++ b/services/inputflinger/dispatcher/InputState.h
@@ -30,7 +30,7 @@
* synthesized when events are dropped. */
class InputState {
public:
- InputState();
+ explicit InputState(const IdGenerator& idGenerator);
~InputState();
// Returns true if there is no state to be canceled.
@@ -111,6 +111,8 @@
void mergePointerStateTo(MotionMemento& other) const;
};
+ const IdGenerator& mIdGenerator; // InputDispatcher owns it so we won't have dangling reference.
+
std::vector<KeyMemento> mKeyMementos;
std::vector<MotionMemento> mMotionMementos;
KeyedVector<int32_t, int32_t> mFallbackKeys;
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 2998cc9..657a134 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -46,7 +46,6 @@
: mContext(this),
mEventHub(eventHub),
mPolicy(policy),
- mNextId(1),
mGlobalMetaState(0),
mGeneration(1),
mNextInputDeviceId(END_RESERVED_ID),
@@ -697,7 +696,8 @@
// --- InputReader::ContextImpl ---
-InputReader::ContextImpl::ContextImpl(InputReader* reader) : mReader(reader) {}
+InputReader::ContextImpl::ContextImpl(InputReader* reader)
+ : mReader(reader), mIdGenerator(IdGenerator::Source::INPUT_READER) {}
void InputReader::ContextImpl::updateGlobalMetaState() {
// lock is already held by the input loop
@@ -762,7 +762,7 @@
}
int32_t InputReader::ContextImpl::getNextId() {
- return (mReader->mNextId)++;
+ return mIdGenerator.nextId();
}
} // namespace android
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index eaa105a..693ec30 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -94,6 +94,7 @@
class ContextImpl : public InputReaderContext {
InputReader* mReader;
+ IdGenerator mIdGenerator;
public:
explicit ContextImpl(InputReader* reader);
@@ -132,9 +133,6 @@
InputReaderConfiguration mConfig;
- // used by InputReaderContext::getNextId() as a counter for event sequence numbers
- uint32_t mNextId;
-
// The event queue.
static const int EVENT_BUFFER_SIZE = 256;
RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 270f891..d30c4f1 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -16,13 +16,18 @@
#include "../dispatcher/InputDispatcher.h"
+#include <android-base/stringprintf.h>
#include <binder/Binder.h>
#include <input/Input.h>
#include <gtest/gtest.h>
#include <linux/input.h>
+#include <cinttypes>
+#include <unordered_set>
#include <vector>
+using android::base::StringPrintf;
+
namespace android::inputdispatcher {
// An arbitrary time value.
@@ -107,6 +112,11 @@
<< "Expected onPointerDownOutsideFocus to not have been called";
}
+ void setKeyRepeatConfiguration(nsecs_t timeout, nsecs_t delay) {
+ mConfig.keyRepeatTimeout = timeout;
+ mConfig.keyRepeatDelay = delay;
+ }
+
private:
std::unique_ptr<InputEvent> mFilteredEvent;
std::optional<nsecs_t> mConfigurationChangedTime;
@@ -1443,6 +1453,105 @@
ASSERT_EQ(0, verifiedKey.repeatCount);
}
+class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
+protected:
+ static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
+ static constexpr nsecs_t KEY_REPEAT_DELAY = 40 * 1000000; // 40 ms
+
+ sp<FakeApplicationHandle> mApp;
+ sp<FakeWindowHandle> mWindow;
+
+ virtual void SetUp() override {
+ mFakePolicy = new FakeInputDispatcherPolicy();
+ mFakePolicy->setKeyRepeatConfiguration(KEY_REPEAT_TIMEOUT, KEY_REPEAT_DELAY);
+ mDispatcher = new InputDispatcher(mFakePolicy);
+ mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
+ ASSERT_EQ(OK, mDispatcher->start());
+
+ setUpWindow();
+ }
+
+ void setUpWindow() {
+ mApp = new FakeApplicationHandle();
+ mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+
+ mWindow->setFocus(true);
+ mDispatcher->setInputWindows({mWindow}, ADISPLAY_ID_DEFAULT);
+
+ mWindow->consumeFocusEvent(true);
+ }
+
+ void sendAndConsumeKeyDown() {
+ NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
+ keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Otherwise it won't generate repeat event
+ mDispatcher->notifyKey(&keyArgs);
+
+ // Window should receive key down event.
+ mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
+ }
+
+ void expectKeyRepeatOnce(int32_t repeatCount) {
+ SCOPED_TRACE(StringPrintf("Checking event with repeat count %" PRId32, repeatCount));
+ InputEvent* repeatEvent = mWindow->consume();
+ ASSERT_NE(nullptr, repeatEvent);
+
+ uint32_t eventType = repeatEvent->getType();
+ ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, eventType);
+
+ KeyEvent* repeatKeyEvent = static_cast<KeyEvent*>(repeatEvent);
+ uint32_t eventAction = repeatKeyEvent->getAction();
+ EXPECT_EQ(AKEY_EVENT_ACTION_DOWN, eventAction);
+ EXPECT_EQ(repeatCount, repeatKeyEvent->getRepeatCount());
+ }
+
+ void sendAndConsumeKeyUp() {
+ NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
+ keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Unless it won't generate repeat event
+ mDispatcher->notifyKey(&keyArgs);
+
+ // Window should receive key down event.
+ mWindow->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
+ 0 /*expectedFlags*/);
+ }
+};
+
+TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeat) {
+ sendAndConsumeKeyDown();
+ for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
+ expectKeyRepeatOnce(repeatCount);
+ }
+}
+
+TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) {
+ sendAndConsumeKeyDown();
+ expectKeyRepeatOnce(1 /*repeatCount*/);
+ sendAndConsumeKeyUp();
+ mWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
+ sendAndConsumeKeyDown();
+ for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
+ InputEvent* repeatEvent = mWindow->consume();
+ ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
+ EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
+ IdGenerator::getSource(repeatEvent->getId()));
+ }
+}
+
+TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseUniqueEventId) {
+ sendAndConsumeKeyDown();
+
+ std::unordered_set<int32_t> idSet;
+ for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
+ InputEvent* repeatEvent = mWindow->consume();
+ ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
+ int32_t id = repeatEvent->getId();
+ EXPECT_EQ(idSet.end(), idSet.find(id));
+ idSet.insert(id);
+ }
+}
+
/* Test InputDispatcher for MultiDisplay */
class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
public:
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 46cd480..3ae8b56 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1642,7 +1642,7 @@
ASSERT_EQ(1, event.value);
}
-TEST_F(InputReaderTest, DeviceReset_IncrementsId) {
+TEST_F(InputReaderTest, DeviceReset_RandomId) {
constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
constexpr int32_t eventHubId = 1;
@@ -1659,22 +1659,37 @@
disableDevice(deviceId);
mReader->loopOnce();
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
- ASSERT_TRUE(prevId < resetArgs.id);
+ ASSERT_NE(prevId, resetArgs.id);
prevId = resetArgs.id;
enableDevice(deviceId);
mReader->loopOnce();
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
- ASSERT_TRUE(prevId < resetArgs.id);
+ ASSERT_NE(prevId, resetArgs.id);
prevId = resetArgs.id;
disableDevice(deviceId);
mReader->loopOnce();
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
- ASSERT_TRUE(prevId < resetArgs.id);
+ ASSERT_NE(prevId, resetArgs.id);
prevId = resetArgs.id;
}
+TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
+ constexpr int32_t deviceId = 1;
+ constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ constexpr int32_t eventHubId = 1;
+ std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
+ // Must add at least one mapper or the device will be ignored!
+ device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
+ mReader->setNextDevice(device);
+ ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
+
+ NotifyDeviceResetArgs resetArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
+ ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
+}
+
TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
@@ -1821,14 +1836,14 @@
keyboard->pressAndReleaseHomeKey();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
- ASSERT_LT(prevId, keyArgs.id);
+ ASSERT_NE(prevId, keyArgs.id);
prevId = keyArgs.id;
ASSERT_LE(prevTimestamp, keyArgs.eventTime);
prevTimestamp = keyArgs.eventTime;
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
- ASSERT_LT(prevId, keyArgs.id);
+ ASSERT_NE(prevId, keyArgs.id);
ASSERT_LE(prevTimestamp, keyArgs.eventTime);
}