From cef0eb8ea5bbbd18af936c04803408c0a2e0a28f Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 5 Aug 2022 12:14:46 -0700 Subject: Remove unused variable outKey This output variable is never used, delete it. Bug: 238626341 Test: atest libinput_tests inputflinger_tests Change-Id: Ide7d91f83ae88b2273519eabe1e8cb58ce89a9e5 --- libs/input/KeyCharacterMap.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 2039fa6553..a5e651254b 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -304,9 +304,8 @@ char16_t KeyCharacterMap::getNumber(int32_t keyCode) const { char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const { char16_t result = 0; - const Key* key; const Behavior* behavior; - if (getKeyBehavior(keyCode, metaState, &key, &behavior)) { + if (getKeyBehavior(keyCode, metaState, &behavior)) { result = behavior->character; } #if DEBUG_MAPPING @@ -321,9 +320,8 @@ bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState, outFallbackAction->metaState = 0; bool result = false; - const Key* key; const Behavior* behavior; - if (getKeyBehavior(keyCode, metaState, &key, &behavior)) { + if (getKeyBehavior(keyCode, metaState, &behavior)) { if (behavior->fallbackKeyCode) { outFallbackAction->keyCode = behavior->fallbackKeyCode; outFallbackAction->metaState = metaState & ~behavior->metaState; @@ -438,9 +436,8 @@ void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState, *outKeyCode = keyCode; *outMetaState = metaState; - const Key* key; const Behavior* behavior; - if (getKeyBehavior(keyCode, metaState, &key, &behavior)) { + if (getKeyBehavior(keyCode, metaState, &behavior)) { if (behavior->replacementKeyCode) { *outKeyCode = behavior->replacementKeyCode; int32_t newMetaState = metaState & ~behavior->metaState; @@ -485,13 +482,12 @@ bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { } bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState, - const Key** outKey, const Behavior** outBehavior) const { + const Behavior** outBehavior) const { const Key* key; if (getKey(keyCode, &key)) { const Behavior* behavior = key->firstBehavior; while (behavior) { if (matchesMetaState(metaState, behavior->metaState)) { - *outKey = key; *outBehavior = behavior; return true; } -- cgit v1.2.3-59-g8ed1b From 12300c14b96851ce39ea78d03c103a2dc2db9e01 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 5 Aug 2022 12:30:36 -0700 Subject: Return pointer from getKeyBehavior This function returns bool and outPointer, which is redundant. Return pointer directly. Bug: 238626341 Test: atest libinput_tests inputflinger_tests Change-Id: I7b945cd3a485afbb3f0ef0aef489e87e8358f4a7 --- include/input/KeyCharacterMap.h | 2 +- libs/input/KeyCharacterMap.cpp | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index c2afb014e1..585ea3c315 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -240,7 +240,7 @@ private: KeyCharacterMap(const std::string& filename); bool getKey(int32_t keyCode, const Key** outKey) const; - bool getKeyBehavior(int32_t keyCode, int32_t metaState, const Behavior** outBehavior) const; + const Behavior* getKeyBehavior(int32_t keyCode, int32_t metaState) const; static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState); bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const; diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index a5e651254b..5cb844eb19 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -304,8 +304,8 @@ char16_t KeyCharacterMap::getNumber(int32_t keyCode) const { char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const { char16_t result = 0; - const Behavior* behavior; - if (getKeyBehavior(keyCode, metaState, &behavior)) { + const Behavior* behavior = getKeyBehavior(keyCode, metaState); + if (behavior != nullptr) { result = behavior->character; } #if DEBUG_MAPPING @@ -320,8 +320,8 @@ bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState, outFallbackAction->metaState = 0; bool result = false; - const Behavior* behavior; - if (getKeyBehavior(keyCode, metaState, &behavior)) { + const Behavior* behavior = getKeyBehavior(keyCode, metaState); + if (behavior != nullptr) { if (behavior->fallbackKeyCode) { outFallbackAction->keyCode = behavior->fallbackKeyCode; outFallbackAction->metaState = metaState & ~behavior->metaState; @@ -436,8 +436,8 @@ void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState, *outKeyCode = keyCode; *outMetaState = metaState; - const Behavior* behavior; - if (getKeyBehavior(keyCode, metaState, &behavior)) { + const Behavior* behavior = getKeyBehavior(keyCode, metaState); + if (behavior != nullptr) { if (behavior->replacementKeyCode) { *outKeyCode = behavior->replacementKeyCode; int32_t newMetaState = metaState & ~behavior->metaState; @@ -481,20 +481,19 @@ bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { return false; } -bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState, - const Behavior** outBehavior) const { +const KeyCharacterMap::Behavior* KeyCharacterMap::getKeyBehavior(int32_t keyCode, + int32_t metaState) const { const Key* key; if (getKey(keyCode, &key)) { const Behavior* behavior = key->firstBehavior; while (behavior) { if (matchesMetaState(metaState, behavior->metaState)) { - *outBehavior = behavior; - return true; + return behavior; } behavior = behavior->next; } } - return false; + return nullptr; } bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) { -- cgit v1.2.3-59-g8ed1b From aa9e9d25f15c100e7da87f6465ba50b45f7bf552 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 5 Aug 2022 11:13:31 -0700 Subject: Use std::list to store Behavior objects There's a bug about behavior being null. It's not clear how it gets there, but before this CL, there was a custom implementation of linked list to store the behaviours. Instead of implementing a custom linked list, let's switch over to std::list to remove the possibility of this bug. Bug: 238626341 Test: atest libinput_tests inputflinger_tests KeyCharacterMapTest Change-Id: I98e20de7d40b74e4af085cdafb68f867e6ebfe19 --- include/input/KeyCharacterMap.h | 18 +++---- libs/input/KeyCharacterMap.cpp | 115 +++++++++++++--------------------------- 2 files changed, 44 insertions(+), 89 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index 585ea3c315..1c9a5eaac1 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -18,6 +18,7 @@ #define _LIBINPUT_KEY_CHARACTER_MAP_H #include +#include #ifdef __linux__ #include @@ -152,29 +153,22 @@ public: private: struct Behavior { - Behavior(); - Behavior(const Behavior& other); - - /* The next behavior in the list, or NULL if none. */ - Behavior* next; - /* The meta key modifiers for this behavior. */ - int32_t metaState; + int32_t metaState = 0; /* The character to insert. */ - char16_t character; + char16_t character = 0; /* The fallback keycode if the key is not handled. */ - int32_t fallbackKeyCode; + int32_t fallbackKeyCode = 0; /* The replacement keycode if the key has to be replaced outright. */ - int32_t replacementKeyCode; + int32_t replacementKeyCode = 0; }; struct Key { Key(); Key(const Key& other); - ~Key(); /* The single character label printed on the key, or 0 if none. */ char16_t label; @@ -184,7 +178,7 @@ private: /* The list of key behaviors sorted from most specific to least specific * meta key binding. */ - Behavior* firstBehavior; + std::list behaviors; }; class Parser { diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 5cb844eb19..422e6e09eb 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -345,12 +345,12 @@ char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_ // Try to find the most general behavior that maps to this character. // For example, the base key behavior will usually be last in the list. // However, if we find a perfect meta state match for one behavior then use that one. - for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) { - if (behavior->character) { + for (const Behavior& behavior : key->behaviors) { + if (behavior.character) { for (size_t i = 0; i < numChars; i++) { - if (behavior->character == chars[i]) { - result = behavior->character; - if ((behavior->metaState & metaState) == behavior->metaState) { + if (behavior.character == chars[i]) { + result = behavior.character; + if ((behavior.metaState & metaState) == behavior.metaState) { goto ExactMatch; } break; @@ -485,12 +485,10 @@ const KeyCharacterMap::Behavior* KeyCharacterMap::getKeyBehavior(int32_t keyCode int32_t metaState) const { const Key* key; if (getKey(keyCode, &key)) { - const Behavior* behavior = key->firstBehavior; - while (behavior) { - if (matchesMetaState(metaState, behavior->metaState)) { - return behavior; + for (const Behavior& behavior : key->behaviors) { + if (matchesMetaState(metaState, behavior.metaState)) { + return &behavior; } - behavior = behavior->next; } } return nullptr; @@ -538,12 +536,12 @@ bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMeta // Try to find the most general behavior that maps to this character. // For example, the base key behavior will usually be last in the list. const Behavior* found = nullptr; - for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) { - if (behavior->character == ch) { - found = behavior; + for (const Behavior& behavior : key->behaviors) { + if (behavior.character == ch) { + found = &behavior; } } - if (found) { + if (found != nullptr) { *outKeyCode = mKeys.keyAt(i); *outMetaState = found->metaState; return true; @@ -701,7 +699,6 @@ std::shared_ptr KeyCharacterMap::readFromParcel(Parcel* parcel) key->number = number; map->mKeys.add(keyCode, key); - Behavior* lastBehavior = nullptr; while (parcel->readInt32()) { int32_t metaState = parcel->readInt32(); char16_t character = parcel->readInt32(); @@ -711,17 +708,12 @@ std::shared_ptr KeyCharacterMap::readFromParcel(Parcel* parcel) return nullptr; } - Behavior* behavior = new Behavior(); - behavior->metaState = metaState; - behavior->character = character; - behavior->fallbackKeyCode = fallbackKeyCode; - behavior->replacementKeyCode = replacementKeyCode; - if (lastBehavior) { - lastBehavior->next = behavior; - } else { - key->firstBehavior = behavior; - } - lastBehavior = behavior; + key->behaviors.push_back({ + .metaState = metaState, + .character = character, + .fallbackKeyCode = fallbackKeyCode, + .replacementKeyCode = replacementKeyCode, + }); } if (parcel->errorCheck()) { @@ -772,13 +764,12 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { parcel->writeInt32(keyCode); parcel->writeInt32(key->label); parcel->writeInt32(key->number); - for (const Behavior* behavior = key->firstBehavior; behavior != nullptr; - behavior = behavior->next) { + for (const Behavior& behavior : key->behaviors) { parcel->writeInt32(1); - parcel->writeInt32(behavior->metaState); - parcel->writeInt32(behavior->character); - parcel->writeInt32(behavior->fallbackKeyCode); - parcel->writeInt32(behavior->replacementKeyCode); + parcel->writeInt32(behavior.metaState); + parcel->writeInt32(behavior.character); + parcel->writeInt32(behavior.fallbackKeyCode); + parcel->writeInt32(behavior.replacementKeyCode); } parcel->writeInt32(0); } @@ -799,38 +790,10 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { // --- KeyCharacterMap::Key --- -KeyCharacterMap::Key::Key() : - label(0), number(0), firstBehavior(nullptr) { -} - -KeyCharacterMap::Key::Key(const Key& other) : - label(other.label), number(other.number), - firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : nullptr) { -} - -KeyCharacterMap::Key::~Key() { - Behavior* behavior = firstBehavior; - while (behavior) { - Behavior* next = behavior->next; - delete behavior; - behavior = next; - } -} - - -// --- KeyCharacterMap::Behavior --- - -KeyCharacterMap::Behavior::Behavior() : - next(nullptr), metaState(0), character(0), fallbackKeyCode(0), replacementKeyCode(0) { -} - -KeyCharacterMap::Behavior::Behavior(const Behavior& other) : - next(other.next ? new Behavior(*other.next) : nullptr), - metaState(other.metaState), character(other.character), - fallbackKeyCode(other.fallbackKeyCode), - replacementKeyCode(other.replacementKeyCode) { -} +KeyCharacterMap::Key::Key() : label(0), number(0) {} +KeyCharacterMap::Key::Key(const Key& other) + : label(other.label), number(other.number), behaviors(other.behaviors) {} // --- KeyCharacterMap::Parser --- @@ -1208,23 +1171,21 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { #endif break; case PROPERTY_META: { - for (Behavior* b = key->firstBehavior; b; b = b->next) { - if (b->metaState == property.metaState) { + for (const Behavior& b : key->behaviors) { + if (b.metaState == property.metaState) { ALOGE("%s: Duplicate key behavior for modifier.", mTokenizer->getLocation().string()); return BAD_VALUE; } } - Behavior* newBehavior = new Behavior(behavior); - newBehavior->metaState = property.metaState; - newBehavior->next = key->firstBehavior; - key->firstBehavior = newBehavior; -#if DEBUG_PARSER - ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.", - mKeyCode, - newBehavior->metaState, newBehavior->character, - newBehavior->fallbackKeyCode, newBehavior->replacementKeyCode); -#endif + Behavior newBehavior = behavior; + newBehavior.metaState = property.metaState; + key->behaviors.push_front(newBehavior); + ALOGD_IF(DEBUG_PARSER, + "Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.", + mKeyCode, key->behaviors.front().metaState, key->behaviors.front().character, + key->behaviors.front().fallbackKeyCode, + key->behaviors.front().replacementKeyCode); break; } } @@ -1237,8 +1198,8 @@ status_t KeyCharacterMap::Parser::finishKey(Key* key) { if (!key->number) { char16_t digit = 0; char16_t symbol = 0; - for (Behavior* b = key->firstBehavior; b; b = b->next) { - char16_t ch = b->character; + for (const Behavior& b : key->behaviors) { + char16_t ch = b.character; if (ch) { if (ch >= '0' && ch <= '9') { digit = ch; -- cgit v1.2.3-59-g8ed1b From cbba14c55c15ab3d41a4427fbb2406e6d0ade4b2 Mon Sep 17 00:00:00 2001 From: Vaibhav Devmurari Date: Mon, 10 Oct 2022 16:54:49 +0000 Subject: Add API to support key remappings on native side For adding support for modifier key remapping, we need to add native support save key remappings and send appropriate android key codes using KeyCharacterMap. Test: atest KeyboardLayoutChangeTest Bug: 252812993 Change-Id: Ib3efa866c6e6408dd11e97dfaf49feb92f48bc18 --- include/input/KeyCharacterMap.h | 20 ++- libs/input/KeyCharacterMap.cpp | 150 +++++++++++++-------- services/inputflinger/include/InputReaderBase.h | 3 + services/inputflinger/reader/EventHub.cpp | 30 ++++- services/inputflinger/reader/InputDevice.cpp | 6 + services/inputflinger/reader/InputReader.cpp | 9 ++ services/inputflinger/reader/include/EventHub.h | 6 + services/inputflinger/reader/include/InputDevice.h | 6 + services/inputflinger/reader/include/InputReader.h | 2 + services/inputflinger/tests/FakeEventHub.cpp | 8 +- services/inputflinger/tests/FakeEventHub.h | 2 + services/inputflinger/tests/InputReader_test.cpp | 21 +++ .../tests/fuzzers/InputReaderFuzzer.cpp | 4 + .../inputflinger/tests/fuzzers/MapperHelpers.h | 1 + 14 files changed, 198 insertions(+), 70 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index dc928b806f..867a08955c 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -125,14 +125,21 @@ public: bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, Vector& 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 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 applyKeyBehavior(int32_t keyCode, + int32_t metaState) const; #ifdef __linux__ /* Reads a key map from a parcel. */ @@ -227,8 +234,9 @@ private: std::string mLoadFileName; bool mLayoutOverlayApplied; - KeyedVector mKeysByScanCode; - KeyedVector mKeysByUsageCode; + std::map mKeyRemapping; + std::map mKeysByScanCode; + std::map mKeysByUsageCode; KeyCharacterMap(const std::string& filename); diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 422e6e09eb..fa5c41f657 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -43,7 +43,6 @@ // Enables debug output for mapping. #define DEBUG_MAPPING 0 - namespace android { static const char* WHITESPACE = " \t\r"; @@ -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++) { @@ -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; @@ -131,22 +131,9 @@ 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)) { - return false; - } - if (mKeysByUsageCode.valueAt(i) != other.mKeysByUsageCode.valueAt(i)) { - return false; - } + if (mKeyRemapping != other.mKeyRemapping || mKeysByScanCode != other.mKeysByScanCode || + mKeysByUsageCode != other.mKeysByUsageCode) { + return false; } return true; @@ -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; } @@ -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); @@ -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); @@ -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 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 ~ " - "replacement keyCode=%d, replacement metaState=0x%08x.", - keyCode, metaState, *outKeyCode, *outMetaState); + ALOGD("applyKeyBehavior: keyCode=%d, metaState=0x%08x ~ " + "replacement keyCode=%d, replacement metaState=0x%08x.", + fromKeyCode, fromMetaState, toKeyCode, toMetaState); #endif + return std::make_pair(toKeyCode, toMetaState); } bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { @@ -720,6 +734,18 @@ std::shared_ptr 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; @@ -727,7 +753,7 @@ std::shared_ptr 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; } @@ -739,7 +765,7 @@ std::shared_ptr 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; } @@ -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__ @@ -950,9 +982,9 @@ status_t KeyCharacterMap::Parser::parseMapKey() { mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } - KeyedVector& map = - mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; - if (map.indexOfKey(code) >= 0) { + std::map& 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; @@ -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; } diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h index 6d6cefb0c0..b8a6dade34 100644 --- a/services/inputflinger/include/InputReaderBase.h +++ b/services/inputflinger/include/InputReaderBase.h @@ -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 */ diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp index f2ea90c291..e26bc8c6dc 100644 --- a/services/inputflinger/reader/EventHub.cpp +++ b/services/inputflinger/reader/EventHub.cpp @@ -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 { @@ -1023,6 +1027,18 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, const std::vector 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); @@ -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; } diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp index 150a8aac0d..e9a94b3a42 100644 --- a/services/inputflinger/reader/InputDevice.cpp +++ b/services/inputflinger/reader/InputDevice.cpp @@ -624,6 +624,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(); } diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index f04a6469ea..57f679c022 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -650,6 +650,15 @@ bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceM return result; } +void InputReader::addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const { + std::scoped_lock _l(mLock); + + InputDevice* device = findInputDeviceLocked(deviceId); + if (device != nullptr) { + device->addKeyRemapping(fromKeyCode, toKeyCode); + } +} + int32_t InputReader::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const { std::scoped_lock _l(mLock); diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h index 42ca482a68..8a844b2088 100644 --- a/services/inputflinger/reader/include/EventHub.h +++ b/services/inputflinger/reader/include/EventHub.h @@ -262,6 +262,9 @@ public: virtual bool hasMscEvent(int32_t deviceId, int mscEvent) const = 0; + virtual void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, + int32_t toKeyCode) const = 0; + virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState, int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const = 0; @@ -460,6 +463,9 @@ public: bool hasMscEvent(int32_t deviceId, int mscEvent) const override final; + void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, + int32_t toKeyCode) const override final; + status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState, int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override final; diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h index 439123bf1d..6fa21e5362 100644 --- a/services/inputflinger/reader/include/InputDevice.h +++ b/services/inputflinger/reader/include/InputDevice.h @@ -114,6 +114,8 @@ public: int32_t getMetaState(); void updateMetaState(int32_t keyCode); + void addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode); + void bumpGeneration(); [[nodiscard]] NotifyDeviceResetArgs notifyReset(nsecs_t when); @@ -278,6 +280,10 @@ public: inline bool hasMscEvent(int mscEvent) const { return mEventHub->hasMscEvent(mId, mscEvent); } + inline void addKeyRemapping(int32_t fromKeyCode, int32_t toKeyCode) const { + mEventHub->addKeyRemapping(mId, fromKeyCode, toKeyCode); + } + inline status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t metaState, int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const { return mEventHub->mapKey(mId, scanCode, usageCode, metaState, outKeycode, outMetaState, diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h index 4f2503ad5c..e9c989a224 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -68,6 +68,8 @@ public: int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) override; int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) override; + void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const override; + int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override; void toggleCapsLockState(int32_t deviceId) override; diff --git a/services/inputflinger/tests/FakeEventHub.cpp b/services/inputflinger/tests/FakeEventHub.cpp index f6cf1cc304..289a7809cc 100644 --- a/services/inputflinger/tests/FakeEventHub.cpp +++ b/services/inputflinger/tests/FakeEventHub.cpp @@ -154,6 +154,11 @@ void FakeEventHub::addKeyCodeMapping(int32_t deviceId, int32_t fromKeyCode, int3 getDevice(deviceId)->keyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode); } +void FakeEventHub::addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const { + Device* device = getDevice(deviceId); + device->keyRemapping.insert_or_assign(fromKeyCode, toKeyCode); +} + void FakeEventHub::addLed(int32_t deviceId, int32_t led, bool initialState) { getDevice(deviceId)->leds.add(led, initialState); } @@ -299,7 +304,8 @@ status_t FakeEventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageC const KeyInfo* key = getKey(device, scanCode, usageCode); if (key) { if (outKeycode) { - *outKeycode = key->keyCode; + auto it = device->keyRemapping.find(key->keyCode); + *outKeycode = it != device->keyRemapping.end() ? it->second : key->keyCode; } if (outFlags) { *outFlags = key->flags; diff --git a/services/inputflinger/tests/FakeEventHub.h b/services/inputflinger/tests/FakeEventHub.h index 21cb2f1963..fb3c8596c7 100644 --- a/services/inputflinger/tests/FakeEventHub.h +++ b/services/inputflinger/tests/FakeEventHub.h @@ -59,6 +59,7 @@ class FakeEventHub : public EventHubInterface { KeyedVector absoluteAxisValue; KeyedVector keysByScanCode; KeyedVector keysByUsageCode; + std::unordered_map keyRemapping; KeyedVector leds; // fake mapping which would normally come from keyCharacterMap std::unordered_map keyCodeMapping; @@ -132,6 +133,7 @@ public: void addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t keyCode, uint32_t flags); void addKeyCodeMapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode); + void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const; void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition); void addSensorAxis(int32_t deviceId, int32_t absCode, InputDeviceSensorType sensorType, diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index eef56902c7..4cc48f6fc3 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -2912,6 +2912,27 @@ TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) { ASSERT_EQ(ARBITRARY_TIME, args.downTime); } +TEST_F(KeyboardInputMapperTest, Process_KeyRemapping) { + mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0); + mFakeEventHub->addKey(EVENTHUB_ID, KEY_B, 0, AKEYCODE_B, 0); + mFakeEventHub->addKeyRemapping(EVENTHUB_ID, AKEYCODE_A, AKEYCODE_B); + + KeyboardInputMapper& mapper = + addMapperAndConfigure(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); + + // Key down by scan code. + process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_A, 1); + NotifyKeyArgs args; + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); + ASSERT_EQ(AKEYCODE_B, args.keyCode); + + // Key up by scan code. + process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 0); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); + ASSERT_EQ(AKEYCODE_B, args.keyCode); +} + /** * Ensure that the readTime is set to the time when the EV_KEY is received. */ diff --git a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp index 2eed9977be..057c15d6b8 100644 --- a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp +++ b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp @@ -153,6 +153,10 @@ public: return reader->getLightPlayerId(deviceId, lightId); } + void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const { + reader->addKeyRemapping(deviceId, fromKeyCode, toKeyCode); + } + int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const { return reader->getKeyCodeForKeyLocation(deviceId, locationKeyCode); } diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h index 445ed182fe..cd852d668c 100644 --- a/services/inputflinger/tests/fuzzers/MapperHelpers.h +++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h @@ -211,6 +211,7 @@ public: int32_t getSwitchState(int32_t deviceId, int32_t sw) const override { return mFdp->ConsumeIntegral(); } + void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const override {} int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override { return mFdp->ConsumeIntegral(); } -- cgit v1.2.3-59-g8ed1b From 23e8ae9cf2793b83e220adec4cf6dec35e090e53 Mon Sep 17 00:00:00 2001 From: Vaibhav Devmurari Date: Thu, 29 Dec 2022 12:07:56 +0000 Subject: Clear applied layout overlay if new layout overlay is null. Need to allow resetting of key character map by setting overlay map to null. This is required when moving from a IME setting that has a KCM to another IME setting that has none. Test: atest KeyboardLayoutChangeTest Bug: 20805588 Change-Id: I62dc65970b61628486aff698a8ab8ccb31c109d6 --- include/input/KeyCharacterMap.h | 3 +++ libs/input/KeyCharacterMap.cpp | 7 +++++++ services/inputflinger/reader/EventHub.cpp | 7 ++++++- 3 files changed, 16 insertions(+), 1 deletion(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index 867a08955c..b5e6f65e48 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -87,6 +87,9 @@ public: /* Combines this key character map with the provided overlay. */ void combine(const KeyCharacterMap& overlay); + /* Clears already applied layout overlay */ + void clearLayoutOverlay(); + /* Gets the keyboard type. */ KeyboardType getKeyboardType() const; diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index fa5c41f657..6bfac40932 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -255,6 +255,13 @@ void KeyCharacterMap::combine(const KeyCharacterMap& overlay) { mLayoutOverlayApplied = true; } +void KeyCharacterMap::clearLayoutOverlay() { + if (mLayoutOverlayApplied) { + reloadBaseFromFile(); + mLayoutOverlayApplied = false; + } +} + KeyCharacterMap::KeyboardType KeyCharacterMap::getKeyboardType() const { return mType; } diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp index b214750443..43b67cae8b 100644 --- a/services/inputflinger/reader/EventHub.cpp +++ b/services/inputflinger/reader/EventHub.cpp @@ -1416,12 +1416,17 @@ const std::shared_ptr EventHub::getKeyCharacterMap(int32_t devi return nullptr; } +// If provided map is null, it will reset key character map to default KCM. bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId, std::shared_ptr map) { std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device == nullptr || map == nullptr || device->keyMap.keyCharacterMap == nullptr) { + if (device == nullptr || device->keyMap.keyCharacterMap == nullptr) { return false; } + if (map == nullptr) { + device->keyMap.keyCharacterMap->clearLayoutOverlay(); + return true; + } device->keyMap.keyCharacterMap->combine(*map); return true; } -- cgit v1.2.3-59-g8ed1b From 5df3493d3cf633f8ac7447bc5474a0dfbc1a8359 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 23 Jan 2023 12:41:01 -0800 Subject: Validate axes and led labels correctly Before this CL, a number of checks for kl file validity were incorrect. Some of the APIs were supposed to return an invalid value, but instead were always returning a valid value, no matter what the input was. Correct these values by switching to std::optional. Bug: 266400536 Test: m libinput_tests && adb sync data && adb shell -t /data/nativetest64/libinput_tests/libinput_tests Change-Id: I4ef45f3249dca4f4f033fb85e9fecbc2ad1f1395 --- include/input/Input.h | 4 +- include/input/InputEventLabels.h | 12 ++-- libs/input/Input.cpp | 4 +- libs/input/InputEventLabels.cpp | 22 +++---- libs/input/KeyCharacterMap.cpp | 24 ++++---- libs/input/KeyLayoutMap.cpp | 106 +++++++++++++++++++------------- libs/input/tests/InputDevice_test.cpp | 14 +++++ libs/input/tests/data/bad_axis_label.kl | 17 +++++ libs/input/tests/data/bad_led_label.kl | 17 +++++ 9 files changed, 142 insertions(+), 78 deletions(-) create mode 100644 libs/input/tests/data/bad_axis_label.kl create mode 100644 libs/input/tests/data/bad_led_label.kl (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/Input.h b/include/input/Input.h index 30b0d6a67a..7573282fc1 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -529,7 +529,7 @@ public: inline nsecs_t getEventTime() const { return mEventTime; } static const char* getLabel(int32_t keyCode); - static int32_t getKeyCodeFromLabel(const char* label); + static std::optional getKeyCodeFromLabel(const char* label); void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId, std::array hmac, int32_t action, int32_t flags, int32_t keyCode, @@ -842,7 +842,7 @@ public: } static const char* getLabel(int32_t axis); - static int32_t getAxisFromLabel(const char* label); + static std::optional getAxisFromLabel(const char* label); static std::string actionToString(int32_t action); diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h index b4374acdcc..4668fce116 100644 --- a/include/input/InputEventLabels.h +++ b/include/input/InputEventLabels.h @@ -35,22 +35,22 @@ struct InputEventLabel { class InputEventLookup { public: - static int lookupValueByLabel(const std::unordered_map& map, - const char* literal); + static std::optional lookupValueByLabel(const std::unordered_map& map, + const char* literal); static const char* lookupLabelByValue(const std::vector& vec, int value); - static int32_t getKeyCodeByLabel(const char* label); + static std::optional getKeyCodeByLabel(const char* label); static const char* getLabelByKeyCode(int32_t keyCode); - static uint32_t getKeyFlagByLabel(const char* label); + static std::optional getKeyFlagByLabel(const char* label); - static int32_t getAxisByLabel(const char* label); + static std::optional getAxisByLabel(const char* label); static const char* getAxisLabel(int32_t axisId); - static int32_t getLedByLabel(const char* label); + static std::optional getLedByLabel(const char* label); private: static const std::unordered_map KEYCODES; diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index c356c2e5e9..133b260a61 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -299,7 +299,7 @@ const char* KeyEvent::getLabel(int32_t keyCode) { return InputEventLookup::getLabelByKeyCode(keyCode); } -int32_t KeyEvent::getKeyCodeFromLabel(const char* label) { +std::optional KeyEvent::getKeyCodeFromLabel(const char* label) { return InputEventLookup::getKeyCodeByLabel(label); } @@ -891,7 +891,7 @@ const char* MotionEvent::getLabel(int32_t axis) { return InputEventLookup::getAxisLabel(axis); } -int32_t MotionEvent::getAxisFromLabel(const char* label) { +std::optional MotionEvent::getAxisFromLabel(const char* label) { return InputEventLookup::getAxisByLabel(label); } diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp index 7159e27b13..d97c1bb629 100644 --- a/libs/input/InputEventLabels.cpp +++ b/libs/input/InputEventLabels.cpp @@ -438,11 +438,11 @@ const std::unordered_map InputEventLookup::LEDS = {LEDS_SEQUEN const std::unordered_map InputEventLookup::FLAGS = {FLAGS_SEQUENCE}; -int InputEventLookup::lookupValueByLabel(const std::unordered_map& map, - const char* literal) { +std::optional InputEventLookup::lookupValueByLabel( + const std::unordered_map& map, const char* literal) { std::string str(literal); auto it = map.find(str); - return it != map.end() ? it->second : 0; + return it != map.end() ? std::make_optional(it->second) : std::nullopt; } const char* InputEventLookup::lookupLabelByValue(const std::vector& vec, @@ -453,8 +453,8 @@ const char* InputEventLookup::lookupLabelByValue(const std::vector InputEventLookup::getKeyCodeByLabel(const char* label) { + return lookupValueByLabel(KEYCODES, label); } const char* InputEventLookup::getLabelByKeyCode(int32_t keyCode) { @@ -464,20 +464,20 @@ const char* InputEventLookup::getLabelByKeyCode(int32_t keyCode) { return nullptr; } -uint32_t InputEventLookup::getKeyFlagByLabel(const char* label) { - return uint32_t(lookupValueByLabel(FLAGS, label)); +std::optional InputEventLookup::getKeyFlagByLabel(const char* label) { + return lookupValueByLabel(FLAGS, label); } -int32_t InputEventLookup::getAxisByLabel(const char* label) { - return int32_t(lookupValueByLabel(AXES, label)); +std::optional InputEventLookup::getAxisByLabel(const char* label) { + return lookupValueByLabel(AXES, label); } const char* InputEventLookup::getAxisLabel(int32_t axisId) { return lookupLabelByValue(AXES_NAMES, axisId); } -int32_t InputEventLookup::getLedByLabel(const char* label) { - return int32_t(lookupValueByLabel(LEDS, label)); +std::optional InputEventLookup::getLedByLabel(const char* label) { + return lookupValueByLabel(LEDS, label); } } // namespace android diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 6bfac40932..737bd15901 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -999,7 +999,7 @@ status_t KeyCharacterMap::Parser::parseMapKey() { mTokenizer->skipDelimiters(WHITESPACE); String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); + std::optional keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); @@ -1010,19 +1010,19 @@ status_t KeyCharacterMap::Parser::parseMapKey() { ALOGD("Parsed map key %s: code=%d, keyCode=%d.", mapUsage ? "usage" : "scan code", code, keyCode); #endif - map.insert_or_assign(code, keyCode); + map.insert_or_assign(code, *keyCode); return NO_ERROR; } status_t KeyCharacterMap::Parser::parseKey() { String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); + std::optional keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); return BAD_VALUE; } - if (mMap->mKeys.indexOfKey(keyCode) >= 0) { + if (mMap->mKeys.indexOfKey(*keyCode) >= 0) { ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); return BAD_VALUE; @@ -1036,11 +1036,9 @@ status_t KeyCharacterMap::Parser::parseKey() { return BAD_VALUE; } -#if DEBUG_PARSER - ALOGD("Parsed beginning of key: keyCode=%d.", keyCode); -#endif - mKeyCode = keyCode; - mMap->mKeys.add(keyCode, new Key()); + ALOGD_IF(DEBUG_PARSER, "Parsed beginning of key: keyCode=%d.", *keyCode); + mKeyCode = *keyCode; + mMap->mKeys.add(*keyCode, new Key()); mState = STATE_KEY; return NO_ERROR; } @@ -1136,7 +1134,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { } else if (token == "fallback") { mTokenizer->skipDelimiters(WHITESPACE); token = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string()); + std::optional keyCode = InputEventLookup::getKeyCodeByLabel(token.string()); if (!keyCode) { ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.", mTokenizer->getLocation().string(), @@ -1148,12 +1146,12 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { mTokenizer->getLocation().string()); return BAD_VALUE; } - behavior.fallbackKeyCode = keyCode; + behavior.fallbackKeyCode = *keyCode; haveFallback = true; } else if (token == "replace") { mTokenizer->skipDelimiters(WHITESPACE); token = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string()); + std::optional keyCode = InputEventLookup::getKeyCodeByLabel(token.string()); if (!keyCode) { ALOGE("%s: Invalid key code label for replace, got '%s'.", mTokenizer->getLocation().string(), @@ -1170,7 +1168,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { mTokenizer->getLocation().string()); return BAD_VALUE; } - behavior.replacementKeyCode = keyCode; + behavior.replacementKeyCode = *keyCode; haveReplacement = true; } else { diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp index 73710330d0..a2649f6f11 100644 --- a/libs/input/KeyLayoutMap.cpp +++ b/libs/input/KeyLayoutMap.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "KeyLayoutMap" +#include #include #include #include @@ -54,6 +55,21 @@ const bool DEBUG_MAPPING = namespace android { namespace { +std::optional parseInt(const char* str) { + char* end; + errno = 0; + const int value = strtol(str, &end, 0); + if (end == str) { + LOG(ERROR) << "Could not parse " << str; + return {}; + } + if (errno == ERANGE) { + LOG(ERROR) << "Out of bounds: " << str; + return {}; + } + return value; +} + constexpr const char* WHITESPACE = " \t\r"; template @@ -336,16 +352,15 @@ status_t KeyLayoutMap::Parser::parseKey() { codeToken = mTokenizer->nextToken(WHITESPACE); } - char* end; - int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); - if (*end) { + std::optional code = parseInt(codeToken.string()); + if (!code) { ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } std::unordered_map& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; - if (map.find(code) != map.end()) { + if (map.find(*code) != map.end()) { ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; @@ -353,7 +368,7 @@ status_t KeyLayoutMap::Parser::parseKey() { mTokenizer->skipDelimiters(WHITESPACE); String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); + std::optional keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); @@ -366,40 +381,39 @@ status_t KeyLayoutMap::Parser::parseKey() { if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break; String8 flagToken = mTokenizer->nextToken(WHITESPACE); - uint32_t flag = InputEventLookup::getKeyFlagByLabel(flagToken.string()); + std::optional flag = InputEventLookup::getKeyFlagByLabel(flagToken.string()); if (!flag) { ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(), flagToken.string()); return BAD_VALUE; } - if (flags & flag) { + if (flags & *flag) { ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(), flagToken.string()); return BAD_VALUE; } - flags |= flag; + flags |= *flag; } ALOGD_IF(DEBUG_PARSER, "Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.", - mapUsage ? "usage" : "scan code", code, keyCode, flags); + mapUsage ? "usage" : "scan code", *code, *keyCode, flags); Key key; - key.keyCode = keyCode; + key.keyCode = *keyCode; key.flags = flags; - map.insert({code, key}); + map.insert({*code, key}); return NO_ERROR; } status_t KeyLayoutMap::Parser::parseAxis() { String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE); - char* end; - int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0)); - if (*end) { + std::optional scanCode = parseInt(scanCodeToken.string()); + if (!scanCode) { ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(), scanCodeToken.string()); return BAD_VALUE; } - if (mMap->mAxes.find(scanCode) != mMap->mAxes.end()) { + if (mMap->mAxes.find(*scanCode) != mMap->mAxes.end()) { ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(), scanCodeToken.string()); return BAD_VALUE; @@ -414,48 +428,53 @@ status_t KeyLayoutMap::Parser::parseAxis() { mTokenizer->skipDelimiters(WHITESPACE); String8 axisToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.axis = InputEventLookup::getAxisByLabel(axisToken.string()); - if (axisInfo.axis < 0) { + std::optional axis = InputEventLookup::getAxisByLabel(axisToken.string()); + if (!axis) { ALOGE("%s: Expected inverted axis label, got '%s'.", mTokenizer->getLocation().string(), axisToken.string()); return BAD_VALUE; } + axisInfo.axis = *axis; } else if (token == "split") { axisInfo.mode = AxisInfo::MODE_SPLIT; mTokenizer->skipDelimiters(WHITESPACE); String8 splitToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0)); - if (*end) { + std::optional splitValue = parseInt(splitToken.string()); + if (!splitValue) { ALOGE("%s: Expected split value, got '%s'.", mTokenizer->getLocation().string(), splitToken.string()); return BAD_VALUE; } + axisInfo.splitValue = *splitValue; mTokenizer->skipDelimiters(WHITESPACE); String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.axis = InputEventLookup::getAxisByLabel(lowAxisToken.string()); - if (axisInfo.axis < 0) { + std::optional axis = InputEventLookup::getAxisByLabel(lowAxisToken.string()); + if (!axis) { ALOGE("%s: Expected low axis label, got '%s'.", mTokenizer->getLocation().string(), lowAxisToken.string()); return BAD_VALUE; } + axisInfo.axis = *axis; mTokenizer->skipDelimiters(WHITESPACE); String8 highAxisToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.highAxis = InputEventLookup::getAxisByLabel(highAxisToken.string()); - if (axisInfo.highAxis < 0) { + std::optional highAxis = InputEventLookup::getAxisByLabel(highAxisToken.string()); + if (!highAxis) { ALOGE("%s: Expected high axis label, got '%s'.", mTokenizer->getLocation().string(), highAxisToken.string()); return BAD_VALUE; } + axisInfo.highAxis = *highAxis; } else { - axisInfo.axis = InputEventLookup::getAxisByLabel(token.string()); - if (axisInfo.axis < 0) { + std::optional axis = InputEventLookup::getAxisByLabel(token.string()); + if (!axis) { ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.", mTokenizer->getLocation().string(), token.string()); return BAD_VALUE; } + axisInfo.axis = *axis; } for (;;) { @@ -467,12 +486,13 @@ status_t KeyLayoutMap::Parser::parseAxis() { if (keywordToken == "flat") { mTokenizer->skipDelimiters(WHITESPACE); String8 flatToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0)); - if (*end) { + std::optional flatOverride = parseInt(flatToken.string()); + if (!flatOverride) { ALOGE("%s: Expected flat value, got '%s'.", mTokenizer->getLocation().string(), flatToken.string()); return BAD_VALUE; } + axisInfo.flatOverride = *flatOverride; } else { ALOGE("%s: Expected keyword 'flat', got '%s'.", mTokenizer->getLocation().string(), keywordToken.string()); @@ -483,9 +503,9 @@ status_t KeyLayoutMap::Parser::parseAxis() { ALOGD_IF(DEBUG_PARSER, "Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, " "splitValue=%d, flatOverride=%d.", - scanCode, axisInfo.mode, axisInfo.axis, axisInfo.highAxis, axisInfo.splitValue, + *scanCode, axisInfo.mode, axisInfo.axis, axisInfo.highAxis, axisInfo.splitValue, axisInfo.flatOverride); - mMap->mAxes.insert({scanCode, axisInfo}); + mMap->mAxes.insert({*scanCode, axisInfo}); return NO_ERROR; } @@ -497,9 +517,8 @@ status_t KeyLayoutMap::Parser::parseLed() { mTokenizer->skipDelimiters(WHITESPACE); codeToken = mTokenizer->nextToken(WHITESPACE); } - char* end; - int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); - if (*end) { + std::optional code = parseInt(codeToken.string()); + if (!code) { ALOGE("%s: Expected led %s number, got '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; @@ -507,7 +526,7 @@ status_t KeyLayoutMap::Parser::parseLed() { std::unordered_map& map = mapUsage ? mMap->mLedsByUsageCode : mMap->mLedsByScanCode; - if (map.find(code) != map.end()) { + if (map.find(*code) != map.end()) { ALOGE("%s: Duplicate entry for led %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; @@ -515,19 +534,19 @@ status_t KeyLayoutMap::Parser::parseLed() { mTokenizer->skipDelimiters(WHITESPACE); String8 ledCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t ledCode = InputEventLookup::getLedByLabel(ledCodeToken.string()); - if (ledCode < 0) { + std::optional ledCode = InputEventLookup::getLedByLabel(ledCodeToken.string()); + if (!ledCode) { ALOGE("%s: Expected LED code label, got '%s'.", mTokenizer->getLocation().string(), ledCodeToken.string()); return BAD_VALUE; } ALOGD_IF(DEBUG_PARSER, "Parsed led %s: code=%d, ledCode=%d.", mapUsage ? "usage" : "scan code", - code, ledCode); + *code, *ledCode); Led led; - led.ledCode = ledCode; - map.insert({code, led}); + led.ledCode = *ledCode; + map.insert({*code, led}); return NO_ERROR; } @@ -565,16 +584,15 @@ static std::optional getSensorDataIndex(String8 token) { // sensor 0x05 GYROSCOPE Z status_t KeyLayoutMap::Parser::parseSensor() { String8 codeToken = mTokenizer->nextToken(WHITESPACE); - char* end; - int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); - if (*end) { + std::optional code = parseInt(codeToken.string()); + if (!code) { ALOGE("%s: Expected sensor %s number, got '%s'.", mTokenizer->getLocation().string(), "abs code", codeToken.string()); return BAD_VALUE; } std::unordered_map& map = mMap->mSensorsByAbsCode; - if (map.find(code) != map.end()) { + if (map.find(*code) != map.end()) { ALOGE("%s: Duplicate entry for sensor %s '%s'.", mTokenizer->getLocation().string(), "abs code", codeToken.string()); return BAD_VALUE; @@ -599,13 +617,13 @@ status_t KeyLayoutMap::Parser::parseSensor() { } int32_t sensorDataIndex = indexOpt.value(); - ALOGD_IF(DEBUG_PARSER, "Parsed sensor: abs code=%d, sensorType=%s, sensorDataIndex=%d.", code, + ALOGD_IF(DEBUG_PARSER, "Parsed sensor: abs code=%d, sensorType=%s, sensorDataIndex=%d.", *code, ftl::enum_string(sensorType).c_str(), sensorDataIndex); Sensor sensor; sensor.sensorType = sensorType; sensor.sensorDataIndex = sensorDataIndex; - map.emplace(code, sensor); + map.emplace(*code, sensor); return NO_ERROR; } diff --git a/libs/input/tests/InputDevice_test.cpp b/libs/input/tests/InputDevice_test.cpp index 2344463241..ee961f0ffc 100644 --- a/libs/input/tests/InputDevice_test.cpp +++ b/libs/input/tests/InputDevice_test.cpp @@ -133,6 +133,20 @@ TEST_F(InputDeviceKeyMapTest, keyCharacteMapApplyMultipleOverlaysTest) { ASSERT_EQ(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap); } +TEST_F(InputDeviceKeyMapTest, keyCharacteMapBadAxisLabel) { + std::string klPath = base::GetExecutableDirectory() + "/data/bad_axis_label.kl"; + + base::Result> ret = KeyLayoutMap::load(klPath); + ASSERT_FALSE(ret.ok()) << "Should not be able to load KeyLayout at " << klPath; +} + +TEST_F(InputDeviceKeyMapTest, keyCharacteMapBadLedLabel) { + std::string klPath = base::GetExecutableDirectory() + "/data/bad_led_label.kl"; + + base::Result> ret = KeyLayoutMap::load(klPath); + ASSERT_FALSE(ret.ok()) << "Should not be able to load KeyLayout at " << klPath; +} + TEST(InputDeviceKeyLayoutTest, DoesNotLoadWhenRequiredKernelConfigIsMissing) { #if !defined(__ANDROID__) GTEST_SKIP() << "Can't check kernel configs on host"; diff --git a/libs/input/tests/data/bad_axis_label.kl b/libs/input/tests/data/bad_axis_label.kl new file mode 100644 index 0000000000..689738077c --- /dev/null +++ b/libs/input/tests/data/bad_axis_label.kl @@ -0,0 +1,17 @@ +# Copyright (C) 2023 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This KL should not be loaded because the axis label is not valid + +axis 0 DEFINITELY_NOT_AXIS_LABEL diff --git a/libs/input/tests/data/bad_led_label.kl b/libs/input/tests/data/bad_led_label.kl new file mode 100644 index 0000000000..293c0d2af4 --- /dev/null +++ b/libs/input/tests/data/bad_led_label.kl @@ -0,0 +1,17 @@ +# Copyright (C) 2023 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This KL should not be loaded because the led label is invalid + +led 0 ABSOLUTELY_NOT_LED_LABEL -- cgit v1.2.3-59-g8ed1b From 5af2834b5ec418e7d1c8b5925b488df12c18aab4 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 17 Apr 2023 08:45:31 -0700 Subject: Pass reference to finishKey Since the parameter is assumed to be non-null, pass it by reference. Bug: 274058082 Test: m libinput_tests && $ANDROID_HOST_OUT/nativetest64/libinput_tests/libinput_tests Change-Id: Iedf8970a57e4463e6addc8ee1013feb3ee60c009 --- include/input/KeyCharacterMap.h | 2 +- libs/input/KeyCharacterMap.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index c67310eaec..9f1c0e28c6 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -227,7 +227,7 @@ private: status_t parseMapKey(); status_t parseKey(); status_t parseKeyProperty(); - status_t finishKey(Key* key); + status_t finishKey(Key& key); status_t parseModifier(const std::string& token, int32_t* outMetaState); status_t parseCharacterLiteral(char16_t* outCharacter); }; diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 737bd15901..65398d717d 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -1048,7 +1048,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER); if (token == "}") { mState = STATE_TOP; - return finishKey(key); + return finishKey(*key); } Vector properties; @@ -1230,12 +1230,12 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { return NO_ERROR; } -status_t KeyCharacterMap::Parser::finishKey(Key* key) { +status_t KeyCharacterMap::Parser::finishKey(Key& key) { // Fill in default number property. - if (!key->number) { + if (!key.number) { char16_t digit = 0; char16_t symbol = 0; - for (const Behavior& b : key->behaviors) { + for (const Behavior& b : key.behaviors) { char16_t ch = b.character; if (ch) { if (ch >= '0' && ch <= '9') { @@ -1247,7 +1247,7 @@ status_t KeyCharacterMap::Parser::finishKey(Key* key) { } } } - key->number = digit ? digit : symbol; + key.number = digit ? digit : symbol; } return NO_ERROR; } -- cgit v1.2.3-59-g8ed1b From 0bae1a0fbde55fc78ecfb203bc555009a86c4233 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 17 Apr 2023 09:00:59 -0700 Subject: Return Key* from getKey The call getKey can fail. Rather than returning a separate bool that the caller might ignore, return a pointer to simplify the code. Bug: 278299254 Test: m libinput_tests && $ANDROID_HOST_OUT/nativetest64/libinput_tests/libinput_tests Change-Id: I28c25bee8890bdc90ca7e069c803423a7420e6b4 --- include/input/KeyCharacterMap.h | 2 +- libs/input/KeyCharacterMap.cpp | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index 9f1c0e28c6..9423041b68 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -243,7 +243,7 @@ private: KeyCharacterMap(const std::string& filename); - bool getKey(int32_t keyCode, const Key** outKey) const; + const Key* getKey(int32_t keyCode) const; const Behavior* getKeyBehavior(int32_t keyCode, int32_t metaState) const; static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState); diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 65398d717d..136a560aea 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -272,8 +272,8 @@ const std::string KeyCharacterMap::getLoadFileName() const { char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const { char16_t result = 0; - const Key* key; - if (getKey(keyCode, &key)) { + const Key* key = getKey(keyCode); + if (key != nullptr) { result = key->label; } #if DEBUG_MAPPING @@ -284,8 +284,8 @@ char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const { char16_t KeyCharacterMap::getNumber(int32_t keyCode) const { char16_t result = 0; - const Key* key; - if (getKey(keyCode, &key)) { + const Key* key = getKey(keyCode); + if (key != nullptr) { result = key->number; } #if DEBUG_MAPPING @@ -332,8 +332,8 @@ bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState, char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars, int32_t metaState) const { char16_t result = 0; - const Key* key; - if (getKey(keyCode, &key)) { + const Key* key = getKey(keyCode); + if (key != nullptr) { // Try to find the most general behavior that maps to this character. // For example, the base key behavior will usually be last in the list. // However, if we find a perfect meta state match for one behavior then use that one. @@ -493,19 +493,18 @@ std::pair KeyCharacterMap::applyKeyBehavior(int32_t fromKeyCod return std::make_pair(toKeyCode, toMetaState); } -bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { +const KeyCharacterMap::Key* KeyCharacterMap::getKey(int32_t keyCode) const { ssize_t index = mKeys.indexOfKey(keyCode); if (index >= 0) { - *outKey = mKeys.valueAt(index); - return true; + return mKeys.valueAt(index); } - return false; + return nullptr; } const KeyCharacterMap::Behavior* KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState) const { - const Key* key; - if (getKey(keyCode, &key)) { + const Key* key = getKey(keyCode); + if (key != nullptr) { for (const Behavior& behavior : key->behaviors) { if (matchesMetaState(metaState, behavior.metaState)) { return &behavior; -- cgit v1.2.3-59-g8ed1b From edcd042535eb2f56100f69593b502770b9bee92d Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 17 Apr 2023 16:11:22 -0700 Subject: Convert Vector usage to std::vector Prefer std::vector implementation over the custom Vector data type. Bug: 278299254 Test: atest android.view.cts.KeyCharacterMapTest Change-Id: If5b4e270a5c89c56619ae0c576495024438bd651 --- libs/input/KeyCharacterMap.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 136a560aea..f703901ed9 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -1050,14 +1050,14 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { return finishKey(*key); } - Vector properties; + std::vector properties; // Parse all comma-delimited property names up to the first colon. for (;;) { if (token == "label") { - properties.add(Property(PROPERTY_LABEL)); + properties.emplace_back(PROPERTY_LABEL); } else if (token == "number") { - properties.add(Property(PROPERTY_NUMBER)); + properties.emplace_back(PROPERTY_NUMBER); } else { int32_t metaState; status_t status = parseModifier(token.string(), &metaState); @@ -1066,7 +1066,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { mTokenizer->getLocation().string(), token.string()); return status; } - properties.add(Property(PROPERTY_META, metaState)); + properties.emplace_back(PROPERTY_META, metaState); } mTokenizer->skipDelimiters(WHITESPACE); @@ -1181,8 +1181,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#'); // Add the behavior. - for (size_t i = 0; i < properties.size(); i++) { - const Property& property = properties.itemAt(i); + for (const Property& property : properties) { switch (property.property) { case PROPERTY_LABEL: if (key->label) { -- cgit v1.2.3-59-g8ed1b From 2a916c4622b762c1f39d69a2991f459a8fe7ec81 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 17 Apr 2023 10:37:05 -0700 Subject: Use std::unordered_map in KeyCharacterMap Previously, KeyedVector was used in KeyCharacterMap. Convert this to the std::unordered_map. Bug: 278299254 Test: m checkinput Test: m libinput_tests && $ANDROID_HOST_OUT/nativetest64/libinput_tests/libinput_tests Change-Id: I643aa8cc8ae0c68ade4d11d02e34be64faf7f157 --- include/input/KeyCharacterMap.h | 24 ++--- libs/input/KeyCharacterMap.cpp | 179 +++++++++------------------------- services/inputflinger/Android.bp | 3 + services/inputflinger/host/Android.bp | 9 +- 4 files changed, 63 insertions(+), 152 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index 9423041b68..b2e8baade3 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -26,9 +26,9 @@ #include #include #include -#include #include #include +#include // Maximum number of keys supported by KeyCharacterMaps #define MAX_KEYS 8192 @@ -152,13 +152,9 @@ public: void writeToParcel(Parcel* parcel) const; #endif - bool operator==(const KeyCharacterMap& other) const; + bool operator==(const KeyCharacterMap& other) const = default; - bool operator!=(const KeyCharacterMap& other) const; - - KeyCharacterMap(const KeyCharacterMap& other); - - virtual ~KeyCharacterMap(); + KeyCharacterMap(const KeyCharacterMap& other) = default; private: struct Behavior { @@ -173,17 +169,18 @@ private: /* The replacement keycode if the key has to be replaced outright. */ int32_t replacementKeyCode = 0; + + bool operator==(const Behavior&) const = default; }; struct Key { - Key(); - Key(const Key& other); + bool operator==(const Key&) const = default; /* The single character label printed on the key, or 0 if none. */ - char16_t label; + char16_t label = 0; /* The number or symbol character generated by the key, or 0 if none. */ - char16_t number; + char16_t number = 0; /* The list of key behaviors sorted from most specific to least specific * meta key binding. */ @@ -218,7 +215,6 @@ private: public: Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format); - ~Parser(); status_t parse(); private: @@ -232,8 +228,8 @@ private: status_t parseCharacterLiteral(char16_t* outCharacter); }; - KeyedVector mKeys; - KeyboardType mType; + std::map mKeys; + KeyboardType mType = KeyboardType::UNKNOWN; std::string mLoadFileName; bool mLayoutOverlayApplied = false; diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index f703901ed9..12c9e533c3 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -85,63 +85,7 @@ static String8 toString(const char16_t* chars, size_t numChars) { // --- KeyCharacterMap --- -KeyCharacterMap::KeyCharacterMap(const std::string& filename) - : mType(KeyboardType::UNKNOWN), mLoadFileName(filename) {} - -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++) { - mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i))); - } -} - -KeyCharacterMap::~KeyCharacterMap() { - clear(); -} - -bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const { - if (mType != other.mType) { - return false; - } - if (mLoadFileName != other.mLoadFileName) { - return false; - } - if (mLayoutOverlayApplied != other.mLayoutOverlayApplied) { - return false; - } - if (mKeys.size() != other.mKeys.size() || mKeyRemapping.size() != other.mKeyRemapping.size() || - mKeysByScanCode.size() != other.mKeysByScanCode.size() || - mKeysByUsageCode.size() != other.mKeysByUsageCode.size()) { - return false; - } - - for (size_t i = 0; i < mKeys.size(); i++) { - if (mKeys.keyAt(i) != other.mKeys.keyAt(i)) { - return false; - } - const Key* key = mKeys.valueAt(i); - const Key* otherKey = other.mKeys.valueAt(i); - if (key->label != otherKey->label || key->number != otherKey->number) { - return false; - } - } - - if (mKeyRemapping != other.mKeyRemapping || mKeysByScanCode != other.mKeysByScanCode || - mKeysByUsageCode != other.mKeysByUsageCode) { - return false; - } - - return true; -} - -bool KeyCharacterMap::operator!=(const KeyCharacterMap& other) const { - return !(*this == other); -} +KeyCharacterMap::KeyCharacterMap(const std::string& filename) : mLoadFileName(filename) {} base::Result> KeyCharacterMap::load(const std::string& filename, Format format) { @@ -207,10 +151,6 @@ status_t KeyCharacterMap::load(Tokenizer* tokenizer, Format format) { void KeyCharacterMap::clear() { mKeysByScanCode.clear(); mKeysByUsageCode.clear(); - for (size_t i = 0; i < mKeys.size(); i++) { - Key* key = mKeys.editValueAt(i); - delete key; - } mKeys.clear(); mLayoutOverlayApplied = false; mType = KeyboardType::UNKNOWN; @@ -233,24 +173,16 @@ void KeyCharacterMap::combine(const KeyCharacterMap& overlay) { if (mLayoutOverlayApplied) { reloadBaseFromFile(); } - for (size_t i = 0; i < overlay.mKeys.size(); i++) { - int32_t keyCode = overlay.mKeys.keyAt(i); - Key* key = overlay.mKeys.valueAt(i); - ssize_t oldIndex = mKeys.indexOfKey(keyCode); - if (oldIndex >= 0) { - delete mKeys.valueAt(oldIndex); - mKeys.editValueAt(oldIndex) = new Key(*key); - } else { - mKeys.add(keyCode, new Key(*key)); - } + for (const auto& [keyCode, key] : overlay.mKeys) { + mKeys.insert_or_assign(keyCode, key); } - for (auto const& it : overlay.mKeysByScanCode) { - mKeysByScanCode.insert_or_assign(it.first, it.second); + for (const auto& [fromScanCode, toAndroidKeyCode] : overlay.mKeysByScanCode) { + mKeysByScanCode.insert_or_assign(fromScanCode, toAndroidKeyCode); } - for (auto const& it : overlay.mKeysByUsageCode) { - mKeysByUsageCode.insert_or_assign(it.first, it.second); + for (const auto& [fromHidUsageCode, toAndroidKeyCode] : overlay.mKeysByUsageCode) { + mKeysByUsageCode.insert_or_assign(fromHidUsageCode, toAndroidKeyCode); } mLayoutOverlayApplied = true; } @@ -343,19 +275,15 @@ char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_ if (behavior.character == chars[i]) { result = behavior.character; if ((behavior.metaState & metaState) == behavior.metaState) { - goto ExactMatch; + // Found exact match! + return result; } break; } } } } - ExactMatch: ; } -#if DEBUG_MAPPING - ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.", - keyCode, toString(chars, numChars).string(), metaState, result); -#endif return result; } @@ -494,9 +422,9 @@ std::pair KeyCharacterMap::applyKeyBehavior(int32_t fromKeyCod } const KeyCharacterMap::Key* KeyCharacterMap::getKey(int32_t keyCode) const { - ssize_t index = mKeys.indexOfKey(keyCode); - if (index >= 0) { - return mKeys.valueAt(index); + auto it = mKeys.find(keyCode); + if (it != mKeys.end()) { + return &it->second; } return nullptr; } @@ -550,19 +478,17 @@ bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMeta return false; } - for (size_t i = 0; i < mKeys.size(); i++) { - const Key* key = mKeys.valueAt(i); - + for (const auto& [keyCode, key] : mKeys) { // Try to find the most general behavior that maps to this character. // For example, the base key behavior will usually be last in the list. const Behavior* found = nullptr; - for (const Behavior& behavior : key->behaviors) { + for (const Behavior& behavior : key.behaviors) { if (behavior.character == ch) { found = &behavior; } } if (found != nullptr) { - *outKeyCode = mKeys.keyAt(i); + *outKeyCode = keyCode; *outMetaState = found->metaState; return true; } @@ -714,11 +640,7 @@ std::shared_ptr KeyCharacterMap::readFromParcel(Parcel* parcel) return nullptr; } - Key* key = new Key(); - key->label = label; - key->number = number; - map->mKeys.add(keyCode, key); - + Key key{.label = label, .number = number}; while (parcel->readInt32()) { int32_t metaState = parcel->readInt32(); char16_t character = parcel->readInt32(); @@ -728,13 +650,14 @@ std::shared_ptr KeyCharacterMap::readFromParcel(Parcel* parcel) return nullptr; } - key->behaviors.push_back({ + key.behaviors.push_back({ .metaState = metaState, .character = character, .fallbackKeyCode = fallbackKeyCode, .replacementKeyCode = replacementKeyCode, }); } + map->mKeys.emplace(keyCode, std::move(key)); if (parcel->errorCheck()) { return nullptr; @@ -790,13 +713,11 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { size_t numKeys = mKeys.size(); parcel->writeInt32(numKeys); - for (size_t i = 0; i < numKeys; i++) { - int32_t keyCode = mKeys.keyAt(i); - const Key* key = mKeys.valueAt(i); + for (const auto& [keyCode, key] : mKeys) { parcel->writeInt32(keyCode); - parcel->writeInt32(key->label); - parcel->writeInt32(key->number); - for (const Behavior& behavior : key->behaviors) { + parcel->writeInt32(key.label); + parcel->writeInt32(key.number); + for (const Behavior& behavior : key.behaviors) { parcel->writeInt32(1); parcel->writeInt32(behavior.metaState); parcel->writeInt32(behavior.character); @@ -826,22 +747,12 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { } #endif // __linux__ -// --- KeyCharacterMap::Key --- - -KeyCharacterMap::Key::Key() : label(0), number(0) {} - -KeyCharacterMap::Key::Key(const Key& other) - : label(other.label), number(other.number), behaviors(other.behaviors) {} - // --- KeyCharacterMap::Parser --- KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) : mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) { } -KeyCharacterMap::Parser::~Parser() { -} - status_t KeyCharacterMap::Parser::parse() { while (!mTokenizer->isEof()) { #if DEBUG_PARSER @@ -1021,7 +932,7 @@ status_t KeyCharacterMap::Parser::parseKey() { keyCodeToken.string()); return BAD_VALUE; } - if (mMap->mKeys.indexOfKey(*keyCode) >= 0) { + if (mMap->mKeys.find(*keyCode) != mMap->mKeys.end()) { ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); return BAD_VALUE; @@ -1037,17 +948,17 @@ status_t KeyCharacterMap::Parser::parseKey() { ALOGD_IF(DEBUG_PARSER, "Parsed beginning of key: keyCode=%d.", *keyCode); mKeyCode = *keyCode; - mMap->mKeys.add(*keyCode, new Key()); + mMap->mKeys.emplace(*keyCode, Key{}); mState = STATE_KEY; return NO_ERROR; } status_t KeyCharacterMap::Parser::parseKeyProperty() { - Key* key = mMap->mKeys.valueFor(mKeyCode); + Key& key = mMap->mKeys[mKeyCode]; String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER); if (token == "}") { mState = STATE_TOP; - return finishKey(*key); + return finishKey(key); } std::vector properties; @@ -1184,43 +1095,41 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { for (const Property& property : properties) { switch (property.property) { case PROPERTY_LABEL: - if (key->label) { - ALOGE("%s: Duplicate label for key.", - mTokenizer->getLocation().string()); - return BAD_VALUE; - } - key->label = behavior.character; + if (key.label) { + ALOGE("%s: Duplicate label for key.", mTokenizer->getLocation().string()); + return BAD_VALUE; + } + key.label = behavior.character; #if DEBUG_PARSER - ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label); + ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key.label); #endif break; case PROPERTY_NUMBER: - if (key->number) { - ALOGE("%s: Duplicate number for key.", - mTokenizer->getLocation().string()); - return BAD_VALUE; + if (key.number) { + ALOGE("%s: Duplicate number for key.", mTokenizer->getLocation().string()); + return BAD_VALUE; } - key->number = behavior.character; + key.number = behavior.character; #if DEBUG_PARSER - ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number); + ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key.number); #endif break; case PROPERTY_META: { - for (const Behavior& b : key->behaviors) { - if (b.metaState == property.metaState) { + for (const Behavior& b : key.behaviors) { + if (b.metaState == property.metaState) { ALOGE("%s: Duplicate key behavior for modifier.", mTokenizer->getLocation().string()); return BAD_VALUE; - } + } } Behavior newBehavior = behavior; newBehavior.metaState = property.metaState; - key->behaviors.push_front(newBehavior); + key.behaviors.push_front(newBehavior); ALOGD_IF(DEBUG_PARSER, "Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.", - mKeyCode, key->behaviors.front().metaState, key->behaviors.front().character, - key->behaviors.front().fallbackKeyCode, - key->behaviors.front().replacementKeyCode); + mKeyCode, key.behaviors.front().metaState, key.behaviors.front().character, + key.behaviors.front().fallbackKeyCode, + key.behaviors.front().replacementKeyCode); break; } } diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp index e04481ca50..69df45bc3e 100644 --- a/services/inputflinger/Android.bp +++ b/services/inputflinger/Android.bp @@ -224,6 +224,9 @@ phony { "libinputservice_test", "Bug-115739809", "StructLayout_test", + // currently unused, but still must build correctly + "inputflinger", + "libinputflingerhost", // native fuzzers "inputflinger_latencytracker_fuzzer", diff --git a/services/inputflinger/host/Android.bp b/services/inputflinger/host/Android.bp index 743587c6f8..4d2839f038 100644 --- a/services/inputflinger/host/Android.bp +++ b/services/inputflinger/host/Android.bp @@ -23,7 +23,7 @@ package { cc_library_shared { name: "libinputflingerhost", - + cpp_std: "c++20", srcs: [ "InputFlinger.cpp", "InputDriver.cpp", @@ -64,14 +64,17 @@ cc_binary { srcs: ["main.cpp"], - cflags: ["-Wall", "-Werror"], + cflags: [ + "-Wall", + "-Werror", + ], shared_libs: [ "libbase", "libbinder", "libinputflingerhost", "libutils", - "libinput" + "libinput", ], static_libs: [ "libarect", -- cgit v1.2.3-59-g8ed1b From a7a99887349032123eafadb99155e5a486e13efc Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Mon, 14 Aug 2023 18:03:09 +0000 Subject: Migrate from android::String isEmpty to empty This empty method is different from the old one - it aligns with std::string definition. Bug: 295394788 Test: make checkbuild Change-Id: Id74502de0e51182aa9629db8dc70739be4483d12 (cherry picked from commit e50b2dec7a98b7a96369558897354ff196c9af44) --- cmds/atrace/atrace.cpp | 2 +- libs/gui/tests/GLTest.cpp | 16 ++++++++-------- libs/input/KeyCharacterMap.cpp | 2 +- libs/input/PropertyMap.cpp | 2 +- libs/input/VirtualKeyMap.cpp | 2 +- services/sensorservice/SensorService.cpp | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) (limited to 'libs/input/KeyCharacterMap.cpp') diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index ea2dddad23..5719a09a16 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -796,7 +796,7 @@ static bool setCategoriesEnableFromFile(const char* categories_file) bool ok = true; while (!tokenizer->isEol()) { String8 token = tokenizer->nextToken(" "); - if (token.isEmpty()) { + if (token.empty()) { tokenizer->skipDelimiters(" "); continue; } diff --git a/libs/gui/tests/GLTest.cpp b/libs/gui/tests/GLTest.cpp index 9024b70cd6..e5f4aaa999 100644 --- a/libs/gui/tests/GLTest.cpp +++ b/libs/gui/tests/GLTest.cpp @@ -191,24 +191,24 @@ EGLSurface GLTest::createWindowSurface(EGLDisplay display, EGLConfig config, msg += String8::format("r(%d isn't %d)", pixel[0], r); } if (g >= 0 && abs(g - int(pixel[1])) > tolerance) { - if (!msg.isEmpty()) { + if (!msg.empty()) { msg += " "; } msg += String8::format("g(%d isn't %d)", pixel[1], g); } if (b >= 0 && abs(b - int(pixel[2])) > tolerance) { - if (!msg.isEmpty()) { + if (!msg.empty()) { msg += " "; } msg += String8::format("b(%d isn't %d)", pixel[2], b); } if (a >= 0 && abs(a - int(pixel[3])) > tolerance) { - if (!msg.isEmpty()) { + if (!msg.empty()) { msg += " "; } msg += String8::format("a(%d isn't %d)", pixel[3], a); } - if (!msg.isEmpty()) { + if (!msg.empty()) { return ::testing::AssertionFailure(::testing::Message(msg.c_str())); } else { return ::testing::AssertionSuccess(); @@ -223,24 +223,24 @@ EGLSurface GLTest::createWindowSurface(EGLDisplay display, EGLConfig config, msg += String8::format("left(%d isn't %d)", r1.left, r2.left); } if (abs(r1.top - r2.top) > tolerance) { - if (!msg.isEmpty()) { + if (!msg.empty()) { msg += " "; } msg += String8::format("top(%d isn't %d)", r1.top, r2.top); } if (abs(r1.right - r2.right) > tolerance) { - if (!msg.isEmpty()) { + if (!msg.empty()) { msg += " "; } msg += String8::format("right(%d isn't %d)", r1.right, r2.right); } if (abs(r1.bottom - r2.bottom) > tolerance) { - if (!msg.isEmpty()) { + if (!msg.empty()) { msg += " "; } msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom); } - if (!msg.isEmpty()) { + if (!msg.empty()) { msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]", r1.left, r1.top, r1.right, r1.bottom, r2.left, r2.top, r2.right, r2.bottom); diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index d571917ff9..a4cd239a92 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -1247,7 +1247,7 @@ status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) } // Ensure that we consumed the entire token. - if (mTokenizer->nextToken(WHITESPACE).isEmpty()) { + if (mTokenizer->nextToken(WHITESPACE).empty()) { return NO_ERROR; } diff --git a/libs/input/PropertyMap.cpp b/libs/input/PropertyMap.cpp index 315f5a6d4f..db0c98fc91 100644 --- a/libs/input/PropertyMap.cpp +++ b/libs/input/PropertyMap.cpp @@ -171,7 +171,7 @@ status_t PropertyMap::Parser::parse() { if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') { String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER); - if (keyToken.isEmpty()) { + if (keyToken.empty()) { ALOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().c_str()); return BAD_VALUE; } diff --git a/libs/input/VirtualKeyMap.cpp b/libs/input/VirtualKeyMap.cpp index de62c870ff..8b8af4290f 100644 --- a/libs/input/VirtualKeyMap.cpp +++ b/libs/input/VirtualKeyMap.cpp @@ -146,7 +146,7 @@ bool VirtualKeyMap::Parser::parseNextIntField(int32_t* outValue) { String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER); char* end; *outValue = strtol(token.c_str(), &end, 0); - if (token.isEmpty() || *end != '\0') { + if (token.empty() || *end != '\0') { ALOGE("Expected an integer, got '%s'.", token.c_str()); return false; } diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 1030cee588..c69b072525 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -609,7 +609,7 @@ status_t SensorService::dump(int fd, const Vector& args) { for (auto&& i : mRecentEvent) { std::shared_ptr s = getSensorInterfaceFromHandle(i.first); if (!i.second->isEmpty() && s != nullptr) { - if (privileged || s->getSensor().getRequiredPermission().isEmpty()) { + if (privileged || s->getSensor().getRequiredPermission().empty()) { i.second->setFormat("normal"); } else { i.second->setFormat("mask_data"); @@ -735,7 +735,7 @@ status_t SensorService::dumpProtoLocked(int fd, ConnectionSafeAutolock* connLock for (auto&& i : mRecentEvent) { std::shared_ptr s = getSensorInterfaceFromHandle(i.first); if (!i.second->isEmpty() && s != nullptr) { - i.second->setFormat(privileged || s->getSensor().getRequiredPermission().isEmpty() ? + i.second->setFormat(privileged || s->getSensor().getRequiredPermission().empty() ? "normal" : "mask_data"); const uint64_t mToken = proto.start(service::SensorEventsProto::RECENT_EVENTS_LOGS); proto.write(service::SensorEventsProto::RecentEventsLog::NAME, -- cgit v1.2.3-59-g8ed1b