Add SensorManager support in inputflinger.
Add sensor device, sensor input mapper, sens event dispatcher support
into inputflinger.
Bug: 161634265
Test: atest inputflinger_tests
Change-Id: I2dcb2c35d9dccefc4cd8d939b79cf340931a9410
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 34eba5b..2ed441d 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -23,6 +23,7 @@
#include <android-base/stringprintf.h>
#include <input/InputDevice.h>
#include <input/InputEventLabels.h>
+#include <input/NamedEnum.h>
using android::base::StringPrintf;
@@ -166,7 +167,9 @@
mKeyCharacterMap(other.mKeyCharacterMap),
mHasVibrator(other.mHasVibrator),
mHasButtonUnderPad(other.mHasButtonUnderPad),
- mMotionRanges(other.mMotionRanges) {}
+ mHasSensor(other.mHasSensor),
+ mMotionRanges(other.mMotionRanges),
+ mSensors(other.mSensors) {}
InputDeviceInfo::~InputDeviceInfo() {
}
@@ -185,7 +188,9 @@
mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
mHasVibrator = false;
mHasButtonUnderPad = false;
+ mHasSensor = false;
mMotionRanges.clear();
+ mSensors.clear();
}
const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
@@ -214,4 +219,28 @@
mMotionRanges.push_back(range);
}
+void InputDeviceInfo::addSensorInfo(const InputDeviceSensorInfo& info) {
+ if (mSensors.find(info.type) != mSensors.end()) {
+ ALOGW("Sensor type %s already exists, will be replaced by new sensor added.",
+ NamedEnum::string(info.type).c_str());
+ }
+ mSensors.insert_or_assign(info.type, info);
+}
+
+const std::vector<InputDeviceSensorType> InputDeviceInfo::getSensorTypes() {
+ std::vector<InputDeviceSensorType> types;
+ for (const auto& [type, info] : mSensors) {
+ types.push_back(type);
+ }
+ return types;
+}
+
+const InputDeviceSensorInfo* InputDeviceInfo::getSensorInfo(InputDeviceSensorType type) {
+ auto it = mSensors.find(type);
+ if (it == mSensors.end()) {
+ return nullptr;
+ }
+ return &it->second;
+}
+
} // namespace android
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index f5432ad..5666de6 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -103,6 +103,48 @@
}
}
+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;
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index 16ce48a..d36e417 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -20,12 +20,13 @@
#include <android/keycodes.h>
#include <input/InputEventLabels.h>
-#include <input/Keyboard.h>
#include <input/KeyLayoutMap.h>
-#include <utils/Log.h>
+#include <input/Keyboard.h>
+#include <input/NamedEnum.h>
#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
+#include <utils/Log.h>
#include <utils/Timers.h>
+#include <utils/Tokenizer.h>
// Enables debug output for the parser.
#define DEBUG_PARSER 0
@@ -41,6 +42,26 @@
static const char* WHITESPACE = " \t\r";
+#define SENSOR_ENTRY(type) NamedEnum::string(type), type
+static const std::unordered_map<std::string, InputDeviceSensorType> SENSOR_LIST =
+ {{SENSOR_ENTRY(InputDeviceSensorType::ACCELEROMETER)},
+ {SENSOR_ENTRY(InputDeviceSensorType::MAGNETIC_FIELD)},
+ {SENSOR_ENTRY(InputDeviceSensorType::ORIENTATION)},
+ {SENSOR_ENTRY(InputDeviceSensorType::GYROSCOPE)},
+ {SENSOR_ENTRY(InputDeviceSensorType::LIGHT)},
+ {SENSOR_ENTRY(InputDeviceSensorType::PRESSURE)},
+ {SENSOR_ENTRY(InputDeviceSensorType::TEMPERATURE)},
+ {SENSOR_ENTRY(InputDeviceSensorType::PROXIMITY)},
+ {SENSOR_ENTRY(InputDeviceSensorType::GRAVITY)},
+ {SENSOR_ENTRY(InputDeviceSensorType::LINEAR_ACCELERATION)},
+ {SENSOR_ENTRY(InputDeviceSensorType::ROTATION_VECTOR)},
+ {SENSOR_ENTRY(InputDeviceSensorType::RELATIVE_HUMIDITY)},
+ {SENSOR_ENTRY(InputDeviceSensorType::AMBIENT_TEMPERATURE)},
+ {SENSOR_ENTRY(InputDeviceSensorType::MAGNETIC_FIELD_UNCALIBRATED)},
+ {SENSOR_ENTRY(InputDeviceSensorType::GAME_ROTATION_VECTOR)},
+ {SENSOR_ENTRY(InputDeviceSensorType::GYROSCOPE_UNCALIBRATED)},
+ {SENSOR_ENTRY(InputDeviceSensorType::SIGNIFICANT_MOTION)}};
+
// --- KeyLayoutMap ---
KeyLayoutMap::KeyLayoutMap() {
@@ -127,6 +148,24 @@
return NO_ERROR;
}
+// 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) {
+ auto it = mSensorsByAbsCode.find(absCode);
+ if (it == mSensorsByAbsCode.end()) {
+#if DEBUG_MAPPING
+ ALOGD("mapSensor: absCode=%d, ~ Failed.", absCode);
+#endif
+ return Errorf("Can't find abs code {}.", absCode);
+ }
+ const Sensor& sensor = it->second;
+
+#if DEBUG_MAPPING
+ ALOGD("mapSensor: absCode=%d, sensorType=0x%0x, sensorDataIndex=0x%x.", absCode,
+ NamedEnum::string(sensor.sensorType), sensor.sensorDataIndex);
+#endif
+ return std::make_pair(sensor.sensorType, sensor.sensorDataIndex);
+}
+
const KeyLayoutMap::Key* KeyLayoutMap::getKey(int32_t scanCode, int32_t usageCode) const {
if (usageCode) {
ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
@@ -242,6 +281,10 @@
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseLed();
if (status) return status;
+ } else if (keywordToken == "sensor") {
+ mTokenizer->skipDelimiters(WHITESPACE);
+ status_t status = parseSensor();
+ if (status) return status;
} else {
ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
keywordToken.string());
@@ -468,4 +511,84 @@
map.add(code, led);
return NO_ERROR;
}
+
+static std::optional<InputDeviceSensorType> getSensorType(const char* token) {
+ auto it = SENSOR_LIST.find(std::string(token));
+ if (it == SENSOR_LIST.end()) {
+ return std::nullopt;
+ }
+ return it->second;
+}
+
+static std::optional<int32_t> getSensorDataIndex(String8 token) {
+ std::string tokenStr(token.string());
+ if (tokenStr == "X") {
+ return 0;
+ } else if (tokenStr == "Y") {
+ return 1;
+ } else if (tokenStr == "Z") {
+ return 2;
+ }
+ return std::nullopt;
+}
+
+// Parse sensor type and data index mapping, as below format
+// sensor <raw abs> <sensor type> <sensor data index>
+// raw abs : the linux abs code of the axis
+// sensor type : string name of InputDeviceSensorType
+// sensor data index : the data index of sensor, out of [X, Y, Z]
+// Examples:
+// sensor 0x00 ACCELEROMETER X
+// sensor 0x01 ACCELEROMETER Y
+// sensor 0x02 ACCELEROMETER Z
+// sensor 0x03 GYROSCOPE X
+// sensor 0x04 GYROSCOPE Y
+// 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) {
+ ALOGE("%s: Expected sensor %s number, got '%s'.", mTokenizer->getLocation().string(),
+ "abs code", codeToken.string());
+ return BAD_VALUE;
+ }
+
+ std::unordered_map<int32_t, Sensor>& map = mMap->mSensorsByAbsCode;
+ if (map.find(code) != map.end()) {
+ ALOGE("%s: Duplicate entry for sensor %s '%s'.", mTokenizer->getLocation().string(),
+ "abs code", codeToken.string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 sensorTypeToken = mTokenizer->nextToken(WHITESPACE);
+ std::optional<InputDeviceSensorType> typeOpt = getSensorType(sensorTypeToken.string());
+ if (!typeOpt) {
+ ALOGE("%s: Expected sensor code label, got '%s'.", mTokenizer->getLocation().string(),
+ sensorTypeToken.string());
+ return BAD_VALUE;
+ }
+ InputDeviceSensorType sensorType = typeOpt.value();
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 sensorDataIndexToken = mTokenizer->nextToken(WHITESPACE);
+ std::optional<int32_t> indexOpt = getSensorDataIndex(sensorDataIndexToken);
+ if (!indexOpt) {
+ ALOGE("%s: Expected sensor data index label, got '%s'.", mTokenizer->getLocation().string(),
+ sensorDataIndexToken.string());
+ return BAD_VALUE;
+ }
+ int32_t sensorDataIndex = indexOpt.value();
+
+#if DEBUG_PARSER
+ ALOGD("Parsed sensor: abs code=%d, sensorType=%d, sensorDataIndex=%d.", code,
+ NamedEnum::string(sensorType).c_str(), sensorDataIndex);
+#endif
+
+ Sensor sensor;
+ sensor.sensorType = sensorType;
+ sensor.sensorDataIndex = sensorDataIndex;
+ map.emplace(code, sensor);
+ return NO_ERROR;
+}
};
diff --git a/libs/input/tests/InputDevice_test.cpp b/libs/input/tests/InputDevice_test.cpp
index c174ae9..e2cf245 100644
--- a/libs/input/tests/InputDevice_test.cpp
+++ b/libs/input/tests/InputDevice_test.cpp
@@ -14,9 +14,12 @@
* limitations under the License.
*/
-
+#include <binder/Binder.h>
+#include <binder/Parcel.h>
#include <gtest/gtest.h>
#include <input/InputDevice.h>
+#include <input/KeyLayoutMap.h>
+#include <input/Keyboard.h>
namespace android {
@@ -31,4 +34,52 @@
ASSERT_EQ(std::string("deviceName-123_version_C_"), identifier.getCanonicalName());
}
+class InputDeviceKeyMapTest : public testing::Test {
+protected:
+ void loadKeyLayout(const char* name) {
+ std::string path =
+ getInputDeviceConfigurationFilePathByName(name,
+ InputDeviceConfigurationFileType::
+ KEY_LAYOUT);
+ ASSERT_FALSE(path.empty());
+ base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(path);
+ ASSERT_TRUE(ret) << "Cannot load KeyLayout at " << path;
+ mKeyMap.keyLayoutMap = std::move(*ret);
+ mKeyMap.keyLayoutFile = path;
+ }
+
+ void loadKeyCharacterMap(const char* name) {
+ InputDeviceIdentifier identifier;
+ identifier.name = name;
+ std::string path =
+ getInputDeviceConfigurationFilePathByName(identifier.getCanonicalName(),
+ InputDeviceConfigurationFileType::
+ KEY_CHARACTER_MAP);
+ ASSERT_FALSE(path.empty()) << "KeyCharacterMap for " << name << " not found";
+ base::Result<std::shared_ptr<KeyCharacterMap>> ret =
+ KeyCharacterMap::load(path, KeyCharacterMap::Format::BASE);
+ ASSERT_TRUE(ret) << "Cannot load KeyCharacterMap at " << path;
+ mKeyMap.keyCharacterMap = *ret;
+ mKeyMap.keyCharacterMapFile = path;
+ }
+
+ virtual void SetUp() override {
+ loadKeyLayout("Generic");
+ loadKeyCharacterMap("Generic");
+ }
+
+ virtual void TearDown() override {}
+
+ KeyMap mKeyMap;
+};
+
+TEST_F(InputDeviceKeyMapTest, keyCharacterMapParcelingTest) {
+ Parcel parcel;
+ mKeyMap.keyCharacterMap->writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ std::shared_ptr<KeyCharacterMap> map = KeyCharacterMap::readFromParcel(&parcel);
+ // Verify the key character map is the same as original
+ ASSERT_EQ(*map, *mKeyMap.keyCharacterMap);
+}
+
} // namespace android
\ No newline at end of file