Loading services/inputflinger/reader/InputDevice.cpp +19 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,7 @@ InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t genera mIdentifier(identifier), mIdentifier(identifier), mClasses(0), mClasses(0), mSources(0), mSources(0), mIsWaking(false), mIsExternal(false), mIsExternal(false), mHasMic(false), mHasMic(false), mDropUntilNextSync(false) {} mDropUntilNextSync(false) {} Loading Loading @@ -101,6 +102,7 @@ void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) { dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str()); dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str()); dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration); dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration); dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); dump += StringPrintf(INDENT2 "IsWaking: %s\n", toString(mIsWaking)); dump += StringPrintf(INDENT2 "AssociatedDisplayPort: "); dump += StringPrintf(INDENT2 "AssociatedDisplayPort: "); if (mAssociatedDisplayPort) { if (mAssociatedDisplayPort) { dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort); dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort); Loading Loading @@ -220,6 +222,7 @@ std::list<NotifyArgs> InputDevice::configure(nsecs_t when, mAssociatedDeviceType = mAssociatedDeviceType = getValueByKey(readerConfig.deviceTypeAssociations, mIdentifier.location); getValueByKey(readerConfig.deviceTypeAssociations, mIdentifier.location); mIsWaking = mConfiguration.getBool("device.wake").value_or(false); } } if (!changes.any() || changes.test(Change::KEYBOARD_LAYOUTS)) { if (!changes.any() || changes.test(Change::KEYBOARD_LAYOUTS)) { Loading Loading @@ -376,9 +379,25 @@ std::list<NotifyArgs> InputDevice::process(const RawEvent* rawEvents, size_t cou } } --count; --count; } } postProcess(out); return out; return out; } } void InputDevice::postProcess(std::list<NotifyArgs>& args) const { if (mIsWaking) { // Update policy flags to request wake for the `NotifyArgs` that come from waking devices. for (auto& arg : args) { if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) { notifyMotionArgs->policyFlags |= POLICY_FLAG_WAKE; } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) { notifySwitchArgs->policyFlags |= POLICY_FLAG_WAKE; } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) { notifyKeyArgs->policyFlags |= POLICY_FLAG_WAKE; } } } } std::list<NotifyArgs> InputDevice::timeoutExpired(nsecs_t when) { std::list<NotifyArgs> InputDevice::timeoutExpired(nsecs_t when) { std::list<NotifyArgs> out; std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.timeoutExpired(when); }); for_each_mapper([&](InputMapper& mapper) { out += mapper.timeoutExpired(when); }); Loading services/inputflinger/reader/include/InputDevice.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -191,6 +191,7 @@ private: std::unique_ptr<PeripheralControllerInterface> mController; std::unique_ptr<PeripheralControllerInterface> mController; uint32_t mSources; uint32_t mSources; bool mIsWaking; bool mIsExternal; bool mIsExternal; std::optional<uint8_t> mAssociatedDisplayPort; std::optional<uint8_t> mAssociatedDisplayPort; std::optional<std::string> mAssociatedDisplayUniqueId; std::optional<std::string> mAssociatedDisplayUniqueId; Loading @@ -207,6 +208,10 @@ private: PropertyMap mConfiguration; PropertyMap mConfiguration; // Runs logic post a `process` call. This can be used to update the generated `NotifyArgs` as // per the properties of the InputDevice. void postProcess(std::list<NotifyArgs>& args) const; // helpers to interate over the devices collection // helpers to interate over the devices collection // run a function against every mapper on every subdevice // run a function against every mapper on every subdevice inline void for_each_mapper(std::function<void(InputMapper&)> f) { inline void for_each_mapper(std::function<void(InputMapper&)> f) { Loading services/inputflinger/tests/InputReader_test.cpp +77 −1 Original line number Original line Diff line number Diff line Loading @@ -161,6 +161,7 @@ class FakeInputMapper : public InputMapper { // fake mapping which would normally come from keyCharacterMap // fake mapping which would normally come from keyCharacterMap std::unordered_map<int32_t, int32_t> mKeyCodeMapping; std::unordered_map<int32_t, int32_t> mKeyCodeMapping; std::vector<int32_t> mSupportedKeyCodes; std::vector<int32_t> mSupportedKeyCodes; std::list<NotifyArgs> mProcessResult; std::mutex mLock; std::mutex mLock; std::condition_variable mStateChangedCondition; std::condition_variable mStateChangedCondition; Loading Loading @@ -191,6 +192,14 @@ public: mMetaState = metaState; mMetaState = metaState; } } // Sets the return value for the `process` call. void setProcessResult(std::list<NotifyArgs> notifyArgs) { mProcessResult.clear(); for (auto notifyArg : notifyArgs) { mProcessResult.push_back(notifyArg); } } void assertConfigureWasCalled() { void assertConfigureWasCalled() { std::unique_lock<std::mutex> lock(mLock); std::unique_lock<std::mutex> lock(mLock); base::ScopedLockAssertion assumeLocked(mLock); base::ScopedLockAssertion assumeLocked(mLock); Loading Loading @@ -291,7 +300,7 @@ private: mLastEvent = *rawEvent; mLastEvent = *rawEvent; mProcessWasCalled = true; mProcessWasCalled = true; mStateChangedCondition.notify_all(); mStateChangedCondition.notify_all(); return {}; return mProcessResult; } } int32_t getKeyCodeState(uint32_t, int32_t keyCode) override { int32_t getKeyCodeState(uint32_t, int32_t keyCode) override { Loading Loading @@ -2475,6 +2484,73 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled()); ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled()); } } TEST_F(InputDeviceTest, WakeDevice_AddsWakeFlagToProcessNotifyArgs) { mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "1"); FakeInputMapper& mapper = mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(), AINPUT_SOURCE_KEYBOARD); NotifyMotionArgs args1; NotifySwitchArgs args2; NotifyKeyArgs args3; mapper.setProcessResult({args1, args2, args3}); InputReaderConfiguration config; std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{}); RawEvent event; event.deviceId = EVENTHUB_ID; std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1); for (auto& arg : notifyArgs) { if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) { ASSERT_EQ(POLICY_FLAG_WAKE, notifyMotionArgs->policyFlags); } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) { ASSERT_EQ(POLICY_FLAG_WAKE, notifySwitchArgs->policyFlags); } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) { ASSERT_EQ(POLICY_FLAG_WAKE, notifyKeyArgs->policyFlags); } } } TEST_F(InputDeviceTest, NotWakeDevice_DoesNotAddWakeFlagToProcessNotifyArgs) { mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0"); FakeInputMapper& mapper = mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(), AINPUT_SOURCE_KEYBOARD); NotifyMotionArgs args; mapper.setProcessResult({args}); InputReaderConfiguration config; std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{}); RawEvent event; event.deviceId = EVENTHUB_ID; std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1); // POLICY_FLAG_WAKE is not added to the NotifyArgs. ASSERT_EQ(0u, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags); } TEST_F(InputDeviceTest, NotWakeDevice_DoesNotRemoveExistingWakeFlagFromProcessNotifyArgs) { mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0"); FakeInputMapper& mapper = mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(), AINPUT_SOURCE_KEYBOARD); NotifyMotionArgs args; args.policyFlags = POLICY_FLAG_WAKE; mapper.setProcessResult({args}); InputReaderConfiguration config; std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{}); RawEvent event; event.deviceId = EVENTHUB_ID; std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1); // The POLICY_FLAG_WAKE is preserved, despite the device being a non-wake device. ASSERT_EQ(POLICY_FLAG_WAKE, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags); } // A single input device is associated with a specific display. Check that: // A single input device is associated with a specific display. Check that: // 1. Device is disabled if the viewport corresponding to the associated display is not found // 1. Device is disabled if the viewport corresponding to the associated display is not found // 2. Device is disabled when setEnabled API is called // 2. Device is disabled when setEnabled API is called Loading Loading
services/inputflinger/reader/InputDevice.cpp +19 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,7 @@ InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t genera mIdentifier(identifier), mIdentifier(identifier), mClasses(0), mClasses(0), mSources(0), mSources(0), mIsWaking(false), mIsExternal(false), mIsExternal(false), mHasMic(false), mHasMic(false), mDropUntilNextSync(false) {} mDropUntilNextSync(false) {} Loading Loading @@ -101,6 +102,7 @@ void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) { dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str()); dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str()); dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration); dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration); dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); dump += StringPrintf(INDENT2 "IsWaking: %s\n", toString(mIsWaking)); dump += StringPrintf(INDENT2 "AssociatedDisplayPort: "); dump += StringPrintf(INDENT2 "AssociatedDisplayPort: "); if (mAssociatedDisplayPort) { if (mAssociatedDisplayPort) { dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort); dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort); Loading Loading @@ -220,6 +222,7 @@ std::list<NotifyArgs> InputDevice::configure(nsecs_t when, mAssociatedDeviceType = mAssociatedDeviceType = getValueByKey(readerConfig.deviceTypeAssociations, mIdentifier.location); getValueByKey(readerConfig.deviceTypeAssociations, mIdentifier.location); mIsWaking = mConfiguration.getBool("device.wake").value_or(false); } } if (!changes.any() || changes.test(Change::KEYBOARD_LAYOUTS)) { if (!changes.any() || changes.test(Change::KEYBOARD_LAYOUTS)) { Loading Loading @@ -376,9 +379,25 @@ std::list<NotifyArgs> InputDevice::process(const RawEvent* rawEvents, size_t cou } } --count; --count; } } postProcess(out); return out; return out; } } void InputDevice::postProcess(std::list<NotifyArgs>& args) const { if (mIsWaking) { // Update policy flags to request wake for the `NotifyArgs` that come from waking devices. for (auto& arg : args) { if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) { notifyMotionArgs->policyFlags |= POLICY_FLAG_WAKE; } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) { notifySwitchArgs->policyFlags |= POLICY_FLAG_WAKE; } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) { notifyKeyArgs->policyFlags |= POLICY_FLAG_WAKE; } } } } std::list<NotifyArgs> InputDevice::timeoutExpired(nsecs_t when) { std::list<NotifyArgs> InputDevice::timeoutExpired(nsecs_t when) { std::list<NotifyArgs> out; std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.timeoutExpired(when); }); for_each_mapper([&](InputMapper& mapper) { out += mapper.timeoutExpired(when); }); Loading
services/inputflinger/reader/include/InputDevice.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -191,6 +191,7 @@ private: std::unique_ptr<PeripheralControllerInterface> mController; std::unique_ptr<PeripheralControllerInterface> mController; uint32_t mSources; uint32_t mSources; bool mIsWaking; bool mIsExternal; bool mIsExternal; std::optional<uint8_t> mAssociatedDisplayPort; std::optional<uint8_t> mAssociatedDisplayPort; std::optional<std::string> mAssociatedDisplayUniqueId; std::optional<std::string> mAssociatedDisplayUniqueId; Loading @@ -207,6 +208,10 @@ private: PropertyMap mConfiguration; PropertyMap mConfiguration; // Runs logic post a `process` call. This can be used to update the generated `NotifyArgs` as // per the properties of the InputDevice. void postProcess(std::list<NotifyArgs>& args) const; // helpers to interate over the devices collection // helpers to interate over the devices collection // run a function against every mapper on every subdevice // run a function against every mapper on every subdevice inline void for_each_mapper(std::function<void(InputMapper&)> f) { inline void for_each_mapper(std::function<void(InputMapper&)> f) { Loading
services/inputflinger/tests/InputReader_test.cpp +77 −1 Original line number Original line Diff line number Diff line Loading @@ -161,6 +161,7 @@ class FakeInputMapper : public InputMapper { // fake mapping which would normally come from keyCharacterMap // fake mapping which would normally come from keyCharacterMap std::unordered_map<int32_t, int32_t> mKeyCodeMapping; std::unordered_map<int32_t, int32_t> mKeyCodeMapping; std::vector<int32_t> mSupportedKeyCodes; std::vector<int32_t> mSupportedKeyCodes; std::list<NotifyArgs> mProcessResult; std::mutex mLock; std::mutex mLock; std::condition_variable mStateChangedCondition; std::condition_variable mStateChangedCondition; Loading Loading @@ -191,6 +192,14 @@ public: mMetaState = metaState; mMetaState = metaState; } } // Sets the return value for the `process` call. void setProcessResult(std::list<NotifyArgs> notifyArgs) { mProcessResult.clear(); for (auto notifyArg : notifyArgs) { mProcessResult.push_back(notifyArg); } } void assertConfigureWasCalled() { void assertConfigureWasCalled() { std::unique_lock<std::mutex> lock(mLock); std::unique_lock<std::mutex> lock(mLock); base::ScopedLockAssertion assumeLocked(mLock); base::ScopedLockAssertion assumeLocked(mLock); Loading Loading @@ -291,7 +300,7 @@ private: mLastEvent = *rawEvent; mLastEvent = *rawEvent; mProcessWasCalled = true; mProcessWasCalled = true; mStateChangedCondition.notify_all(); mStateChangedCondition.notify_all(); return {}; return mProcessResult; } } int32_t getKeyCodeState(uint32_t, int32_t keyCode) override { int32_t getKeyCodeState(uint32_t, int32_t keyCode) override { Loading Loading @@ -2475,6 +2484,73 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled()); ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled()); } } TEST_F(InputDeviceTest, WakeDevice_AddsWakeFlagToProcessNotifyArgs) { mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "1"); FakeInputMapper& mapper = mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(), AINPUT_SOURCE_KEYBOARD); NotifyMotionArgs args1; NotifySwitchArgs args2; NotifyKeyArgs args3; mapper.setProcessResult({args1, args2, args3}); InputReaderConfiguration config; std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{}); RawEvent event; event.deviceId = EVENTHUB_ID; std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1); for (auto& arg : notifyArgs) { if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) { ASSERT_EQ(POLICY_FLAG_WAKE, notifyMotionArgs->policyFlags); } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) { ASSERT_EQ(POLICY_FLAG_WAKE, notifySwitchArgs->policyFlags); } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) { ASSERT_EQ(POLICY_FLAG_WAKE, notifyKeyArgs->policyFlags); } } } TEST_F(InputDeviceTest, NotWakeDevice_DoesNotAddWakeFlagToProcessNotifyArgs) { mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0"); FakeInputMapper& mapper = mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(), AINPUT_SOURCE_KEYBOARD); NotifyMotionArgs args; mapper.setProcessResult({args}); InputReaderConfiguration config; std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{}); RawEvent event; event.deviceId = EVENTHUB_ID; std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1); // POLICY_FLAG_WAKE is not added to the NotifyArgs. ASSERT_EQ(0u, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags); } TEST_F(InputDeviceTest, NotWakeDevice_DoesNotRemoveExistingWakeFlagFromProcessNotifyArgs) { mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0"); FakeInputMapper& mapper = mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(), AINPUT_SOURCE_KEYBOARD); NotifyMotionArgs args; args.policyFlags = POLICY_FLAG_WAKE; mapper.setProcessResult({args}); InputReaderConfiguration config; std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{}); RawEvent event; event.deviceId = EVENTHUB_ID; std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1); // The POLICY_FLAG_WAKE is preserved, despite the device being a non-wake device. ASSERT_EQ(POLICY_FLAG_WAKE, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags); } // A single input device is associated with a specific display. Check that: // A single input device is associated with a specific display. Check that: // 1. Device is disabled if the viewport corresponding to the associated display is not found // 1. Device is disabled if the viewport corresponding to the associated display is not found // 2. Device is disabled when setEnabled API is called // 2. Device is disabled when setEnabled API is called Loading