/* * Copyright 2024 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. */ #include "SensorInputMapper.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "InputMapperTest.h" #include "TestEventMatchers.h" namespace android { using testing::AllOf; using testing::ElementsAre; using testing::Return; using testing::VariantWith; namespace { constexpr int32_t ACCEL_RAW_MIN = -32768; constexpr int32_t ACCEL_RAW_MAX = 32768; constexpr int32_t ACCEL_RAW_FUZZ = 16; constexpr int32_t ACCEL_RAW_FLAT = 0; constexpr int32_t ACCEL_RAW_RESOLUTION = 8192; constexpr int32_t GYRO_RAW_MIN = -2097152; constexpr int32_t GYRO_RAW_MAX = 2097152; constexpr int32_t GYRO_RAW_FUZZ = 16; constexpr int32_t GYRO_RAW_FLAT = 0; constexpr int32_t GYRO_RAW_RESOLUTION = 1024; constexpr float GRAVITY_MS2_UNIT = 9.80665f; constexpr float DEGREE_RADIAN_UNIT = 0.0174533f; } // namespace class SensorInputMapperTest : public InputMapperUnitTest { protected: void SetUp() override { InputMapperUnitTest::SetUp(); EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID)) .WillRepeatedly(Return(InputDeviceClass::SENSOR)); // The mapper requests info on all ABS axes, including ones which aren't actually used, so // just return nullopt for all axes we don't explicitly set up. EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, testing::_)) .WillRepeatedly(Return(std::nullopt)); } void setupSensor(int32_t absCode, InputDeviceSensorType type, int32_t sensorDataIndex) { EXPECT_CALL(mMockEventHub, mapSensor(EVENTHUB_ID, absCode)) .WillRepeatedly(Return(std::make_pair(type, sensorDataIndex))); } }; TEST_F(SensorInputMapperTest, GetSources) { mMapper = createInputMapper(*mDeviceContext, mFakePolicy->getReaderConfiguration()); ASSERT_EQ(static_cast(AINPUT_SOURCE_SENSOR), mMapper->getSources()); } TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) { EXPECT_CALL(mMockEventHub, hasMscEvent(EVENTHUB_ID, MSC_TIMESTAMP)) .WillRepeatedly(Return(true)); setupSensor(ABS_X, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/0); setupSensor(ABS_Y, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/1); setupSensor(ABS_Z, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/2); setupAxis(ABS_X, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION, ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ); setupAxis(ABS_Y, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION, ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ); setupAxis(ABS_Z, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION, ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ); mPropertyMap.addProperty("sensor.accelerometer.reportingMode", "0"); mPropertyMap.addProperty("sensor.accelerometer.maxDelay", "100000"); mPropertyMap.addProperty("sensor.accelerometer.minDelay", "5000"); mPropertyMap.addProperty("sensor.accelerometer.power", "1.5"); mMapper = createInputMapper(*mDeviceContext, mFakePolicy->getReaderConfiguration()); EXPECT_CALL(mMockEventHub, enableDevice(EVENTHUB_ID)); ASSERT_TRUE(mMapper->enableSensor(InputDeviceSensorType::ACCELEROMETER, std::chrono::microseconds(10000), std::chrono::microseconds(0))); std::list args; args += process(ARBITRARY_TIME, EV_ABS, ABS_X, 20000); args += process(ARBITRARY_TIME, EV_ABS, ABS_Y, -20000); args += process(ARBITRARY_TIME, EV_ABS, ABS_Z, 40000); args += process(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1000); args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); std::vector values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT, -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT, 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT}; ASSERT_EQ(args.size(), 1u); const NotifySensorArgs& arg = std::get(args.front()); ASSERT_EQ(arg.source, AINPUT_SOURCE_SENSOR); ASSERT_EQ(arg.deviceId, DEVICE_ID); ASSERT_EQ(arg.sensorType, InputDeviceSensorType::ACCELEROMETER); ASSERT_EQ(arg.accuracy, InputDeviceSensorAccuracy::HIGH); ASSERT_EQ(arg.hwTimestamp, ARBITRARY_TIME); ASSERT_EQ(arg.values, values); mMapper->flushSensor(InputDeviceSensorType::ACCELEROMETER); } TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) { EXPECT_CALL(mMockEventHub, hasMscEvent(EVENTHUB_ID, MSC_TIMESTAMP)) .WillRepeatedly(Return(true)); setupSensor(ABS_RX, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/0); setupSensor(ABS_RY, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/1); setupSensor(ABS_RZ, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/2); setupAxis(ABS_RX, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION, GYRO_RAW_FLAT, GYRO_RAW_FUZZ); setupAxis(ABS_RY, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION, GYRO_RAW_FLAT, GYRO_RAW_FUZZ); setupAxis(ABS_RZ, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION, GYRO_RAW_FLAT, GYRO_RAW_FUZZ); mPropertyMap.addProperty("sensor.gyroscope.reportingMode", "0"); mPropertyMap.addProperty("sensor.gyroscope.maxDelay", "100000"); mPropertyMap.addProperty("sensor.gyroscope.minDelay", "5000"); mPropertyMap.addProperty("sensor.gyroscope.power", "0.8"); mMapper = createInputMapper(*mDeviceContext, mFakePolicy->getReaderConfiguration()); EXPECT_CALL(mMockEventHub, enableDevice(EVENTHUB_ID)); ASSERT_TRUE(mMapper->enableSensor(InputDeviceSensorType::GYROSCOPE, std::chrono::microseconds(10000), std::chrono::microseconds(0))); std::list args; args += process(ARBITRARY_TIME, EV_ABS, ABS_RX, 20000); args += process(ARBITRARY_TIME, EV_ABS, ABS_RY, -20000); args += process(ARBITRARY_TIME, EV_ABS, ABS_RZ, 40000); args += process(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1000); args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); std::vector values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT, -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT, 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT}; ASSERT_EQ(args.size(), 1u); const NotifySensorArgs& arg = std::get(args.front()); ASSERT_EQ(arg.source, AINPUT_SOURCE_SENSOR); ASSERT_EQ(arg.deviceId, DEVICE_ID); ASSERT_EQ(arg.sensorType, InputDeviceSensorType::GYROSCOPE); ASSERT_EQ(arg.accuracy, InputDeviceSensorAccuracy::HIGH); ASSERT_EQ(arg.hwTimestamp, ARBITRARY_TIME); ASSERT_EQ(arg.values, values); mMapper->flushSensor(InputDeviceSensorType::GYROSCOPE); } } // namespace android