Add lock to protect UnwantedInteractionBlocker
The call to 'dump' may come from any thread, and therefore could cause a
crash. Add a lock to protect this input stage.
To run the test:
adb shell -t "/data/nativetest64/inputflinger_tests/inputflinger_tests --gtest_filter='*Dump*' --gtest_repeat=100000 --gtest_break_on_failure"
Before this patch, the test failed after ~5K - ~13K iterations (took
10-20 seconds to crash).
Bug: 232645962
Test: m inputflinger_tests && adb sync data && <run the test>
Change-Id: I2a199690450bc5bb4a8576aa59075e99d37a531b
diff --git a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
index e378096..0062f42 100644
--- a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
+++ b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
#include <gui/constants.h>
#include <linux/input.h>
+#include <thread>
#include "TestInputListener.h"
@@ -547,6 +548,27 @@
mBlocker->notifyMotion(&args);
}
+/**
+ * Call dump, and on another thread, try to send some motions. The blocker should
+ * not crash. On 2022 hardware, this test requires ~ 13K executions (about 20 seconds) to reproduce
+ * the original bug. This is meant to be run with "--gtest_repeat=100000 --gtest_break_on_failure"
+ * options
+ */
+TEST_F(UnwantedInteractionBlockerTest, DumpCanBeAccessedOnAnotherThread) {
+ mBlocker->notifyInputDevicesChanged({generateTestDeviceInfo()});
+ NotifyMotionArgs args1 = generateMotionArgs(0 /*downTime*/, 0 /*eventTime*/, DOWN, {{1, 2, 3}});
+ mBlocker->notifyMotion(&args1);
+ std::thread dumpThread([this]() {
+ std::string dump;
+ mBlocker->dump(dump);
+ });
+ NotifyMotionArgs args2 = generateMotionArgs(0 /*downTime*/, 1 /*eventTime*/, MOVE, {{4, 5, 6}});
+ mBlocker->notifyMotion(&args2);
+ NotifyMotionArgs args3 = generateMotionArgs(0 /*downTime*/, 2 /*eventTime*/, UP, {{4, 5, 6}});
+ mBlocker->notifyMotion(&args3);
+ dumpThread.join();
+}
+
using UnwantedInteractionBlockerTestDeathTest = UnwantedInteractionBlockerTest;
/**