diff options
Diffstat (limited to 'libs/input/KeyLayoutMap.cpp')
-rw-r--r-- | libs/input/KeyLayoutMap.cpp | 145 |
1 files changed, 82 insertions, 63 deletions
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp index 79b6cea292..ddc9ea457e 100644 --- a/libs/input/KeyLayoutMap.cpp +++ b/libs/input/KeyLayoutMap.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "KeyLayoutMap" +#include <android-base/logging.h> #include <android/keycodes.h> #include <ftl/enum.h> #include <input/InputEventLabels.h> @@ -54,6 +55,21 @@ const bool DEBUG_MAPPING = namespace android { namespace { +std::optional<int> 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 <InputDeviceSensorType S> @@ -192,7 +208,8 @@ status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t usageCode, } // Return pair of sensor type and sensor data index, for the input device abs code -base::Result<std::pair<InputDeviceSensorType, int32_t>> KeyLayoutMap::mapSensor(int32_t absCode) { +base::Result<std::pair<InputDeviceSensorType, int32_t>> KeyLayoutMap::mapSensor( + int32_t absCode) const { auto it = mSensorsByAbsCode.find(absCode); if (it == mSensorsByAbsCode.end()) { ALOGD_IF(DEBUG_MAPPING, "mapSensor: absCode=%d, ~ Failed.", absCode); @@ -344,24 +361,23 @@ status_t KeyLayoutMap::Parser::parseKey() { codeToken = mTokenizer->nextToken(WHITESPACE); } - char* end; - int32_t code = int32_t(strtol(codeToken.c_str(), &end, 0)); - if (*end) { + std::optional<int> code = parseInt(codeToken.c_str()); + if (!code) { ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().c_str(), - mapUsage ? "usage" : "scan code", codeToken.c_str()); + mapUsage ? "usage" : "scan code", codeToken.c_str()); return BAD_VALUE; } std::unordered_map<int32_t, Key>& 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().c_str(), - mapUsage ? "usage" : "scan code", codeToken.c_str()); + mapUsage ? "usage" : "scan code", codeToken.c_str()); return BAD_VALUE; } mTokenizer->skipDelimiters(WHITESPACE); String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.c_str()); + std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.c_str()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().c_str(), keyCodeToken.c_str()); @@ -374,42 +390,41 @@ status_t KeyLayoutMap::Parser::parseKey() { if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break; String8 flagToken = mTokenizer->nextToken(WHITESPACE); - uint32_t flag = InputEventLookup::getKeyFlagByLabel(flagToken.c_str()); + std::optional<int> flag = InputEventLookup::getKeyFlagByLabel(flagToken.c_str()); if (!flag) { ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().c_str(), flagToken.c_str()); return BAD_VALUE; } - if (flags & flag) { + if (flags & *flag) { ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().c_str(), - flagToken.c_str()); + flagToken.c_str()); 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.c_str(), &end, 0)); - if (*end) { + std::optional<int> scanCode = parseInt(scanCodeToken.c_str()); + if (!scanCode) { ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().c_str(), - scanCodeToken.c_str()); + scanCodeToken.c_str()); 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().c_str(), - scanCodeToken.c_str()); + scanCodeToken.c_str()); return BAD_VALUE; } @@ -422,48 +437,53 @@ status_t KeyLayoutMap::Parser::parseAxis() { mTokenizer->skipDelimiters(WHITESPACE); String8 axisToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.axis = InputEventLookup::getAxisByLabel(axisToken.c_str()); - if (axisInfo.axis < 0) { - ALOGE("%s: Expected inverted axis label, got '%s'.", mTokenizer->getLocation().c_str(), - axisToken.c_str()); + std::optional<int> axis = InputEventLookup::getAxisByLabel(axisToken.c_str()); + if (!axis) { + ALOGE("%s: Expected inverted axis label, got '%s'.", + mTokenizer->getLocation().c_str(), axisToken.c_str()); 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.c_str(), &end, 0)); - if (*end) { - ALOGE("%s: Expected split value, got '%s'.", mTokenizer->getLocation().c_str(), - splitToken.c_str()); + std::optional<int> splitValue = parseInt(splitToken.c_str()); + if (!splitValue) { + ALOGE("%s: Expected split value, got '%s'.", + mTokenizer->getLocation().c_str(), splitToken.c_str()); return BAD_VALUE; } + axisInfo.splitValue = *splitValue; mTokenizer->skipDelimiters(WHITESPACE); String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.axis = InputEventLookup::getAxisByLabel(lowAxisToken.c_str()); - if (axisInfo.axis < 0) { - ALOGE("%s: Expected low axis label, got '%s'.", mTokenizer->getLocation().c_str(), - lowAxisToken.c_str()); + std::optional<int> axis = InputEventLookup::getAxisByLabel(lowAxisToken.c_str()); + if (!axis) { + ALOGE("%s: Expected low axis label, got '%s'.", + mTokenizer->getLocation().c_str(), lowAxisToken.c_str()); return BAD_VALUE; } + axisInfo.axis = *axis; mTokenizer->skipDelimiters(WHITESPACE); String8 highAxisToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.highAxis = InputEventLookup::getAxisByLabel(highAxisToken.c_str()); - if (axisInfo.highAxis < 0) { - ALOGE("%s: Expected high axis label, got '%s'.", mTokenizer->getLocation().c_str(), - highAxisToken.c_str()); + std::optional<int> highAxis = InputEventLookup::getAxisByLabel(highAxisToken.c_str()); + if (!highAxis) { + ALOGE("%s: Expected high axis label, got '%s'.", + mTokenizer->getLocation().c_str(), highAxisToken.c_str()); return BAD_VALUE; } + axisInfo.highAxis = *highAxis; } else { - axisInfo.axis = InputEventLookup::getAxisByLabel(token.c_str()); - if (axisInfo.axis < 0) { + std::optional<int> axis = InputEventLookup::getAxisByLabel(token.c_str()); + if (!axis) { ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.", mTokenizer->getLocation().c_str(), token.c_str()); return BAD_VALUE; } + axisInfo.axis = *axis; } for (;;) { @@ -475,12 +495,13 @@ status_t KeyLayoutMap::Parser::parseAxis() { if (keywordToken == "flat") { mTokenizer->skipDelimiters(WHITESPACE); String8 flatToken = mTokenizer->nextToken(WHITESPACE); - axisInfo.flatOverride = int32_t(strtol(flatToken.c_str(), &end, 0)); - if (*end) { - ALOGE("%s: Expected flat value, got '%s'.", mTokenizer->getLocation().c_str(), - flatToken.c_str()); + std::optional<int> flatOverride = parseInt(flatToken.c_str()); + if (!flatOverride) { + ALOGE("%s: Expected flat value, got '%s'.", + mTokenizer->getLocation().c_str(), flatToken.c_str()); return BAD_VALUE; } + axisInfo.flatOverride = *flatOverride; } else { ALOGE("%s: Expected keyword 'flat', got '%s'.", mTokenizer->getLocation().c_str(), keywordToken.c_str()); @@ -491,9 +512,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; } @@ -505,37 +526,36 @@ status_t KeyLayoutMap::Parser::parseLed() { mTokenizer->skipDelimiters(WHITESPACE); codeToken = mTokenizer->nextToken(WHITESPACE); } - char* end; - int32_t code = int32_t(strtol(codeToken.c_str(), &end, 0)); - if (*end) { + std::optional<int> code = parseInt(codeToken.c_str()); + if (!code) { ALOGE("%s: Expected led %s number, got '%s'.", mTokenizer->getLocation().c_str(), - mapUsage ? "usage" : "scan code", codeToken.c_str()); + mapUsage ? "usage" : "scan code", codeToken.c_str()); return BAD_VALUE; } std::unordered_map<int32_t, Led>& 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().c_str(), - mapUsage ? "usage" : "scan code", codeToken.c_str()); + mapUsage ? "usage" : "scan code", codeToken.c_str()); return BAD_VALUE; } mTokenizer->skipDelimiters(WHITESPACE); String8 ledCodeToken = mTokenizer->nextToken(WHITESPACE); - int32_t ledCode = InputEventLookup::getLedByLabel(ledCodeToken.c_str()); - if (ledCode < 0) { + std::optional<int> ledCode = InputEventLookup::getLedByLabel(ledCodeToken.c_str()); + if (!ledCode) { ALOGE("%s: Expected LED code label, got '%s'.", mTokenizer->getLocation().c_str(), - ledCodeToken.c_str()); + ledCodeToken.c_str()); 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; } @@ -573,16 +593,15 @@ static std::optional<int32_t> 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.c_str(), &end, 0)); - if (*end) { + std::optional<int> code = parseInt(codeToken.c_str()); + if (!code) { ALOGE("%s: Expected sensor %s number, got '%s'.", mTokenizer->getLocation().c_str(), "abs code", codeToken.c_str()); return BAD_VALUE; } std::unordered_map<int32_t, Sensor>& 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().c_str(), "abs code", codeToken.c_str()); return BAD_VALUE; @@ -607,13 +626,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; } |