Loading include/input/InputTransport.h +15 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ */ #include <string> #include <unordered_map> #include <android-base/chrono_utils.h> Loading Loading @@ -155,6 +156,7 @@ struct InputMessage { struct Finished { uint32_t empty1; uint32_t handled; // actually a bool, but we must maintain 8-byte alignment nsecs_t consumeTime; // The time when the event was consumed by the receiving end inline size_t size() const { return sizeof(Finished); } } finished; Loading Loading @@ -362,7 +364,8 @@ public: /* Receives the finished signal from the consumer in reply to the original dispatch signal. * If a signal was received, returns the message sequence number, * and whether the consumer handled the message. * whether the consumer handled the message, and the time the event was first read by the * consumer. * * The returned sequence number is never 0 unless the operation failed. * Loading @@ -371,7 +374,8 @@ public: * Returns DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled); status_t receiveFinishedSignal( const std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)>& callback); private: std::shared_ptr<InputChannel> mChannel; Loading Loading @@ -577,6 +581,13 @@ private: }; std::vector<SeqChain> mSeqChains; // The time at which each event with the sequence number 'seq' was consumed. // This data is provided in 'finishInputEvent' so that the receiving end can measure the latency // This collection is populated when the event is received, and the entries are erased when the // events are finished. It should not grow infinitely because if an event is not ack'd, ANR // will be raised for that connection, and no further events will be posted to that channel. std::unordered_map<uint32_t /*seq*/, nsecs_t /*consumeTime*/> mConsumeTimes; status_t consumeBatch(InputEventFactoryInterface* factory, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent); status_t consumeSamples(InputEventFactoryInterface* factory, Loading @@ -589,6 +600,8 @@ private: ssize_t findBatch(int32_t deviceId, int32_t source) const; ssize_t findTouchState(int32_t deviceId, int32_t source) const; nsecs_t getConsumeTime(uint32_t seq) const; void popConsumeTime(uint32_t seq); status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled); static void rewriteMessage(TouchState& state, InputMessage& msg); Loading libs/input/InputTransport.cpp +40 −8 Original line number Diff line number Diff line Loading @@ -234,6 +234,7 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const { } case InputMessage::Type::FINISHED: { msg->body.finished.handled = body.finished.handled; msg->body.finished.consumeTime = body.finished.consumeTime; break; } case InputMessage::Type::FOCUS: { Loading Loading @@ -597,7 +598,8 @@ status_t InputPublisher::publishCaptureEvent(uint32_t seq, int32_t eventId, return mChannel->sendMessage(&msg); } status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) { status_t InputPublisher::receiveFinishedSignal( const std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)>& callback) { if (DEBUG_TRANSPORT_ACTIONS) { ALOGD("channel '%s' publisher ~ receiveFinishedSignal", mChannel->getName().c_str()); } Loading @@ -605,8 +607,6 @@ status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandle InputMessage msg; status_t result = mChannel->receiveMessage(&msg); if (result) { *outSeq = 0; *outHandled = false; return result; } if (msg.header.type != InputMessage::Type::FINISHED) { Loading @@ -614,8 +614,7 @@ status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandle mChannel->getName().c_str(), msg.header.type); return UNKNOWN_ERROR; } *outSeq = msg.header.seq; *outHandled = msg.body.finished.handled == 1; callback(msg.header.seq, msg.body.finished.handled == 1, msg.body.finished.consumeTime); return OK; } Loading Loading @@ -651,6 +650,9 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consum } else { // Receive a fresh message. status_t result = mChannel->receiveMessage(&mMsg); if (result == OK) { mConsumeTimes.emplace(mMsg.header.seq, systemTime(SYSTEM_TIME_MONOTONIC)); } if (result) { // Consume the next batched event unless batches are being held for later. if (consumeBatches || result != WOULD_BLOCK) { Loading Loading @@ -1147,12 +1149,33 @@ status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { return sendUnchainedFinishedSignal(seq, handled); } nsecs_t InputConsumer::getConsumeTime(uint32_t seq) const { auto it = mConsumeTimes.find(seq); // Consume time will be missing if either 'finishInputEvent' is called twice, or if it was // called for the wrong (synthetic?) input event. Either way, it is a bug that should be fixed. LOG_ALWAYS_FATAL_IF(it == mConsumeTimes.end(), "Could not find consume time for seq=%" PRIu32, seq); return it->second; } void InputConsumer::popConsumeTime(uint32_t seq) { mConsumeTimes.erase(seq); } status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) { InputMessage msg; msg.header.type = InputMessage::Type::FINISHED; msg.header.seq = seq; msg.body.finished.handled = handled ? 1 : 0; return mChannel->sendMessage(&msg); msg.body.finished.consumeTime = getConsumeTime(seq); status_t result = mChannel->sendMessage(&msg); if (result == OK) { // Remove the consume time if the socket write succeeded. We will not need to ack this // message anymore. If the socket write did not succeed, we will try again and will still // need consume time. popConsumeTime(seq); } return result; } bool InputConsumer::hasDeferredEvent() const { Loading Loading @@ -1304,8 +1327,9 @@ std::string InputConsumer::dump() const { break; } case InputMessage::Type::FINISHED: { out += android::base::StringPrintf("handled=%s", toString(msg.body.finished.handled)); out += android::base::StringPrintf("handled=%s, consumeTime=%" PRId64, toString(msg.body.finished.handled), msg.body.finished.consumeTime); break; } case InputMessage::Type::FOCUS: { Loading Loading @@ -1335,6 +1359,14 @@ std::string InputConsumer::dump() const { if (mSeqChains.empty()) { out += " <empty>\n"; } out += "mConsumeTimes:\n"; for (const auto& [seq, consumeTime] : mConsumeTimes) { out += android::base::StringPrintf(" seq = %" PRIu32 " consumeTime = %" PRId64, seq, consumeTime); } if (mConsumeTimes.empty()) { out += " <empty>\n"; } return out; } Loading libs/input/tests/InputPublisherAndConsumer_test.cpp +44 −4 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() { constexpr int32_t repeatCount = 1; constexpr nsecs_t downTime = 3; constexpr nsecs_t eventTime = 4; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); status = mPublisher->publishKeyEvent(seq, eventId, deviceId, source, displayId, hmac, action, flags, keyCode, scanCode, metaState, repeatCount, downTime, Loading Loading @@ -122,13 +123,22 @@ void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() { uint32_t finishedSeq = 0; bool handled = false; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_TRUE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { Loading Loading @@ -160,6 +170,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { constexpr nsecs_t downTime = 3; constexpr size_t pointerCount = 3; constexpr nsecs_t eventTime = 4; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); PointerProperties pointerProperties[pointerCount]; PointerCoords pointerCoords[pointerCount]; for (size_t i = 0; i < pointerCount; i++) { Loading Loading @@ -262,13 +273,22 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { uint32_t finishedSeq = 0; bool handled = true; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_FALSE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } void InputPublisherAndConsumerTest::PublishAndConsumeFocusEvent() { Loading @@ -278,6 +298,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeFocusEvent() { int32_t eventId = InputEvent::nextId(); constexpr bool hasFocus = true; constexpr bool inTouchMode = true; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); status = mPublisher->publishFocusEvent(seq, eventId, hasFocus, inTouchMode); ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK"; Loading @@ -302,12 +323,21 @@ void InputPublisherAndConsumerTest::PublishAndConsumeFocusEvent() { uint32_t finishedSeq = 0; bool handled = false; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_TRUE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } void InputPublisherAndConsumerTest::PublishAndConsumeCaptureEvent() { Loading @@ -316,6 +346,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeCaptureEvent() { constexpr uint32_t seq = 42; int32_t eventId = InputEvent::nextId(); constexpr bool captureEnabled = true; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); status = mPublisher->publishCaptureEvent(seq, eventId, captureEnabled); ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK"; Loading @@ -339,12 +370,21 @@ void InputPublisherAndConsumerTest::PublishAndConsumeCaptureEvent() { uint32_t finishedSeq = 0; bool handled = false; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_TRUE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) { Loading libs/input/tests/StructLayout_test.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ void TestInputMessageAlignment() { CHECK_OFFSET(InputMessage::Body::Capture, pointerCaptureEnabled, 4); CHECK_OFFSET(InputMessage::Body::Finished, handled, 4); CHECK_OFFSET(InputMessage::Body::Finished, consumeTime, 8); } void TestHeaderSize() { Loading @@ -100,7 +101,7 @@ void TestBodySize() { static_assert(sizeof(InputMessage::Body::Motion) == offsetof(InputMessage::Body::Motion, pointers) + sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS); static_assert(sizeof(InputMessage::Body::Finished) == 8); static_assert(sizeof(InputMessage::Body::Finished) == 16); static_assert(sizeof(InputMessage::Body::Focus) == 8); static_assert(sizeof(InputMessage::Body::Capture) == 8); } Loading services/inputflinger/dispatcher/Entry.h +1 −0 Original line number Diff line number Diff line Loading @@ -272,6 +272,7 @@ struct CommandEntry { std::string obscuringPackage; bool enabled; int32_t pid; nsecs_t consumeTime; // time when the event was consumed by InputConsumer }; } // namespace android::inputdispatcher Loading Loading
include/input/InputTransport.h +15 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ */ #include <string> #include <unordered_map> #include <android-base/chrono_utils.h> Loading Loading @@ -155,6 +156,7 @@ struct InputMessage { struct Finished { uint32_t empty1; uint32_t handled; // actually a bool, but we must maintain 8-byte alignment nsecs_t consumeTime; // The time when the event was consumed by the receiving end inline size_t size() const { return sizeof(Finished); } } finished; Loading Loading @@ -362,7 +364,8 @@ public: /* Receives the finished signal from the consumer in reply to the original dispatch signal. * If a signal was received, returns the message sequence number, * and whether the consumer handled the message. * whether the consumer handled the message, and the time the event was first read by the * consumer. * * The returned sequence number is never 0 unless the operation failed. * Loading @@ -371,7 +374,8 @@ public: * Returns DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled); status_t receiveFinishedSignal( const std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)>& callback); private: std::shared_ptr<InputChannel> mChannel; Loading Loading @@ -577,6 +581,13 @@ private: }; std::vector<SeqChain> mSeqChains; // The time at which each event with the sequence number 'seq' was consumed. // This data is provided in 'finishInputEvent' so that the receiving end can measure the latency // This collection is populated when the event is received, and the entries are erased when the // events are finished. It should not grow infinitely because if an event is not ack'd, ANR // will be raised for that connection, and no further events will be posted to that channel. std::unordered_map<uint32_t /*seq*/, nsecs_t /*consumeTime*/> mConsumeTimes; status_t consumeBatch(InputEventFactoryInterface* factory, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent); status_t consumeSamples(InputEventFactoryInterface* factory, Loading @@ -589,6 +600,8 @@ private: ssize_t findBatch(int32_t deviceId, int32_t source) const; ssize_t findTouchState(int32_t deviceId, int32_t source) const; nsecs_t getConsumeTime(uint32_t seq) const; void popConsumeTime(uint32_t seq); status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled); static void rewriteMessage(TouchState& state, InputMessage& msg); Loading
libs/input/InputTransport.cpp +40 −8 Original line number Diff line number Diff line Loading @@ -234,6 +234,7 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const { } case InputMessage::Type::FINISHED: { msg->body.finished.handled = body.finished.handled; msg->body.finished.consumeTime = body.finished.consumeTime; break; } case InputMessage::Type::FOCUS: { Loading Loading @@ -597,7 +598,8 @@ status_t InputPublisher::publishCaptureEvent(uint32_t seq, int32_t eventId, return mChannel->sendMessage(&msg); } status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) { status_t InputPublisher::receiveFinishedSignal( const std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)>& callback) { if (DEBUG_TRANSPORT_ACTIONS) { ALOGD("channel '%s' publisher ~ receiveFinishedSignal", mChannel->getName().c_str()); } Loading @@ -605,8 +607,6 @@ status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandle InputMessage msg; status_t result = mChannel->receiveMessage(&msg); if (result) { *outSeq = 0; *outHandled = false; return result; } if (msg.header.type != InputMessage::Type::FINISHED) { Loading @@ -614,8 +614,7 @@ status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandle mChannel->getName().c_str(), msg.header.type); return UNKNOWN_ERROR; } *outSeq = msg.header.seq; *outHandled = msg.body.finished.handled == 1; callback(msg.header.seq, msg.body.finished.handled == 1, msg.body.finished.consumeTime); return OK; } Loading Loading @@ -651,6 +650,9 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consum } else { // Receive a fresh message. status_t result = mChannel->receiveMessage(&mMsg); if (result == OK) { mConsumeTimes.emplace(mMsg.header.seq, systemTime(SYSTEM_TIME_MONOTONIC)); } if (result) { // Consume the next batched event unless batches are being held for later. if (consumeBatches || result != WOULD_BLOCK) { Loading Loading @@ -1147,12 +1149,33 @@ status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { return sendUnchainedFinishedSignal(seq, handled); } nsecs_t InputConsumer::getConsumeTime(uint32_t seq) const { auto it = mConsumeTimes.find(seq); // Consume time will be missing if either 'finishInputEvent' is called twice, or if it was // called for the wrong (synthetic?) input event. Either way, it is a bug that should be fixed. LOG_ALWAYS_FATAL_IF(it == mConsumeTimes.end(), "Could not find consume time for seq=%" PRIu32, seq); return it->second; } void InputConsumer::popConsumeTime(uint32_t seq) { mConsumeTimes.erase(seq); } status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) { InputMessage msg; msg.header.type = InputMessage::Type::FINISHED; msg.header.seq = seq; msg.body.finished.handled = handled ? 1 : 0; return mChannel->sendMessage(&msg); msg.body.finished.consumeTime = getConsumeTime(seq); status_t result = mChannel->sendMessage(&msg); if (result == OK) { // Remove the consume time if the socket write succeeded. We will not need to ack this // message anymore. If the socket write did not succeed, we will try again and will still // need consume time. popConsumeTime(seq); } return result; } bool InputConsumer::hasDeferredEvent() const { Loading Loading @@ -1304,8 +1327,9 @@ std::string InputConsumer::dump() const { break; } case InputMessage::Type::FINISHED: { out += android::base::StringPrintf("handled=%s", toString(msg.body.finished.handled)); out += android::base::StringPrintf("handled=%s, consumeTime=%" PRId64, toString(msg.body.finished.handled), msg.body.finished.consumeTime); break; } case InputMessage::Type::FOCUS: { Loading Loading @@ -1335,6 +1359,14 @@ std::string InputConsumer::dump() const { if (mSeqChains.empty()) { out += " <empty>\n"; } out += "mConsumeTimes:\n"; for (const auto& [seq, consumeTime] : mConsumeTimes) { out += android::base::StringPrintf(" seq = %" PRIu32 " consumeTime = %" PRId64, seq, consumeTime); } if (mConsumeTimes.empty()) { out += " <empty>\n"; } return out; } Loading
libs/input/tests/InputPublisherAndConsumer_test.cpp +44 −4 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() { constexpr int32_t repeatCount = 1; constexpr nsecs_t downTime = 3; constexpr nsecs_t eventTime = 4; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); status = mPublisher->publishKeyEvent(seq, eventId, deviceId, source, displayId, hmac, action, flags, keyCode, scanCode, metaState, repeatCount, downTime, Loading Loading @@ -122,13 +123,22 @@ void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() { uint32_t finishedSeq = 0; bool handled = false; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_TRUE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { Loading Loading @@ -160,6 +170,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { constexpr nsecs_t downTime = 3; constexpr size_t pointerCount = 3; constexpr nsecs_t eventTime = 4; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); PointerProperties pointerProperties[pointerCount]; PointerCoords pointerCoords[pointerCount]; for (size_t i = 0; i < pointerCount; i++) { Loading Loading @@ -262,13 +273,22 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { uint32_t finishedSeq = 0; bool handled = true; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_FALSE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } void InputPublisherAndConsumerTest::PublishAndConsumeFocusEvent() { Loading @@ -278,6 +298,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeFocusEvent() { int32_t eventId = InputEvent::nextId(); constexpr bool hasFocus = true; constexpr bool inTouchMode = true; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); status = mPublisher->publishFocusEvent(seq, eventId, hasFocus, inTouchMode); ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK"; Loading @@ -302,12 +323,21 @@ void InputPublisherAndConsumerTest::PublishAndConsumeFocusEvent() { uint32_t finishedSeq = 0; bool handled = false; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_TRUE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } void InputPublisherAndConsumerTest::PublishAndConsumeCaptureEvent() { Loading @@ -316,6 +346,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeCaptureEvent() { constexpr uint32_t seq = 42; int32_t eventId = InputEvent::nextId(); constexpr bool captureEnabled = true; const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); status = mPublisher->publishCaptureEvent(seq, eventId, captureEnabled); ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK"; Loading @@ -339,12 +370,21 @@ void InputPublisherAndConsumerTest::PublishAndConsumeCaptureEvent() { uint32_t finishedSeq = 0; bool handled = false; status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled); nsecs_t consumeTime; status = mPublisher->receiveFinishedSignal( [&finishedSeq, &handled, &consumeTime](uint32_t inSeq, bool inHandled, nsecs_t inConsumeTime) -> void { finishedSeq = inSeq; handled = inHandled; consumeTime = inConsumeTime; }); ASSERT_EQ(OK, status) << "publisher receiveFinishedSignal should return OK"; ASSERT_EQ(seq, finishedSeq) << "publisher receiveFinishedSignal should have returned the original sequence number"; ASSERT_TRUE(handled) << "publisher receiveFinishedSignal should have set handled to consumer's reply"; ASSERT_GE(consumeTime, publishTime) << "finished signal's consume time should be greater than publish time"; } TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) { Loading
libs/input/tests/StructLayout_test.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ void TestInputMessageAlignment() { CHECK_OFFSET(InputMessage::Body::Capture, pointerCaptureEnabled, 4); CHECK_OFFSET(InputMessage::Body::Finished, handled, 4); CHECK_OFFSET(InputMessage::Body::Finished, consumeTime, 8); } void TestHeaderSize() { Loading @@ -100,7 +101,7 @@ void TestBodySize() { static_assert(sizeof(InputMessage::Body::Motion) == offsetof(InputMessage::Body::Motion, pointers) + sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS); static_assert(sizeof(InputMessage::Body::Finished) == 8); static_assert(sizeof(InputMessage::Body::Finished) == 16); static_assert(sizeof(InputMessage::Body::Focus) == 8); static_assert(sizeof(InputMessage::Body::Capture) == 8); } Loading
services/inputflinger/dispatcher/Entry.h +1 −0 Original line number Diff line number Diff line Loading @@ -272,6 +272,7 @@ struct CommandEntry { std::string obscuringPackage; bool enabled; int32_t pid; nsecs_t consumeTime; // time when the event was consumed by InputConsumer }; } // namespace android::inputdispatcher Loading