Make InputReader test components thread safe
This changes all assert*() methods in the following classes to enable
waiting for the assertion to be true:
- FakeInputReaderPolicy
- FakeEventHub
- FakeInputMapper
- TestInputListener
This change should make InputReader robust to being run on another
thread.
Bug: 130819454
Test: atest inputflinger_tests # on crosshatch
Change-Id: I9619109e3377eb706d71fb34d525bd3bdc4ef81a
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index c4f8626..ada2266 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -15,6 +15,7 @@
"-Werror",
"-Wextra",
"-Wno-unused-parameter",
+ "-Wthread-safety",
],
shared_libs: [
"android.hardware.input.classifier@1.0",
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 31b1652..2b3257d 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -25,13 +25,18 @@
#include <TestInputListener.h>
#include <TouchInputMapper.h>
+#include <android-base/thread_annotations.h>
#include <gtest/gtest.h>
#include <inttypes.h>
#include <math.h>
-
namespace android {
+using std::chrono_literals::operator""ms;
+
+// Timeout for waiting for an expected event
+static constexpr std::chrono::duration WAIT_TIMEOUT = 100ms;
+
// An arbitrary time value.
static const nsecs_t ARBITRARY_TIME = 1234;
@@ -164,9 +169,13 @@
// --- FakeInputReaderPolicy ---
class FakeInputReaderPolicy : public InputReaderPolicyInterface {
+ std::mutex mLock;
+ std::condition_variable mDevicesChangedCondition;
+
InputReaderConfiguration mConfig;
KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
- std::vector<InputDeviceInfo> mInputDevices;
+ std::vector<InputDeviceInfo> mInputDevices GUARDED_BY(mLock);
+ bool mInputDevicesChanged GUARDED_BY(mLock){false};
std::vector<DisplayViewport> mViewports;
TouchAffineTransformation transform;
@@ -177,6 +186,20 @@
FakeInputReaderPolicy() {
}
+ void assertInputDevicesChanged() {
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+
+ const bool devicesChanged =
+ mDevicesChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
+ return mInputDevicesChanged;
+ });
+ if (!devicesChanged) {
+ FAIL() << "Timed out waiting for notifyInputDevicesChanged() to be called.";
+ }
+ mInputDevicesChanged = false;
+ }
+
virtual void clearViewports() {
mViewports.clear();
mConfig.setDisplayViewports(mViewports);
@@ -291,7 +314,10 @@
}
virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
+ std::scoped_lock<std::mutex> lock(mLock);
mInputDevices = inputDevices;
+ mInputDevicesChanged = true;
+ mDevicesChangedCondition.notify_all();
}
virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier&) {
@@ -342,9 +368,12 @@
}
};
+ std::mutex mLock;
+ std::condition_variable mEventsCondition;
+
KeyedVector<int32_t, Device*> mDevices;
std::vector<std::string> mExcludedDevices;
- List<RawEvent> mEvents;
+ List<RawEvent> mEvents GUARDED_BY(mLock);
std::unordered_map<int32_t /*deviceId*/, std::vector<TouchVideoFrame>> mVideoFrames;
public:
@@ -496,6 +525,7 @@
void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
int32_t code, int32_t value) {
+ std::scoped_lock<std::mutex> lock(mLock);
RawEvent event;
event.when = when;
event.deviceId = deviceId;
@@ -515,8 +545,14 @@
}
void assertQueueIsEmpty() {
- ASSERT_EQ(size_t(0), mEvents.size())
- << "Expected the event queue to be empty (fully consumed).";
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+ const bool queueIsEmpty =
+ mEventsCondition.wait_for(lock, WAIT_TIMEOUT,
+ [this]() REQUIRES(mLock) { return mEvents.size() == 0; });
+ if (!queueIsEmpty) {
+ FAIL() << "Timed out waiting for EventHub queue to be emptied.";
+ }
}
private:
@@ -619,12 +655,14 @@
}
virtual size_t getEvents(int, RawEvent* buffer, size_t) {
+ std::scoped_lock<std::mutex> lock(mLock);
if (mEvents.empty()) {
return 0;
}
*buffer = *mEvents.begin();
mEvents.erase(mEvents.begin());
+ mEventsCondition.notify_all();
return 1;
}
@@ -877,11 +915,13 @@
KeyedVector<int32_t, int32_t> mScanCodeStates;
KeyedVector<int32_t, int32_t> mSwitchStates;
std::vector<int32_t> mSupportedKeyCodes;
- RawEvent mLastEvent;
- bool mConfigureWasCalled;
- bool mResetWasCalled;
- bool mProcessWasCalled;
+ std::mutex mLock;
+ std::condition_variable mStateChangedCondition;
+ bool mConfigureWasCalled GUARDED_BY(mLock);
+ bool mResetWasCalled GUARDED_BY(mLock);
+ bool mProcessWasCalled GUARDED_BY(mLock);
+ RawEvent mLastEvent GUARDED_BY(mLock);
std::optional<DisplayViewport> mViewport;
public:
@@ -903,20 +943,41 @@
}
void assertConfigureWasCalled() {
- ASSERT_TRUE(mConfigureWasCalled)
- << "Expected configure() to have been called.";
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+ const bool configureCalled =
+ mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
+ return mConfigureWasCalled;
+ });
+ if (!configureCalled) {
+ FAIL() << "Expected configure() to have been called.";
+ }
mConfigureWasCalled = false;
}
void assertResetWasCalled() {
- ASSERT_TRUE(mResetWasCalled)
- << "Expected reset() to have been called.";
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+ const bool resetCalled =
+ mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
+ return mResetWasCalled;
+ });
+ if (!resetCalled) {
+ FAIL() << "Expected reset() to have been called.";
+ }
mResetWasCalled = false;
}
void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
- ASSERT_TRUE(mProcessWasCalled)
- << "Expected process() to have been called.";
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+ const bool processCalled =
+ mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
+ return mProcessWasCalled;
+ });
+ if (!processCalled) {
+ FAIL() << "Expected process() to have been called.";
+ }
if (outLastEvent) {
*outLastEvent = mLastEvent;
}
@@ -953,6 +1014,7 @@
}
virtual void configure(nsecs_t, const InputReaderConfiguration* config, uint32_t changes) {
+ std::scoped_lock<std::mutex> lock(mLock);
mConfigureWasCalled = true;
// Find the associated viewport if exist.
@@ -960,15 +1022,21 @@
if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
mViewport = config->getDisplayViewportByPort(*displayPort);
}
+
+ mStateChangedCondition.notify_all();
}
virtual void reset(nsecs_t) {
+ std::scoped_lock<std::mutex> lock(mLock);
mResetWasCalled = true;
+ mStateChangedCondition.notify_all();
}
virtual void process(const RawEvent* rawEvent) {
+ std::scoped_lock<std::mutex> lock(mLock);
mLastEvent = *rawEvent;
mProcessWasCalled = true;
+ mStateChangedCondition.notify_all();
}
virtual int32_t getKeyCodeState(uint32_t, int32_t keyCode) {
@@ -1033,23 +1101,22 @@
}
}
- void setNextDevice(InputDevice* device) {
- mNextDevice = device;
- }
+ void setNextDevice(InputDevice* device) { mNextDevice = device; }
InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const std::string& name,
- uint32_t classes, const std::string& location = "") {
+ uint32_t classes, const std::string& location = "") {
InputDeviceIdentifier identifier;
identifier.name = name;
identifier.location = location;
int32_t generation = deviceId + 1;
return new InputDevice(&mContext, deviceId, generation, controllerNumber, identifier,
- classes);
+ classes);
}
protected:
virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
- const InputDeviceIdentifier& identifier, uint32_t classes) {
+ const InputDeviceIdentifier& identifier,
+ uint32_t classes) {
if (mNextDevice) {
InputDevice* device = mNextDevice;
mNextDevice = nullptr;
@@ -1281,7 +1348,8 @@
mFakeEventHub->finishDeviceScan();
mReader->loopOnce();
mReader->loopOnce();
- mFakeEventHub->assertQueueIsEmpty();
+ ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
+ ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
}
void disableDevice(int32_t deviceId, InputDevice* device) {
@@ -1316,10 +1384,8 @@
ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored",
0, nullptr)); // no classes so device will be ignored
-
std::vector<InputDeviceInfo> inputDevices;
mReader->getInputDevices(inputDevices);
-
ASSERT_EQ(1U, inputDevices.size());
ASSERT_EQ(1, inputDevices[0].getId());
ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
@@ -1345,7 +1411,7 @@
FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD);
device->addMapper(mapper);
mReader->setNextDevice(device);
- addDevice(deviceId, "fake", deviceClass, nullptr);
+ ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
@@ -1358,20 +1424,20 @@
disableDevice(deviceId, device);
mReader->loopOnce();
- mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
ASSERT_EQ(deviceId, resetArgs.deviceId);
ASSERT_EQ(device->isEnabled(), false);
disableDevice(deviceId, device);
mReader->loopOnce();
- mFakeListener->assertNotifyDeviceResetWasNotCalled();
- mFakeListener->assertNotifyConfigurationChangedWasNotCalled();
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
ASSERT_EQ(device->isEnabled(), false);
enableDevice(deviceId, device);
mReader->loopOnce();
- mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
ASSERT_EQ(deviceId, resetArgs.deviceId);
ASSERT_EQ(device->isEnabled(), true);
@@ -1529,7 +1595,7 @@
FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD);
device->addMapper(mapper);
mReader->setNextDevice(device);
- addDevice(deviceId, "fake", deviceClass, nullptr);
+ ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
NotifyDeviceResetArgs resetArgs;
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
@@ -1537,19 +1603,19 @@
disableDevice(deviceId, device);
mReader->loopOnce();
- mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
ASSERT_TRUE(prevSequenceNum < resetArgs.sequenceNum);
prevSequenceNum = resetArgs.sequenceNum;
enableDevice(deviceId, device);
mReader->loopOnce();
- mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
ASSERT_TRUE(prevSequenceNum < resetArgs.sequenceNum);
prevSequenceNum = resetArgs.sequenceNum;
disableDevice(deviceId, device);
mReader->loopOnce();
- mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
ASSERT_TRUE(prevSequenceNum < resetArgs.sequenceNum);
prevSequenceNum = resetArgs.sequenceNum;
}
@@ -1577,6 +1643,7 @@
DISPLAY_ORIENTATION_0, "local:1", hdmi1, ViewportType::VIEWPORT_EXTERNAL);
mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
mReader->loopOnce();
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
// Device should only dispatch to the specified display.
ASSERT_EQ(deviceId, device->getId());
diff --git a/services/inputflinger/tests/TestInputListener.cpp b/services/inputflinger/tests/TestInputListener.cpp
index 3ee33f1..06b05ac 100644
--- a/services/inputflinger/tests/TestInputListener.cpp
+++ b/services/inputflinger/tests/TestInputListener.cpp
@@ -19,6 +19,15 @@
#include "TestInputListener.h"
+namespace {
+
+using std::chrono_literals::operator""ms;
+
+// Timeout for waiting for an expected event
+static constexpr std::chrono::duration WAIT_TIMEOUT = 5ms;
+
+} // namespace
+
namespace android {
// --- TestInputListener ---
@@ -29,87 +38,117 @@
void TestInputListener::assertNotifyConfigurationChangedWasCalled(
NotifyConfigurationChangedArgs* outEventArgs) {
- ASSERT_FALSE(mNotifyConfigurationChangedArgsQueue.empty())
- << "Expected notifyConfigurationChanged() to have been called.";
- if (outEventArgs) {
- *outEventArgs = *mNotifyConfigurationChangedArgsQueue.begin();
- }
- mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
+ ASSERT_NO_FATAL_FAILURE(
+ assertCalled<NotifyConfigurationChangedArgs>(outEventArgs,
+ "Expected notifyConfigurationChanged() "
+ "to have been called."));
}
void TestInputListener::assertNotifyConfigurationChangedWasNotCalled() {
- ASSERT_TRUE(mNotifyConfigurationChangedArgsQueue.empty())
- << "Expected notifyConfigurationChanged() to not have been called.";
+ ASSERT_NO_FATAL_FAILURE(assertNotCalled<NotifyConfigurationChangedArgs>(
+ "notifyConfigurationChanged() should not be called."));
}
void TestInputListener::assertNotifyDeviceResetWasCalled(
NotifyDeviceResetArgs* outEventArgs) {
- ASSERT_FALSE(mNotifyDeviceResetArgsQueue.empty())
- << "Expected notifyDeviceReset() to have been called.";
- if (outEventArgs) {
- *outEventArgs = *mNotifyDeviceResetArgsQueue.begin();
- }
- mNotifyDeviceResetArgsQueue.erase(mNotifyDeviceResetArgsQueue.begin());
+ ASSERT_NO_FATAL_FAILURE(
+ assertCalled<
+ NotifyDeviceResetArgs>(outEventArgs,
+ "Expected notifyDeviceReset() to have been called."));
}
void TestInputListener::assertNotifyDeviceResetWasNotCalled() {
- ASSERT_TRUE(mNotifyDeviceResetArgsQueue.empty())
- << "Expected notifyDeviceReset() to not have been called.";
+ ASSERT_NO_FATAL_FAILURE(
+ assertNotCalled<NotifyDeviceResetArgs>("notifyDeviceReset() should not be called."));
}
void TestInputListener::assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs) {
- ASSERT_FALSE(mNotifyKeyArgsQueue.empty()) << "Expected notifyKey() to have been called.";
- if (outEventArgs) {
- *outEventArgs = *mNotifyKeyArgsQueue.begin();
- }
- mNotifyKeyArgsQueue.erase(mNotifyKeyArgsQueue.begin());
+ ASSERT_NO_FATAL_FAILURE(
+ assertCalled<NotifyKeyArgs>(outEventArgs, "Expected notifyKey() to have been called."));
}
void TestInputListener::assertNotifyKeyWasNotCalled() {
- ASSERT_TRUE(mNotifyKeyArgsQueue.empty()) << "Expected notifyKey() to not have been called.";
+ ASSERT_NO_FATAL_FAILURE(assertNotCalled<NotifyKeyArgs>("notifyKey() should not be called."));
}
void TestInputListener::assertNotifyMotionWasCalled(NotifyMotionArgs* outEventArgs) {
- ASSERT_FALSE(mNotifyMotionArgsQueue.empty()) << "Expected notifyMotion() to have been called.";
- if (outEventArgs) {
- *outEventArgs = *mNotifyMotionArgsQueue.begin();
- }
- mNotifyMotionArgsQueue.erase(mNotifyMotionArgsQueue.begin());
+ ASSERT_NO_FATAL_FAILURE(
+ assertCalled<NotifyMotionArgs>(outEventArgs,
+ "Expected notifyMotion() to have been called."));
}
void TestInputListener::assertNotifyMotionWasNotCalled() {
- ASSERT_TRUE(mNotifyMotionArgsQueue.empty())
- << "Expected notifyMotion() to not have been called.";
+ ASSERT_NO_FATAL_FAILURE(
+ assertNotCalled<NotifySwitchArgs>("notifySwitch() should not be called."));
}
void TestInputListener::assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs) {
- ASSERT_FALSE(mNotifySwitchArgsQueue.empty())
- << "Expected notifySwitch() to have been called.";
- if (outEventArgs) {
- *outEventArgs = *mNotifySwitchArgsQueue.begin();
+ ASSERT_NO_FATAL_FAILURE(
+ assertCalled<NotifySwitchArgs>(outEventArgs,
+ "Expected notifySwitch() to have been called."));
+}
+
+template <class NotifyArgsType>
+void TestInputListener::assertCalled(NotifyArgsType* outEventArgs, std::string message) {
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+
+ std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
+ if (queue.empty()) {
+ const bool eventReceived =
+ mCondition.wait_for(lock, WAIT_TIMEOUT,
+ [&queue]() REQUIRES(mLock) { return !queue.empty(); });
+ if (!eventReceived) {
+ FAIL() << "Timed out waiting for event: " << message.c_str();
+ }
}
- mNotifySwitchArgsQueue.erase(mNotifySwitchArgsQueue.begin());
+ if (outEventArgs) {
+ *outEventArgs = *queue.begin();
+ }
+ queue.erase(queue.begin());
+}
+
+template <class NotifyArgsType>
+void TestInputListener::assertNotCalled(std::string message) {
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+
+ std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
+ const bool eventReceived = mCondition.wait_for(lock, WAIT_TIMEOUT, [&queue]() REQUIRES(mLock) {
+ return !queue.empty();
+ });
+ if (eventReceived) {
+ FAIL() << "Unexpected event: " << message.c_str();
+ }
+}
+
+template <class NotifyArgsType>
+void TestInputListener::notify(const NotifyArgsType* args) {
+ std::scoped_lock<std::mutex> lock(mLock);
+
+ std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
+ queue.push_back(*args);
+ mCondition.notify_all();
}
void TestInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
- mNotifyConfigurationChangedArgsQueue.push_back(*args);
+ notify<NotifyConfigurationChangedArgs>(args);
}
void TestInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
- mNotifyDeviceResetArgsQueue.push_back(*args);
+ notify<NotifyDeviceResetArgs>(args);
}
void TestInputListener::notifyKey(const NotifyKeyArgs* args) {
- mNotifyKeyArgsQueue.push_back(*args);
+ notify<NotifyKeyArgs>(args);
}
void TestInputListener::notifyMotion(const NotifyMotionArgs* args) {
- mNotifyMotionArgsQueue.push_back(*args);
+ notify<NotifyMotionArgs>(args);
}
void TestInputListener::notifySwitch(const NotifySwitchArgs* args) {
- mNotifySwitchArgsQueue.push_back(*args);
- }
-
+ notify<NotifySwitchArgs>(args);
+}
} // namespace android
diff --git a/services/inputflinger/tests/TestInputListener.h b/services/inputflinger/tests/TestInputListener.h
index 085d343..945e2ea 100644
--- a/services/inputflinger/tests/TestInputListener.h
+++ b/services/inputflinger/tests/TestInputListener.h
@@ -17,6 +17,7 @@
#ifndef _UI_TEST_INPUT_LISTENER_H
#define _UI_TEST_INPUT_LISTENER_H
+#include <android-base/thread_annotations.h>
#include <gtest/gtest.h>
#include "InputListener.h"
@@ -25,13 +26,6 @@
// --- TestInputListener ---
class TestInputListener : public InputListenerInterface {
-private:
- std::vector<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgsQueue;
- std::vector<NotifyDeviceResetArgs> mNotifyDeviceResetArgsQueue;
- std::vector<NotifyKeyArgs> mNotifyKeyArgsQueue;
- std::vector<NotifyMotionArgs> mNotifyMotionArgsQueue;
- std::vector<NotifySwitchArgs> mNotifySwitchArgsQueue;
-
protected:
virtual ~TestInputListener();
@@ -58,15 +52,34 @@
void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = nullptr);
private:
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
+ template <class NotifyArgsType>
+ void assertCalled(NotifyArgsType* outEventArgs, std::string message);
- virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
+ template <class NotifyArgsType>
+ void assertNotCalled(std::string message);
- virtual void notifyKey(const NotifyKeyArgs* args);
+ template <class NotifyArgsType>
+ void notify(const NotifyArgsType* args);
- virtual void notifyMotion(const NotifyMotionArgs* args);
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;
- virtual void notifySwitch(const NotifySwitchArgs* args);
+ virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
+
+ virtual void notifyKey(const NotifyKeyArgs* args) override;
+
+ virtual void notifyMotion(const NotifyMotionArgs* args) override;
+
+ virtual void notifySwitch(const NotifySwitchArgs* args) override;
+
+ std::mutex mLock;
+ std::condition_variable mCondition;
+
+ std::tuple<std::vector<NotifyConfigurationChangedArgs>, //
+ std::vector<NotifyDeviceResetArgs>, //
+ std::vector<NotifyKeyArgs>, //
+ std::vector<NotifyMotionArgs>, //
+ std::vector<NotifySwitchArgs>> //
+ mQueues GUARDED_BY(mLock);
};
} // namespace android