Loading services/inputflinger/reader/mapper/KeyboardInputMapper.cpp +20 −8 Original line number Diff line number Diff line Loading @@ -127,7 +127,6 @@ void KeyboardInputMapper::dump(std::string& dump) { dump += StringPrintf(INDENT3 "Orientation: %d\n", getOrientation()); dump += StringPrintf(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size()); dump += StringPrintf(INDENT3 "MetaState: 0x%0x\n", mMetaState); dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime); } std::optional<DisplayViewport> KeyboardInputMapper::findViewport( Loading Loading @@ -196,9 +195,7 @@ void KeyboardInputMapper::dumpParameters(std::string& dump) { } void KeyboardInputMapper::reset(nsecs_t when) { mMetaState = AMETA_NONE; mDownTime = 0; mKeyDowns.clear(); cancelAllDownKeys(when); mCurrentHidUsage = 0; resetLedState(); Loading Loading @@ -281,6 +278,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, policyFlags = 0; } nsecs_t downTime = when; if (down) { // Rotate key codes according to orientation if needed. if (mParameters.orientationAware) { Loading @@ -292,6 +290,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, if (keyDownIndex >= 0) { // key repeat, be sure to use same keycode as before in case of rotation keyCode = mKeyDowns[keyDownIndex].keyCode; downTime = mKeyDowns[keyDownIndex].downTime; } else { // key down if ((policyFlags & POLICY_FLAG_VIRTUAL) && Loading @@ -305,16 +304,16 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, KeyDown keyDown; keyDown.keyCode = keyCode; keyDown.scanCode = scanCode; keyDown.downTime = when; mKeyDowns.push_back(keyDown); } mDownTime = when; } else { // Remove key down. ssize_t keyDownIndex = findKeyDown(scanCode); if (keyDownIndex >= 0) { // key up, be sure to use same keycode as before in case of rotation keyCode = mKeyDowns[keyDownIndex].keyCode; downTime = mKeyDowns[keyDownIndex].downTime; mKeyDowns.erase(mKeyDowns.begin() + (size_t)keyDownIndex); } else { // key was not actually down Loading @@ -333,8 +332,6 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, keyMetaState = mMetaState; } nsecs_t downTime = mDownTime; // Key down on external an keyboard should wake the device. // We don't do this for internal keyboards to prevent them from waking up in your pocket. // For internal keyboards and devices for which the default wake behavior is explicitly Loading Loading @@ -473,4 +470,19 @@ std::optional<int32_t> KeyboardInputMapper::getAssociatedDisplayId() { return std::nullopt; } void KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) { size_t n = mKeyDowns.size(); for (size_t i = 0; i < n; i++) { NotifyKeyArgs args(getContext()->getNextId(), when, systemTime(SYSTEM_TIME_MONOTONIC), getDeviceId(), mSource, getDisplayId(), 0 /*policyFlags*/, AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE, mKeyDowns[i].downTime); getListener().notifyKey(&args); } mKeyDowns.clear(); mMetaState = AMETA_NONE; } } // namespace android services/inputflinger/reader/mapper/KeyboardInputMapper.h +2 −1 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ private: std::optional<DisplayViewport> mViewport; struct KeyDown { nsecs_t downTime; int32_t keyCode; int32_t scanCode; }; Loading @@ -59,7 +60,6 @@ private: std::vector<KeyDown> mKeyDowns; // keys that are down int32_t mMetaState; nsecs_t mDownTime; // time of most recent key down int32_t mCurrentHidUsage; // most recent HID usage seen this packet, or 0 if none Loading Loading @@ -98,6 +98,7 @@ private: void updateLedStateForModifier(LedState& ledState, int32_t led, int32_t modifier, bool reset); std::optional<DisplayViewport> findViewport(nsecs_t when, const InputReaderConfiguration* config); void cancelAllDownKeys(nsecs_t when); }; } // namespace android Loading services/inputflinger/tests/InputReader_test.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -4088,6 +4088,37 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) { ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); } TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) { const int32_t USAGE_A = 0x070004; mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE); mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE); KeyboardInputMapper& mapper = addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); // Key down by scan code. process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1); NotifyKeyArgs args; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); ASSERT_EQ(ARBITRARY_TIME, args.eventTime); ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); ASSERT_EQ(AKEYCODE_HOME, args.keyCode); ASSERT_EQ(KEY_HOME, args.scanCode); ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags); // Disable device, it should synthesize cancellation events for down events. mFakePolicy->addDisabledDevice(DEVICE_ID); configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); ASSERT_EQ(AKEYCODE_HOME, args.keyCode); ASSERT_EQ(KEY_HOME, args.scanCode); ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags); } // --- KeyboardInputMapperTest_ExternalDevice --- class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest { Loading Loading
services/inputflinger/reader/mapper/KeyboardInputMapper.cpp +20 −8 Original line number Diff line number Diff line Loading @@ -127,7 +127,6 @@ void KeyboardInputMapper::dump(std::string& dump) { dump += StringPrintf(INDENT3 "Orientation: %d\n", getOrientation()); dump += StringPrintf(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size()); dump += StringPrintf(INDENT3 "MetaState: 0x%0x\n", mMetaState); dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime); } std::optional<DisplayViewport> KeyboardInputMapper::findViewport( Loading Loading @@ -196,9 +195,7 @@ void KeyboardInputMapper::dumpParameters(std::string& dump) { } void KeyboardInputMapper::reset(nsecs_t when) { mMetaState = AMETA_NONE; mDownTime = 0; mKeyDowns.clear(); cancelAllDownKeys(when); mCurrentHidUsage = 0; resetLedState(); Loading Loading @@ -281,6 +278,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, policyFlags = 0; } nsecs_t downTime = when; if (down) { // Rotate key codes according to orientation if needed. if (mParameters.orientationAware) { Loading @@ -292,6 +290,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, if (keyDownIndex >= 0) { // key repeat, be sure to use same keycode as before in case of rotation keyCode = mKeyDowns[keyDownIndex].keyCode; downTime = mKeyDowns[keyDownIndex].downTime; } else { // key down if ((policyFlags & POLICY_FLAG_VIRTUAL) && Loading @@ -305,16 +304,16 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, KeyDown keyDown; keyDown.keyCode = keyCode; keyDown.scanCode = scanCode; keyDown.downTime = when; mKeyDowns.push_back(keyDown); } mDownTime = when; } else { // Remove key down. ssize_t keyDownIndex = findKeyDown(scanCode); if (keyDownIndex >= 0) { // key up, be sure to use same keycode as before in case of rotation keyCode = mKeyDowns[keyDownIndex].keyCode; downTime = mKeyDowns[keyDownIndex].downTime; mKeyDowns.erase(mKeyDowns.begin() + (size_t)keyDownIndex); } else { // key was not actually down Loading @@ -333,8 +332,6 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down, keyMetaState = mMetaState; } nsecs_t downTime = mDownTime; // Key down on external an keyboard should wake the device. // We don't do this for internal keyboards to prevent them from waking up in your pocket. // For internal keyboards and devices for which the default wake behavior is explicitly Loading Loading @@ -473,4 +470,19 @@ std::optional<int32_t> KeyboardInputMapper::getAssociatedDisplayId() { return std::nullopt; } void KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) { size_t n = mKeyDowns.size(); for (size_t i = 0; i < n; i++) { NotifyKeyArgs args(getContext()->getNextId(), when, systemTime(SYSTEM_TIME_MONOTONIC), getDeviceId(), mSource, getDisplayId(), 0 /*policyFlags*/, AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE, mKeyDowns[i].downTime); getListener().notifyKey(&args); } mKeyDowns.clear(); mMetaState = AMETA_NONE; } } // namespace android
services/inputflinger/reader/mapper/KeyboardInputMapper.h +2 −1 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ private: std::optional<DisplayViewport> mViewport; struct KeyDown { nsecs_t downTime; int32_t keyCode; int32_t scanCode; }; Loading @@ -59,7 +60,6 @@ private: std::vector<KeyDown> mKeyDowns; // keys that are down int32_t mMetaState; nsecs_t mDownTime; // time of most recent key down int32_t mCurrentHidUsage; // most recent HID usage seen this packet, or 0 if none Loading Loading @@ -98,6 +98,7 @@ private: void updateLedStateForModifier(LedState& ledState, int32_t led, int32_t modifier, bool reset); std::optional<DisplayViewport> findViewport(nsecs_t when, const InputReaderConfiguration* config); void cancelAllDownKeys(nsecs_t when); }; } // namespace android Loading
services/inputflinger/tests/InputReader_test.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -4088,6 +4088,37 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) { ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); } TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) { const int32_t USAGE_A = 0x070004; mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE); mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE); KeyboardInputMapper& mapper = addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); // Key down by scan code. process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1); NotifyKeyArgs args; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); ASSERT_EQ(ARBITRARY_TIME, args.eventTime); ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); ASSERT_EQ(AKEYCODE_HOME, args.keyCode); ASSERT_EQ(KEY_HOME, args.scanCode); ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags); // Disable device, it should synthesize cancellation events for down events. mFakePolicy->addDisabledDevice(DEVICE_ID); configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); ASSERT_EQ(AKEYCODE_HOME, args.keyCode); ASSERT_EQ(KEY_HOME, args.scanCode); ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags); } // --- KeyboardInputMapperTest_ExternalDevice --- class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest { Loading