@@ -319,6 +319,8 @@ class InputPublisherAndConsumerNoResamplingTest : public testing::Test,
319319
320320protected:
321321 // Interaction with the looper thread
322+ void blockLooper ();
323+ void unblockLooper ();
322324 enum class LooperMessage : int {
323325 CALL_PROBABLY_HAS_INPUT,
324326 CREATE_CONSUMER,
@@ -389,6 +391,26 @@ class InputPublisherAndConsumerNoResamplingTest : public testing::Test,
389391 };
390392};
391393
394+ void InputPublisherAndConsumerNoResamplingTest::blockLooper () {
395+ {
396+ std::scoped_lock l (mLock );
397+ mLooperMayProceed = false ;
398+ }
399+ sendMessage (LooperMessage::BLOCK_LOOPER);
400+ {
401+ std::unique_lock l (mLock );
402+ mNotifyLooperWaiting .wait (l, [this ] { return mLooperIsBlocked ; });
403+ }
404+ }
405+
406+ void InputPublisherAndConsumerNoResamplingTest::unblockLooper () {
407+ {
408+ std::scoped_lock l (mLock );
409+ mLooperMayProceed = true ;
410+ }
411+ mNotifyLooperMayProceed .notify_all ();
412+ }
413+
392414void InputPublisherAndConsumerNoResamplingTest::sendMessage (LooperMessage message) {
393415 Message msg{ftl::to_underlying (message)};
394416 mLooper ->sendMessage (mMessageHandler , msg);
@@ -600,15 +622,7 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeSinglePointerMu
600622 std::queue<uint32_t > publishedSequenceNumbers;
601623
602624 // Block Looper to increase the chance of batching events
603- {
604- std::scoped_lock l (mLock );
605- mLooperMayProceed = false ;
606- }
607- sendMessage (LooperMessage::BLOCK_LOOPER);
608- {
609- std::unique_lock l (mLock );
610- mNotifyLooperWaiting .wait (l, [this ] { return mLooperIsBlocked ; });
611- }
625+ blockLooper ();
612626
613627 uint32_t firstSampleId;
614628 for (size_t i = 0 ; i < nSamples; ++i) {
@@ -629,12 +643,7 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeSinglePointerMu
629643
630644 std::vector<MotionEvent> singleSampledMotionEvents;
631645
632- // Unblock Looper
633- {
634- std::scoped_lock l (mLock );
635- mLooperMayProceed = true ;
636- }
637- mNotifyLooperMayProceed .notify_all ();
646+ unblockLooper ();
638647
639648 // We have no control over the socket behavior, so the consumer can receive
640649 // the motion as a batched event, or as a sequence of multiple single-sample MotionEvents (or a
@@ -809,6 +818,15 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeTouchModeEvent(
809818 verifyFinishedSignal (*mPublisher , seq, publishTime);
810819}
811820
821+ /* *
822+ * If the publisher has died, consumer should not crash when trying to send an outgoing message.
823+ */
824+ TEST_F (InputPublisherAndConsumerNoResamplingTest, ConsumerWritesAfterPublisherDies) {
825+ mPublisher .reset (); // The publisher has died
826+ mReportTimelineArgs .emplace (/* inputEventId=*/ 10 , /* gpuCompletedTime=*/ 20 , /* presentTime=*/ 30 );
827+ sendMessage (LooperMessage::CALL_REPORT_TIMELINE);
828+ }
829+
812830TEST_F (InputPublisherAndConsumerNoResamplingTest, SendTimeline) {
813831 const int32_t inputEventId = 20 ;
814832 const nsecs_t gpuCompletedTime = 30 ;
0 commit comments