Loading libs/input/InputConsumerNoResampling.cpp +15 −0 Original line number Original line Diff line number Diff line Loading @@ -169,6 +169,12 @@ InputMessage createTimelineMessage(int32_t inputEventId, nsecs_t gpuCompletedTim msg.body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = presentTime; msg.body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = presentTime; return msg; return msg; } } std::ostream& operator<<(std::ostream& out, const InputMessage& msg) { out << ftl::enum_string(msg.header.type); return out; } } // namespace } // namespace // --- InputConsumerNoResampling --- // --- InputConsumerNoResampling --- Loading Loading @@ -272,6 +278,15 @@ void InputConsumerNoResampling::processOutboundEvents() { return; // try again later return; // try again later } } if (result == DEAD_OBJECT) { // If there's no one to receive events in the channel, there's no point in sending them. // Drop all outbound events. LOG(INFO) << "Channel " << mChannel->getName() << " died. Dropping outbound event " << outboundMsg; mOutboundQueue.pop(); setFdEvents(0); continue; } // Some other error. Give up // Some other error. Give up LOG(FATAL) << "Failed to send outbound event on channel '" << mChannel->getName() LOG(FATAL) << "Failed to send outbound event on channel '" << mChannel->getName() << "'. status=" << statusToString(result) << "(" << result << ")"; << "'. status=" << statusToString(result) << "(" << result << ")"; Loading libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp +33 −15 Original line number Original line Diff line number Diff line Loading @@ -319,6 +319,8 @@ protected: protected: protected: // Interaction with the looper thread // Interaction with the looper thread void blockLooper(); void unblockLooper(); enum class LooperMessage : int { enum class LooperMessage : int { CALL_PROBABLY_HAS_INPUT, CALL_PROBABLY_HAS_INPUT, CREATE_CONSUMER, CREATE_CONSUMER, Loading Loading @@ -389,6 +391,26 @@ private: }; }; }; }; void InputPublisherAndConsumerNoResamplingTest::blockLooper() { { std::scoped_lock l(mLock); mLooperMayProceed = false; } sendMessage(LooperMessage::BLOCK_LOOPER); { std::unique_lock l(mLock); mNotifyLooperWaiting.wait(l, [this] { return mLooperIsBlocked; }); } } void InputPublisherAndConsumerNoResamplingTest::unblockLooper() { { std::scoped_lock l(mLock); mLooperMayProceed = true; } mNotifyLooperMayProceed.notify_all(); } void InputPublisherAndConsumerNoResamplingTest::sendMessage(LooperMessage message) { void InputPublisherAndConsumerNoResamplingTest::sendMessage(LooperMessage message) { Message msg{ftl::to_underlying(message)}; Message msg{ftl::to_underlying(message)}; mLooper->sendMessage(mMessageHandler, msg); mLooper->sendMessage(mMessageHandler, msg); Loading Loading @@ -600,15 +622,7 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeSinglePointerMu std::queue<uint32_t> publishedSequenceNumbers; std::queue<uint32_t> publishedSequenceNumbers; // Block Looper to increase the chance of batching events // Block Looper to increase the chance of batching events { blockLooper(); std::scoped_lock l(mLock); mLooperMayProceed = false; } sendMessage(LooperMessage::BLOCK_LOOPER); { std::unique_lock l(mLock); mNotifyLooperWaiting.wait(l, [this] { return mLooperIsBlocked; }); } uint32_t firstSampleId; uint32_t firstSampleId; for (size_t i = 0; i < nSamples; ++i) { for (size_t i = 0; i < nSamples; ++i) { Loading @@ -629,12 +643,7 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeSinglePointerMu std::vector<MotionEvent> singleSampledMotionEvents; std::vector<MotionEvent> singleSampledMotionEvents; // Unblock Looper unblockLooper(); { std::scoped_lock l(mLock); mLooperMayProceed = true; } mNotifyLooperMayProceed.notify_all(); // We have no control over the socket behavior, so the consumer can receive // We have no control over the socket behavior, so the consumer can receive // the motion as a batched event, or as a sequence of multiple single-sample MotionEvents (or a // the motion as a batched event, or as a sequence of multiple single-sample MotionEvents (or a Loading Loading @@ -809,6 +818,15 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeTouchModeEvent( verifyFinishedSignal(*mPublisher, seq, publishTime); verifyFinishedSignal(*mPublisher, seq, publishTime); } } /** * If the publisher has died, consumer should not crash when trying to send an outgoing message. */ TEST_F(InputPublisherAndConsumerNoResamplingTest, ConsumerWritesAfterPublisherDies) { mPublisher.reset(); // The publisher has died mReportTimelineArgs.emplace(/*inputEventId=*/10, /*gpuCompletedTime=*/20, /*presentTime=*/30); sendMessage(LooperMessage::CALL_REPORT_TIMELINE); } TEST_F(InputPublisherAndConsumerNoResamplingTest, SendTimeline) { TEST_F(InputPublisherAndConsumerNoResamplingTest, SendTimeline) { const int32_t inputEventId = 20; const int32_t inputEventId = 20; const nsecs_t gpuCompletedTime = 30; const nsecs_t gpuCompletedTime = 30; Loading Loading
libs/input/InputConsumerNoResampling.cpp +15 −0 Original line number Original line Diff line number Diff line Loading @@ -169,6 +169,12 @@ InputMessage createTimelineMessage(int32_t inputEventId, nsecs_t gpuCompletedTim msg.body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = presentTime; msg.body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = presentTime; return msg; return msg; } } std::ostream& operator<<(std::ostream& out, const InputMessage& msg) { out << ftl::enum_string(msg.header.type); return out; } } // namespace } // namespace // --- InputConsumerNoResampling --- // --- InputConsumerNoResampling --- Loading Loading @@ -272,6 +278,15 @@ void InputConsumerNoResampling::processOutboundEvents() { return; // try again later return; // try again later } } if (result == DEAD_OBJECT) { // If there's no one to receive events in the channel, there's no point in sending them. // Drop all outbound events. LOG(INFO) << "Channel " << mChannel->getName() << " died. Dropping outbound event " << outboundMsg; mOutboundQueue.pop(); setFdEvents(0); continue; } // Some other error. Give up // Some other error. Give up LOG(FATAL) << "Failed to send outbound event on channel '" << mChannel->getName() LOG(FATAL) << "Failed to send outbound event on channel '" << mChannel->getName() << "'. status=" << statusToString(result) << "(" << result << ")"; << "'. status=" << statusToString(result) << "(" << result << ")"; Loading
libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp +33 −15 Original line number Original line Diff line number Diff line Loading @@ -319,6 +319,8 @@ protected: protected: protected: // Interaction with the looper thread // Interaction with the looper thread void blockLooper(); void unblockLooper(); enum class LooperMessage : int { enum class LooperMessage : int { CALL_PROBABLY_HAS_INPUT, CALL_PROBABLY_HAS_INPUT, CREATE_CONSUMER, CREATE_CONSUMER, Loading Loading @@ -389,6 +391,26 @@ private: }; }; }; }; void InputPublisherAndConsumerNoResamplingTest::blockLooper() { { std::scoped_lock l(mLock); mLooperMayProceed = false; } sendMessage(LooperMessage::BLOCK_LOOPER); { std::unique_lock l(mLock); mNotifyLooperWaiting.wait(l, [this] { return mLooperIsBlocked; }); } } void InputPublisherAndConsumerNoResamplingTest::unblockLooper() { { std::scoped_lock l(mLock); mLooperMayProceed = true; } mNotifyLooperMayProceed.notify_all(); } void InputPublisherAndConsumerNoResamplingTest::sendMessage(LooperMessage message) { void InputPublisherAndConsumerNoResamplingTest::sendMessage(LooperMessage message) { Message msg{ftl::to_underlying(message)}; Message msg{ftl::to_underlying(message)}; mLooper->sendMessage(mMessageHandler, msg); mLooper->sendMessage(mMessageHandler, msg); Loading Loading @@ -600,15 +622,7 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeSinglePointerMu std::queue<uint32_t> publishedSequenceNumbers; std::queue<uint32_t> publishedSequenceNumbers; // Block Looper to increase the chance of batching events // Block Looper to increase the chance of batching events { blockLooper(); std::scoped_lock l(mLock); mLooperMayProceed = false; } sendMessage(LooperMessage::BLOCK_LOOPER); { std::unique_lock l(mLock); mNotifyLooperWaiting.wait(l, [this] { return mLooperIsBlocked; }); } uint32_t firstSampleId; uint32_t firstSampleId; for (size_t i = 0; i < nSamples; ++i) { for (size_t i = 0; i < nSamples; ++i) { Loading @@ -629,12 +643,7 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeSinglePointerMu std::vector<MotionEvent> singleSampledMotionEvents; std::vector<MotionEvent> singleSampledMotionEvents; // Unblock Looper unblockLooper(); { std::scoped_lock l(mLock); mLooperMayProceed = true; } mNotifyLooperMayProceed.notify_all(); // We have no control over the socket behavior, so the consumer can receive // We have no control over the socket behavior, so the consumer can receive // the motion as a batched event, or as a sequence of multiple single-sample MotionEvents (or a // the motion as a batched event, or as a sequence of multiple single-sample MotionEvents (or a Loading Loading @@ -809,6 +818,15 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeTouchModeEvent( verifyFinishedSignal(*mPublisher, seq, publishTime); verifyFinishedSignal(*mPublisher, seq, publishTime); } } /** * If the publisher has died, consumer should not crash when trying to send an outgoing message. */ TEST_F(InputPublisherAndConsumerNoResamplingTest, ConsumerWritesAfterPublisherDies) { mPublisher.reset(); // The publisher has died mReportTimelineArgs.emplace(/*inputEventId=*/10, /*gpuCompletedTime=*/20, /*presentTime=*/30); sendMessage(LooperMessage::CALL_REPORT_TIMELINE); } TEST_F(InputPublisherAndConsumerNoResamplingTest, SendTimeline) { TEST_F(InputPublisherAndConsumerNoResamplingTest, SendTimeline) { const int32_t inputEventId = 20; const int32_t inputEventId = 20; const nsecs_t gpuCompletedTime = 30; const nsecs_t gpuCompletedTime = 30; Loading