Loading include/input/KeyCharacterMap.h +14 −6 Original line number Diff line number Diff line Loading @@ -125,14 +125,21 @@ public: bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, Vector<KeyEvent>& outEvents) const; /* Maps an Android key code to another Android key code. This mapping is applied after scanCode * and usageCodes are mapped to corresponding Android Keycode */ void addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode); /* Maps a scan code and usage code to a key code, in case this key map overrides * the mapping in some way. */ status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const; /* Tries to find a replacement key code for a given key code and meta state * in character map. */ void tryRemapKey(int32_t scanCode, int32_t metaState, int32_t* outKeyCode, int32_t* outMetaState) const; /* Returns keycode after applying Android key code remapping defined in mKeyRemapping */ int32_t applyKeyRemapping(int32_t fromKeyCode) const; /* Returns the <keyCode, metaState> pair after applying key behavior defined in the kcm file, * that tries to find a replacement key code based on current meta state */ std::pair<int32_t /*keyCode*/, int32_t /*metaState*/> applyKeyBehavior(int32_t keyCode, int32_t metaState) const; #ifdef __linux__ /* Reads a key map from a parcel. */ Loading Loading @@ -227,8 +234,9 @@ private: std::string mLoadFileName; bool mLayoutOverlayApplied; KeyedVector<int32_t, int32_t> mKeysByScanCode; KeyedVector<int32_t, int32_t> mKeysByUsageCode; std::map<int32_t /* fromAndroidKeyCode */, int32_t /* toAndroidKeyCode */> mKeyRemapping; std::map<int32_t /* fromScanCode */, int32_t /* toAndroidKeyCode */> mKeysByScanCode; std::map<int32_t /* fromHidUsageCode */, int32_t /* toAndroidKeyCode */> mKeysByUsageCode; KeyCharacterMap(const std::string& filename); Loading libs/input/KeyCharacterMap.cpp +91 −59 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ // Enables debug output for mapping. #define DEBUG_MAPPING 0 namespace android { static const char* WHITESPACE = " \t\r"; Loading Loading @@ -93,6 +92,7 @@ KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) : mType(other.mType), mLoadFileName(other.mLoadFileName), mLayoutOverlayApplied(other.mLayoutOverlayApplied), mKeyRemapping(other.mKeyRemapping), mKeysByScanCode(other.mKeysByScanCode), mKeysByUsageCode(other.mKeysByUsageCode) { for (size_t i = 0; i < other.mKeys.size(); i++) { Loading @@ -114,7 +114,7 @@ bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const { if (mLayoutOverlayApplied != other.mLayoutOverlayApplied) { return false; } if (mKeys.size() != other.mKeys.size() || if (mKeys.size() != other.mKeys.size() || mKeyRemapping.size() != other.mKeyRemapping.size() || mKeysByScanCode.size() != other.mKeysByScanCode.size() || mKeysByUsageCode.size() != other.mKeysByUsageCode.size()) { return false; Loading @@ -131,23 +131,10 @@ bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const { } } for (size_t i = 0; i < mKeysByScanCode.size(); i++) { if (mKeysByScanCode.keyAt(i) != other.mKeysByScanCode.keyAt(i)) { return false; } if (mKeysByScanCode.valueAt(i) != other.mKeysByScanCode.valueAt(i)) { return false; } } for (size_t i = 0; i < mKeysByUsageCode.size(); i++) { if (mKeysByUsageCode.keyAt(i) != other.mKeysByUsageCode.keyAt(i)) { if (mKeyRemapping != other.mKeyRemapping || mKeysByScanCode != other.mKeysByScanCode || mKeysByUsageCode != other.mKeysByUsageCode) { return false; } if (mKeysByUsageCode.valueAt(i) != other.mKeysByUsageCode.valueAt(i)) { return false; } } return true; } Loading Loading @@ -258,14 +245,12 @@ void KeyCharacterMap::combine(const KeyCharacterMap& overlay) { } } for (size_t i = 0; i < overlay.mKeysByScanCode.size(); i++) { mKeysByScanCode.replaceValueFor(overlay.mKeysByScanCode.keyAt(i), overlay.mKeysByScanCode.valueAt(i)); for (auto const& it : overlay.mKeysByScanCode) { mKeysByScanCode.insert_or_assign(it.first, it.second); } for (size_t i = 0; i < overlay.mKeysByUsageCode.size(); i++) { mKeysByUsageCode.replaceValueFor(overlay.mKeysByUsageCode.keyAt(i), overlay.mKeysByUsageCode.valueAt(i)); for (auto const& it : overlay.mKeysByUsageCode) { mKeysByUsageCode.insert_or_assign(it.first, it.second); } mLayoutOverlayApplied = true; } Loading Loading @@ -400,11 +385,26 @@ bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t return true; } void KeyCharacterMap::addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode) { if (fromKeyCode == toKeyCode) { mKeyRemapping.erase(fromKeyCode); #if DEBUG_MAPPING ALOGD("addKeyRemapping: Cleared remapping forKeyCode=%d ~ Result Successful.", fromKeyCode); #endif return; } mKeyRemapping.insert_or_assign(fromKeyCode, toKeyCode); #if DEBUG_MAPPING ALOGD("addKeyRemapping: fromKeyCode=%d, toKeyCode=%d ~ Result Successful.", fromKeyCode, toKeyCode); #endif } status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const { if (usageCode) { ssize_t index = mKeysByUsageCode.indexOfKey(usageCode); if (index >= 0) { *outKeyCode = mKeysByUsageCode.valueAt(index); const auto it = mKeysByUsageCode.find(usageCode); if (it != mKeysByUsageCode.end()) { *outKeyCode = it->second; #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); Loading @@ -413,9 +413,9 @@ status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* o } } if (scanCode) { ssize_t index = mKeysByScanCode.indexOfKey(scanCode); if (index >= 0) { *outKeyCode = mKeysByScanCode.valueAt(index); const auto it = mKeysByScanCode.find(scanCode); if (it != mKeysByScanCode.end()) { *outKeyCode = it->second; #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); Loading @@ -431,45 +431,59 @@ status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* o return NAME_NOT_FOUND; } void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState, int32_t *outKeyCode, int32_t *outMetaState) const { *outKeyCode = keyCode; *outMetaState = metaState; int32_t KeyCharacterMap::applyKeyRemapping(int32_t fromKeyCode) const { int32_t toKeyCode = fromKeyCode; const Behavior* behavior = getKeyBehavior(keyCode, metaState); const auto it = mKeyRemapping.find(fromKeyCode); if (it != mKeyRemapping.end()) { toKeyCode = it->second; } #if DEBUG_MAPPING ALOGD("applyKeyRemapping: keyCode=%d ~ replacement keyCode=%d.", fromKeyCode, toKeyCode); #endif return toKeyCode; } std::pair<int32_t, int32_t> KeyCharacterMap::applyKeyBehavior(int32_t fromKeyCode, int32_t fromMetaState) const { int32_t toKeyCode = fromKeyCode; int32_t toMetaState = fromMetaState; const Behavior* behavior = getKeyBehavior(fromKeyCode, fromMetaState); if (behavior != nullptr) { if (behavior->replacementKeyCode) { *outKeyCode = behavior->replacementKeyCode; int32_t newMetaState = metaState & ~behavior->metaState; toKeyCode = behavior->replacementKeyCode; toMetaState = fromMetaState & ~behavior->metaState; // Reset dependent meta states. if (behavior->metaState & AMETA_ALT_ON) { newMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON); toMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON); } if (behavior->metaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { newMetaState &= ~AMETA_ALT_ON; toMetaState &= ~AMETA_ALT_ON; } if (behavior->metaState & AMETA_CTRL_ON) { newMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON); toMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON); } if (behavior->metaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) { newMetaState &= ~AMETA_CTRL_ON; toMetaState &= ~AMETA_CTRL_ON; } if (behavior->metaState & AMETA_SHIFT_ON) { newMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON); toMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON); } if (behavior->metaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) { newMetaState &= ~AMETA_SHIFT_ON; toMetaState &= ~AMETA_SHIFT_ON; } // ... and put universal bits back if needed *outMetaState = normalizeMetaState(newMetaState); toMetaState = normalizeMetaState(toMetaState); } } #if DEBUG_MAPPING ALOGD("tryRemapKey: keyCode=%d, metaState=0x%08x ~ " ALOGD("applyKeyBehavior: keyCode=%d, metaState=0x%08x ~ " "replacement keyCode=%d, replacement metaState=0x%08x.", keyCode, metaState, *outKeyCode, *outMetaState); fromKeyCode, fromMetaState, toKeyCode, toMetaState); #endif return std::make_pair(toKeyCode, toMetaState); } bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { Loading Loading @@ -720,6 +734,18 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) return nullptr; } } size_t numKeyRemapping = parcel->readInt32(); if (parcel->errorCheck()) { return nullptr; } for (size_t i = 0; i < numKeyRemapping; i++) { int32_t key = parcel->readInt32(); int32_t value = parcel->readInt32(); map->mKeyRemapping.insert_or_assign(key, value); if (parcel->errorCheck()) { return nullptr; } } size_t numKeysByScanCode = parcel->readInt32(); if (parcel->errorCheck()) { return nullptr; Loading @@ -727,7 +753,7 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) for (size_t i = 0; i < numKeysByScanCode; i++) { int32_t key = parcel->readInt32(); int32_t value = parcel->readInt32(); map->mKeysByScanCode.add(key, value); map->mKeysByScanCode.insert_or_assign(key, value); if (parcel->errorCheck()) { return nullptr; } Loading @@ -739,7 +765,7 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) for (size_t i = 0; i < numKeysByUsageCode; i++) { int32_t key = parcel->readInt32(); int32_t value = parcel->readInt32(); map->mKeysByUsageCode.add(key, value); map->mKeysByUsageCode.insert_or_assign(key, value); if (parcel->errorCheck()) { return nullptr; } Loading Loading @@ -773,17 +799,23 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { } parcel->writeInt32(0); } size_t numKeyRemapping = mKeyRemapping.size(); parcel->writeInt32(numKeyRemapping); for (auto const& [fromAndroidKeyCode, toAndroidKeyCode] : mKeyRemapping) { parcel->writeInt32(fromAndroidKeyCode); parcel->writeInt32(toAndroidKeyCode); } size_t numKeysByScanCode = mKeysByScanCode.size(); parcel->writeInt32(numKeysByScanCode); for (size_t i = 0; i < numKeysByScanCode; i++) { parcel->writeInt32(mKeysByScanCode.keyAt(i)); parcel->writeInt32(mKeysByScanCode.valueAt(i)); for (auto const& [fromScanCode, toAndroidKeyCode] : mKeysByScanCode) { parcel->writeInt32(fromScanCode); parcel->writeInt32(toAndroidKeyCode); } size_t numKeysByUsageCode = mKeysByUsageCode.size(); parcel->writeInt32(numKeysByUsageCode); for (size_t i = 0; i < numKeysByUsageCode; i++) { parcel->writeInt32(mKeysByUsageCode.keyAt(i)); parcel->writeInt32(mKeysByUsageCode.valueAt(i)); for (auto const& [fromUsageCode, toAndroidKeyCode] : mKeysByUsageCode) { parcel->writeInt32(fromUsageCode); parcel->writeInt32(toAndroidKeyCode); } } #endif // __linux__ Loading Loading @@ -950,9 +982,9 @@ status_t KeyCharacterMap::Parser::parseMapKey() { mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } KeyedVector<int32_t, int32_t>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; if (map.indexOfKey(code) >= 0) { std::map<int32_t, int32_t>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; const auto it = map.find(code); if (it != map.end()) { ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; Loading @@ -971,7 +1003,7 @@ status_t KeyCharacterMap::Parser::parseMapKey() { ALOGD("Parsed map key %s: code=%d, keyCode=%d.", mapUsage ? "usage" : "scan code", code, keyCode); #endif map.add(code, keyCode); map.insert_or_assign(code, keyCode); return NO_ERROR; } Loading services/inputflinger/include/InputReaderBase.h +3 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,9 @@ public: virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) = 0; virtual void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const = 0; virtual int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const = 0; /* Toggle Caps Lock */ Loading services/inputflinger/reader/EventHub.cpp +26 −4 Original line number Diff line number Diff line Loading @@ -952,15 +952,19 @@ int32_t EventHub::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKey device->getKeyCharacterMap()->mapKey(scanCodes[0], 0 /*usageCode*/, &outKeyCode); switch (mapKeyRes) { case OK: return outKeyCode; break; case NAME_NOT_FOUND: // key character map doesn't re-map this scanCode, hence the keyCode remains the same return locationKeyCode; outKeyCode = locationKeyCode; break; default: ALOGW("Failed to get key code for key location: Key character map returned error %s", statusToString(mapKeyRes).c_str()); return AKEYCODE_UNKNOWN; outKeyCode = AKEYCODE_UNKNOWN; break; } // Remap if there is a Key remapping added to the KCM and return the remapped key return device->getKeyCharacterMap()->applyKeyRemapping(outKeyCode); } int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { Loading Loading @@ -1023,6 +1027,18 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t return false; } void EventHub::addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const { std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { return; } const std::shared_ptr<KeyCharacterMap> kcm = device->getKeyCharacterMap(); if (kcm) { kcm->addKeyRemapping(fromKeyCode, toKeyCode); } } status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState, int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const { std::scoped_lock _l(mLock); Loading @@ -1048,7 +1064,13 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, if (status == NO_ERROR) { if (kcm) { kcm->tryRemapKey(*outKeycode, metaState, outKeycode, outMetaState); // Remap keys based on user-defined key remappings and key behavior defined in the // corresponding kcm file *outKeycode = kcm->applyKeyRemapping(*outKeycode); // Remap keys based on Key behavior defined in KCM file std::tie(*outKeycode, *outMetaState) = kcm->applyKeyBehavior(*outKeycode, metaState); } else { *outMetaState = metaState; } Loading services/inputflinger/reader/InputDevice.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -631,6 +631,12 @@ void InputDevice::updateMetaState(int32_t keyCode) { }); } void InputDevice::addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode) { for_each_subdevice([fromKeyCode, toKeyCode](auto& context) { context.addKeyRemapping(fromKeyCode, toKeyCode); }); } void InputDevice::bumpGeneration() { mGeneration = mContext->bumpGeneration(); } Loading Loading
include/input/KeyCharacterMap.h +14 −6 Original line number Diff line number Diff line Loading @@ -125,14 +125,21 @@ public: bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, Vector<KeyEvent>& outEvents) const; /* Maps an Android key code to another Android key code. This mapping is applied after scanCode * and usageCodes are mapped to corresponding Android Keycode */ void addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode); /* Maps a scan code and usage code to a key code, in case this key map overrides * the mapping in some way. */ status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const; /* Tries to find a replacement key code for a given key code and meta state * in character map. */ void tryRemapKey(int32_t scanCode, int32_t metaState, int32_t* outKeyCode, int32_t* outMetaState) const; /* Returns keycode after applying Android key code remapping defined in mKeyRemapping */ int32_t applyKeyRemapping(int32_t fromKeyCode) const; /* Returns the <keyCode, metaState> pair after applying key behavior defined in the kcm file, * that tries to find a replacement key code based on current meta state */ std::pair<int32_t /*keyCode*/, int32_t /*metaState*/> applyKeyBehavior(int32_t keyCode, int32_t metaState) const; #ifdef __linux__ /* Reads a key map from a parcel. */ Loading Loading @@ -227,8 +234,9 @@ private: std::string mLoadFileName; bool mLayoutOverlayApplied; KeyedVector<int32_t, int32_t> mKeysByScanCode; KeyedVector<int32_t, int32_t> mKeysByUsageCode; std::map<int32_t /* fromAndroidKeyCode */, int32_t /* toAndroidKeyCode */> mKeyRemapping; std::map<int32_t /* fromScanCode */, int32_t /* toAndroidKeyCode */> mKeysByScanCode; std::map<int32_t /* fromHidUsageCode */, int32_t /* toAndroidKeyCode */> mKeysByUsageCode; KeyCharacterMap(const std::string& filename); Loading
libs/input/KeyCharacterMap.cpp +91 −59 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ // Enables debug output for mapping. #define DEBUG_MAPPING 0 namespace android { static const char* WHITESPACE = " \t\r"; Loading Loading @@ -93,6 +92,7 @@ KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) : mType(other.mType), mLoadFileName(other.mLoadFileName), mLayoutOverlayApplied(other.mLayoutOverlayApplied), mKeyRemapping(other.mKeyRemapping), mKeysByScanCode(other.mKeysByScanCode), mKeysByUsageCode(other.mKeysByUsageCode) { for (size_t i = 0; i < other.mKeys.size(); i++) { Loading @@ -114,7 +114,7 @@ bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const { if (mLayoutOverlayApplied != other.mLayoutOverlayApplied) { return false; } if (mKeys.size() != other.mKeys.size() || if (mKeys.size() != other.mKeys.size() || mKeyRemapping.size() != other.mKeyRemapping.size() || mKeysByScanCode.size() != other.mKeysByScanCode.size() || mKeysByUsageCode.size() != other.mKeysByUsageCode.size()) { return false; Loading @@ -131,23 +131,10 @@ bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const { } } for (size_t i = 0; i < mKeysByScanCode.size(); i++) { if (mKeysByScanCode.keyAt(i) != other.mKeysByScanCode.keyAt(i)) { return false; } if (mKeysByScanCode.valueAt(i) != other.mKeysByScanCode.valueAt(i)) { return false; } } for (size_t i = 0; i < mKeysByUsageCode.size(); i++) { if (mKeysByUsageCode.keyAt(i) != other.mKeysByUsageCode.keyAt(i)) { if (mKeyRemapping != other.mKeyRemapping || mKeysByScanCode != other.mKeysByScanCode || mKeysByUsageCode != other.mKeysByUsageCode) { return false; } if (mKeysByUsageCode.valueAt(i) != other.mKeysByUsageCode.valueAt(i)) { return false; } } return true; } Loading Loading @@ -258,14 +245,12 @@ void KeyCharacterMap::combine(const KeyCharacterMap& overlay) { } } for (size_t i = 0; i < overlay.mKeysByScanCode.size(); i++) { mKeysByScanCode.replaceValueFor(overlay.mKeysByScanCode.keyAt(i), overlay.mKeysByScanCode.valueAt(i)); for (auto const& it : overlay.mKeysByScanCode) { mKeysByScanCode.insert_or_assign(it.first, it.second); } for (size_t i = 0; i < overlay.mKeysByUsageCode.size(); i++) { mKeysByUsageCode.replaceValueFor(overlay.mKeysByUsageCode.keyAt(i), overlay.mKeysByUsageCode.valueAt(i)); for (auto const& it : overlay.mKeysByUsageCode) { mKeysByUsageCode.insert_or_assign(it.first, it.second); } mLayoutOverlayApplied = true; } Loading Loading @@ -400,11 +385,26 @@ bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t return true; } void KeyCharacterMap::addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode) { if (fromKeyCode == toKeyCode) { mKeyRemapping.erase(fromKeyCode); #if DEBUG_MAPPING ALOGD("addKeyRemapping: Cleared remapping forKeyCode=%d ~ Result Successful.", fromKeyCode); #endif return; } mKeyRemapping.insert_or_assign(fromKeyCode, toKeyCode); #if DEBUG_MAPPING ALOGD("addKeyRemapping: fromKeyCode=%d, toKeyCode=%d ~ Result Successful.", fromKeyCode, toKeyCode); #endif } status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const { if (usageCode) { ssize_t index = mKeysByUsageCode.indexOfKey(usageCode); if (index >= 0) { *outKeyCode = mKeysByUsageCode.valueAt(index); const auto it = mKeysByUsageCode.find(usageCode); if (it != mKeysByUsageCode.end()) { *outKeyCode = it->second; #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); Loading @@ -413,9 +413,9 @@ status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* o } } if (scanCode) { ssize_t index = mKeysByScanCode.indexOfKey(scanCode); if (index >= 0) { *outKeyCode = mKeysByScanCode.valueAt(index); const auto it = mKeysByScanCode.find(scanCode); if (it != mKeysByScanCode.end()) { *outKeyCode = it->second; #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); Loading @@ -431,45 +431,59 @@ status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* o return NAME_NOT_FOUND; } void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState, int32_t *outKeyCode, int32_t *outMetaState) const { *outKeyCode = keyCode; *outMetaState = metaState; int32_t KeyCharacterMap::applyKeyRemapping(int32_t fromKeyCode) const { int32_t toKeyCode = fromKeyCode; const Behavior* behavior = getKeyBehavior(keyCode, metaState); const auto it = mKeyRemapping.find(fromKeyCode); if (it != mKeyRemapping.end()) { toKeyCode = it->second; } #if DEBUG_MAPPING ALOGD("applyKeyRemapping: keyCode=%d ~ replacement keyCode=%d.", fromKeyCode, toKeyCode); #endif return toKeyCode; } std::pair<int32_t, int32_t> KeyCharacterMap::applyKeyBehavior(int32_t fromKeyCode, int32_t fromMetaState) const { int32_t toKeyCode = fromKeyCode; int32_t toMetaState = fromMetaState; const Behavior* behavior = getKeyBehavior(fromKeyCode, fromMetaState); if (behavior != nullptr) { if (behavior->replacementKeyCode) { *outKeyCode = behavior->replacementKeyCode; int32_t newMetaState = metaState & ~behavior->metaState; toKeyCode = behavior->replacementKeyCode; toMetaState = fromMetaState & ~behavior->metaState; // Reset dependent meta states. if (behavior->metaState & AMETA_ALT_ON) { newMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON); toMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON); } if (behavior->metaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { newMetaState &= ~AMETA_ALT_ON; toMetaState &= ~AMETA_ALT_ON; } if (behavior->metaState & AMETA_CTRL_ON) { newMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON); toMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON); } if (behavior->metaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) { newMetaState &= ~AMETA_CTRL_ON; toMetaState &= ~AMETA_CTRL_ON; } if (behavior->metaState & AMETA_SHIFT_ON) { newMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON); toMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON); } if (behavior->metaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) { newMetaState &= ~AMETA_SHIFT_ON; toMetaState &= ~AMETA_SHIFT_ON; } // ... and put universal bits back if needed *outMetaState = normalizeMetaState(newMetaState); toMetaState = normalizeMetaState(toMetaState); } } #if DEBUG_MAPPING ALOGD("tryRemapKey: keyCode=%d, metaState=0x%08x ~ " ALOGD("applyKeyBehavior: keyCode=%d, metaState=0x%08x ~ " "replacement keyCode=%d, replacement metaState=0x%08x.", keyCode, metaState, *outKeyCode, *outMetaState); fromKeyCode, fromMetaState, toKeyCode, toMetaState); #endif return std::make_pair(toKeyCode, toMetaState); } bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { Loading Loading @@ -720,6 +734,18 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) return nullptr; } } size_t numKeyRemapping = parcel->readInt32(); if (parcel->errorCheck()) { return nullptr; } for (size_t i = 0; i < numKeyRemapping; i++) { int32_t key = parcel->readInt32(); int32_t value = parcel->readInt32(); map->mKeyRemapping.insert_or_assign(key, value); if (parcel->errorCheck()) { return nullptr; } } size_t numKeysByScanCode = parcel->readInt32(); if (parcel->errorCheck()) { return nullptr; Loading @@ -727,7 +753,7 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) for (size_t i = 0; i < numKeysByScanCode; i++) { int32_t key = parcel->readInt32(); int32_t value = parcel->readInt32(); map->mKeysByScanCode.add(key, value); map->mKeysByScanCode.insert_or_assign(key, value); if (parcel->errorCheck()) { return nullptr; } Loading @@ -739,7 +765,7 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) for (size_t i = 0; i < numKeysByUsageCode; i++) { int32_t key = parcel->readInt32(); int32_t value = parcel->readInt32(); map->mKeysByUsageCode.add(key, value); map->mKeysByUsageCode.insert_or_assign(key, value); if (parcel->errorCheck()) { return nullptr; } Loading Loading @@ -773,17 +799,23 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { } parcel->writeInt32(0); } size_t numKeyRemapping = mKeyRemapping.size(); parcel->writeInt32(numKeyRemapping); for (auto const& [fromAndroidKeyCode, toAndroidKeyCode] : mKeyRemapping) { parcel->writeInt32(fromAndroidKeyCode); parcel->writeInt32(toAndroidKeyCode); } size_t numKeysByScanCode = mKeysByScanCode.size(); parcel->writeInt32(numKeysByScanCode); for (size_t i = 0; i < numKeysByScanCode; i++) { parcel->writeInt32(mKeysByScanCode.keyAt(i)); parcel->writeInt32(mKeysByScanCode.valueAt(i)); for (auto const& [fromScanCode, toAndroidKeyCode] : mKeysByScanCode) { parcel->writeInt32(fromScanCode); parcel->writeInt32(toAndroidKeyCode); } size_t numKeysByUsageCode = mKeysByUsageCode.size(); parcel->writeInt32(numKeysByUsageCode); for (size_t i = 0; i < numKeysByUsageCode; i++) { parcel->writeInt32(mKeysByUsageCode.keyAt(i)); parcel->writeInt32(mKeysByUsageCode.valueAt(i)); for (auto const& [fromUsageCode, toAndroidKeyCode] : mKeysByUsageCode) { parcel->writeInt32(fromUsageCode); parcel->writeInt32(toAndroidKeyCode); } } #endif // __linux__ Loading Loading @@ -950,9 +982,9 @@ status_t KeyCharacterMap::Parser::parseMapKey() { mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } KeyedVector<int32_t, int32_t>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; if (map.indexOfKey(code) >= 0) { std::map<int32_t, int32_t>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; const auto it = map.find(code); if (it != map.end()) { ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; Loading @@ -971,7 +1003,7 @@ status_t KeyCharacterMap::Parser::parseMapKey() { ALOGD("Parsed map key %s: code=%d, keyCode=%d.", mapUsage ? "usage" : "scan code", code, keyCode); #endif map.add(code, keyCode); map.insert_or_assign(code, keyCode); return NO_ERROR; } Loading
services/inputflinger/include/InputReaderBase.h +3 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,9 @@ public: virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) = 0; virtual void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const = 0; virtual int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const = 0; /* Toggle Caps Lock */ Loading
services/inputflinger/reader/EventHub.cpp +26 −4 Original line number Diff line number Diff line Loading @@ -952,15 +952,19 @@ int32_t EventHub::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKey device->getKeyCharacterMap()->mapKey(scanCodes[0], 0 /*usageCode*/, &outKeyCode); switch (mapKeyRes) { case OK: return outKeyCode; break; case NAME_NOT_FOUND: // key character map doesn't re-map this scanCode, hence the keyCode remains the same return locationKeyCode; outKeyCode = locationKeyCode; break; default: ALOGW("Failed to get key code for key location: Key character map returned error %s", statusToString(mapKeyRes).c_str()); return AKEYCODE_UNKNOWN; outKeyCode = AKEYCODE_UNKNOWN; break; } // Remap if there is a Key remapping added to the KCM and return the remapped key return device->getKeyCharacterMap()->applyKeyRemapping(outKeyCode); } int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { Loading Loading @@ -1023,6 +1027,18 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t return false; } void EventHub::addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const { std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { return; } const std::shared_ptr<KeyCharacterMap> kcm = device->getKeyCharacterMap(); if (kcm) { kcm->addKeyRemapping(fromKeyCode, toKeyCode); } } status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState, int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const { std::scoped_lock _l(mLock); Loading @@ -1048,7 +1064,13 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, if (status == NO_ERROR) { if (kcm) { kcm->tryRemapKey(*outKeycode, metaState, outKeycode, outMetaState); // Remap keys based on user-defined key remappings and key behavior defined in the // corresponding kcm file *outKeycode = kcm->applyKeyRemapping(*outKeycode); // Remap keys based on Key behavior defined in KCM file std::tie(*outKeycode, *outMetaState) = kcm->applyKeyBehavior(*outKeycode, metaState); } else { *outMetaState = metaState; } Loading
services/inputflinger/reader/InputDevice.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -631,6 +631,12 @@ void InputDevice::updateMetaState(int32_t keyCode) { }); } void InputDevice::addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode) { for_each_subdevice([fromKeyCode, toKeyCode](auto& context) { context.addKeyRemapping(fromKeyCode, toKeyCode); }); } void InputDevice::bumpGeneration() { mGeneration = mContext->bumpGeneration(); } Loading