diff options
Diffstat (limited to 'libs/input/KeyCharacterMap.cpp')
-rw-r--r-- | libs/input/KeyCharacterMap.cpp | 225 |
1 files changed, 131 insertions, 94 deletions
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index cb68165433..44f3f34994 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -19,14 +19,14 @@ #include <stdlib.h> #include <string.h> -#ifdef __ANDROID__ +#ifdef __linux__ #include <binder/Parcel.h> #endif - #include <android/keycodes.h> +#include <attestation/HmacKeyManager.h> #include <input/InputEventLabels.h> -#include <input/Keyboard.h> #include <input/KeyCharacterMap.h> +#include <input/Keyboard.h> #include <utils/Log.h> #include <utils/Errors.h> @@ -85,15 +85,12 @@ static String8 toString(const char16_t* chars, size_t numChars) { // --- KeyCharacterMap --- -sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap(); +KeyCharacterMap::KeyCharacterMap() : mType(KeyboardType::UNKNOWN) {} -KeyCharacterMap::KeyCharacterMap() : - mType(KEYBOARD_TYPE_UNKNOWN) { -} - -KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) : - RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode), - mKeysByUsageCode(other.mKeysByUsageCode) { +KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) + : mType(other.mType), + 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))); } @@ -106,102 +103,135 @@ KeyCharacterMap::~KeyCharacterMap() { } } -status_t KeyCharacterMap::load(const std::string& filename, - Format format, sp<KeyCharacterMap>* outMap) { - outMap->clear(); +bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const { + if (mType != other.mType) { + return false; + } + if (mKeys.size() != other.mKeys.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; + } + } + + 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; + } + } + + return true; +} +base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::load(const std::string& filename, + Format format) { Tokenizer* tokenizer; status_t status = Tokenizer::open(String8(filename.c_str()), &tokenizer); if (status) { - ALOGE("Error %d opening key character map file %s.", status, filename.c_str()); - } else { - status = load(tokenizer, format, outMap); - delete tokenizer; + return Errorf("Error {} opening key character map file {}.", status, filename.c_str()); } - return status; + std::unique_ptr<Tokenizer> t(tokenizer); + auto ret = load(t.get(), format); + if (ret.ok()) { + (*ret)->mLoadFileName = filename; + } + return ret; } -status_t KeyCharacterMap::loadContents(const std::string& filename, const char* contents, - Format format, sp<KeyCharacterMap>* outMap) { - outMap->clear(); - +base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::loadContents( + const std::string& filename, const char* contents, Format format) { Tokenizer* tokenizer; status_t status = Tokenizer::fromContents(String8(filename.c_str()), contents, &tokenizer); if (status) { ALOGE("Error %d opening key character map.", status); - } else { - status = load(tokenizer, format, outMap); - delete tokenizer; + return Errorf("Error {} opening key character map.", status); } - return status; + std::unique_ptr<Tokenizer> t(tokenizer); + auto ret = load(t.get(), format); + if (ret.ok()) { + (*ret)->mLoadFileName = filename; + } + return ret; } -status_t KeyCharacterMap::load(Tokenizer* tokenizer, - Format format, sp<KeyCharacterMap>* outMap) { +base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::load(Tokenizer* tokenizer, + Format format) { status_t status = OK; - sp<KeyCharacterMap> map = new KeyCharacterMap(); + std::shared_ptr<KeyCharacterMap> map = std::shared_ptr<KeyCharacterMap>(new KeyCharacterMap()); if (!map.get()) { ALOGE("Error allocating key character map."); - status = NO_MEMORY; - } else { + return Errorf("Error allocating key character map."); + } #if DEBUG_PARSER_PERFORMANCE - nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC); + nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC); #endif - Parser parser(map.get(), tokenizer, format); - status = parser.parse(); + Parser parser(map.get(), tokenizer, format); + status = parser.parse(); #if DEBUG_PARSER_PERFORMANCE - nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; - ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.", - tokenizer->getFilename().string(), tokenizer->getLineNumber(), - elapsedTime / 1000000.0); + nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; + ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.", + tokenizer->getFilename().string(), tokenizer->getLineNumber(), elapsedTime / 1000000.0); #endif - if (!status) { - *outMap = map; - } + if (status == OK) { + return map; } - return status; -} -sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base, - const sp<KeyCharacterMap>& overlay) { - if (overlay == nullptr) { - return base; - } - if (base == nullptr) { - return overlay; - } + return Errorf("Load KeyCharacterMap failed {}.", status); +} - sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get()); - 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 = map->mKeys.indexOfKey(keyCode); +void KeyCharacterMap::combine(const KeyCharacterMap& overlay) { + 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 map->mKeys.valueAt(oldIndex); - map->mKeys.editValueAt(oldIndex) = new Key(*key); + delete mKeys.valueAt(oldIndex); + mKeys.editValueAt(oldIndex) = new Key(*key); } else { - map->mKeys.add(keyCode, new Key(*key)); + mKeys.add(keyCode, new Key(*key)); } } - for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) { - map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i), - overlay->mKeysByScanCode.valueAt(i)); + for (size_t i = 0; i < overlay.mKeysByScanCode.size(); i++) { + mKeysByScanCode.replaceValueFor(overlay.mKeysByScanCode.keyAt(i), + overlay.mKeysByScanCode.valueAt(i)); } - for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) { - map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i), - overlay->mKeysByUsageCode.valueAt(i)); + for (size_t i = 0; i < overlay.mKeysByUsageCode.size(); i++) { + mKeysByUsageCode.replaceValueFor(overlay.mKeysByUsageCode.keyAt(i), + overlay.mKeysByUsageCode.valueAt(i)); } - return map; + mLoadFileName = overlay.mLoadFileName; } -sp<KeyCharacterMap> KeyCharacterMap::empty() { - return sEmpty; +KeyCharacterMap::KeyboardType KeyCharacterMap::getKeyboardType() const { + return mType; } -int32_t KeyCharacterMap::getKeyboardType() const { - return mType; +const std::string KeyCharacterMap::getLoadFileName() const { + return mLoadFileName; } char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const { @@ -599,10 +629,14 @@ void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents, } } -#ifdef __ANDROID__ -sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { - sp<KeyCharacterMap> map = new KeyCharacterMap(); - map->mType = parcel->readInt32(); +#ifdef __linux__ +std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return nullptr; + } + std::shared_ptr<KeyCharacterMap> map = std::shared_ptr<KeyCharacterMap>(new KeyCharacterMap()); + map->mType = static_cast<KeyCharacterMap::KeyboardType>(parcel->readInt32()); size_t numKeys = parcel->readInt32(); if (parcel->errorCheck()) { return nullptr; @@ -656,7 +690,11 @@ sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { } void KeyCharacterMap::writeToParcel(Parcel* parcel) const { - parcel->writeInt32(mType); + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return; + } + parcel->writeInt32(static_cast<int32_t>(mType)); size_t numKeys = mKeys.size(); parcel->writeInt32(numKeys); @@ -677,8 +715,7 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { parcel->writeInt32(0); } } -#endif - +#endif // __linux__ // --- KeyCharacterMap::Key --- @@ -782,20 +819,20 @@ status_t KeyCharacterMap::Parser::parse() { return BAD_VALUE; } - if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) { + if (mMap->mType == KeyboardType::UNKNOWN) { ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.", mTokenizer->getLocation().string()); return BAD_VALUE; } - if (mFormat == FORMAT_BASE) { - if (mMap->mType == KEYBOARD_TYPE_OVERLAY) { + if (mFormat == Format::BASE) { + if (mMap->mType == KeyboardType::OVERLAY) { ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.", mTokenizer->getLocation().string()); return BAD_VALUE; } - } else if (mFormat == FORMAT_OVERLAY) { - if (mMap->mType != KEYBOARD_TYPE_OVERLAY) { + } else if (mFormat == Format::OVERLAY) { + if (mMap->mType != KeyboardType::OVERLAY) { ALOGE("%s: Overlay keyboard layout missing required keyboard " "'type OVERLAY' declaration.", mTokenizer->getLocation().string()); @@ -807,7 +844,7 @@ status_t KeyCharacterMap::Parser::parse() { } status_t KeyCharacterMap::Parser::parseType() { - if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) { + if (mMap->mType != KeyboardType::UNKNOWN) { ALOGE("%s: Duplicate keyboard 'type' declaration.", mTokenizer->getLocation().string()); return BAD_VALUE; @@ -816,20 +853,20 @@ status_t KeyCharacterMap::Parser::parseType() { KeyboardType type; String8 typeToken = mTokenizer->nextToken(WHITESPACE); if (typeToken == "NUMERIC") { - type = KEYBOARD_TYPE_NUMERIC; + type = KeyboardType::NUMERIC; } else if (typeToken == "PREDICTIVE") { - type = KEYBOARD_TYPE_PREDICTIVE; + type = KeyboardType::PREDICTIVE; } else if (typeToken == "ALPHA") { - type = KEYBOARD_TYPE_ALPHA; + type = KeyboardType::ALPHA; } else if (typeToken == "FULL") { - type = KEYBOARD_TYPE_FULL; + type = KeyboardType::FULL; } else if (typeToken == "SPECIAL_FUNCTION") { ALOGW("The SPECIAL_FUNCTION type is now declared in the device's IDC file, please set " "the property 'keyboard.specialFunction' to '1' there instead."); // TODO: return BAD_VALUE here in Q - type = KEYBOARD_TYPE_SPECIAL_FUNCTION; + type = KeyboardType::SPECIAL_FUNCTION; } else if (typeToken == "OVERLAY") { - type = KEYBOARD_TYPE_OVERLAY; + type = KeyboardType::OVERLAY; } else { ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(), typeToken.string()); @@ -880,7 +917,7 @@ status_t KeyCharacterMap::Parser::parseMapKey() { mTokenizer->skipDelimiters(WHITESPACE); String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); + int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); @@ -897,7 +934,7 @@ status_t KeyCharacterMap::Parser::parseMapKey() { status_t KeyCharacterMap::Parser::parseKey() { String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); + int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); @@ -1017,7 +1054,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { } else if (token == "fallback") { mTokenizer->skipDelimiters(WHITESPACE); token = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = getKeyCodeByLabel(token.string()); + int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string()); if (!keyCode) { ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.", mTokenizer->getLocation().string(), @@ -1034,7 +1071,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { } else if (token == "replace") { mTokenizer->skipDelimiters(WHITESPACE); token = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = getKeyCodeByLabel(token.string()); + int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string()); if (!keyCode) { ALOGE("%s: Invalid key code label for replace, got '%s'.", mTokenizer->getLocation().string(), |