InputReader: Use shared keyboard source for all key events
When multiple EventHub devices are merged into a single InputDevice,
it's possible that there are more than one KeyboardInputMappers created
for the device. In this case, each mapper could be configured with a
different source. This can lead to situations where a device generates
key events that have different sources, depending on the mapper from
which it originated.
To make sure all key events use a consistent source for each
InputDevice, use the shared keyboard source when generating events from
a KeyboardInputMapper.
Bug: 354270482
Test: atest inputflinger_tests
Flag: EXEMPT bugfix
Change-Id: I586424b5e8d31d17cbe635d9f91a889aee906d40
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 4a21e48..38dcd65 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -98,10 +98,10 @@
KeyboardInputMapper::KeyboardInputMapper(InputDeviceContext& deviceContext,
const InputReaderConfiguration& readerConfig,
uint32_t source)
- : InputMapper(deviceContext, readerConfig), mSource(source) {}
+ : InputMapper(deviceContext, readerConfig), mMapperSource(source) {}
uint32_t KeyboardInputMapper::getSources() const {
- return mSource;
+ return mMapperSource;
}
ui::Rotation KeyboardInputMapper::getOrientation() {
@@ -351,8 +351,8 @@
policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
}
- out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when, readTime, deviceId, mSource,
- getDisplayId(), policyFlags,
+ out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when, readTime, deviceId,
+ getEventSource(), getDisplayId(), policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, flags,
keyCode, scanCode, keyMetaState, downTime));
return out;
@@ -478,12 +478,12 @@
std::list<NotifyArgs> out;
size_t n = mKeyDowns.size();
for (size_t i = 0; i < n; i++) {
- out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when,
- systemTime(SYSTEM_TIME_MONOTONIC), getDeviceId(), mSource,
- getDisplayId(), /*policyFlags=*/0, AKEY_EVENT_ACTION_UP,
- mKeyDowns[i].flags | AKEY_EVENT_FLAG_CANCELED,
- mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
- mKeyDowns[i].downTime));
+ out.emplace_back(
+ NotifyKeyArgs(getContext()->getNextId(), when, systemTime(SYSTEM_TIME_MONOTONIC),
+ getDeviceId(), getEventSource(), getDisplayId(), /*policyFlags=*/0,
+ AKEY_EVENT_ACTION_UP, mKeyDowns[i].flags | AKEY_EVENT_FLAG_CANCELED,
+ mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
+ mKeyDowns[i].downTime));
}
mKeyDowns.clear();
mMetaState = AMETA_NONE;
@@ -495,4 +495,14 @@
context.setLastKeyDownTimestamp(downTime);
}
+uint32_t KeyboardInputMapper::getEventSource() const {
+ // For all input events generated by this mapper, use the source that's shared across all
+ // KeyboardInputMappers for this device in case there are more than one.
+ static constexpr auto ALL_KEYBOARD_SOURCES =
+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD;
+ const auto deviceSources = getDeviceContext().getDeviceSources();
+ LOG_ALWAYS_FATAL_IF((deviceSources & mMapperSource) != mMapperSource);
+ return deviceSources & ALL_KEYBOARD_SOURCES;
+}
+
} // namespace android