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/services/inputflinger/reader/mapper/InputMapper.cpp b/services/inputflinger/reader/mapper/InputMapper.cpp
index 913cef7..1ce54ae 100644
--- a/services/inputflinger/reader/mapper/InputMapper.cpp
+++ b/services/inputflinger/reader/mapper/InputMapper.cpp
@@ -70,6 +70,16 @@
 
 void InputMapper::cancelTouch(nsecs_t when) {}
 
+bool InputMapper::enableSensor(InputDeviceSensorType sensorType,
+                               std::chrono::microseconds samplingPeriod,
+                               std::chrono::microseconds maxBatchReportLatency) {
+    return true;
+}
+
+void InputMapper::disableSensor(InputDeviceSensorType sensorType) {}
+
+void InputMapper::flushSensor(InputDeviceSensorType sensorType) {}
+
 int32_t InputMapper::getMetaState() {
     return 0;
 }
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index 088dbd8..bd64d8d 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -68,6 +68,11 @@
     virtual bool isVibrating();
     virtual std::vector<int32_t> getVibratorIds();
     virtual void cancelTouch(nsecs_t when);
+    virtual bool enableSensor(InputDeviceSensorType sensorType,
+                              std::chrono::microseconds samplingPeriod,
+                              std::chrono::microseconds maxBatchReportLatency);
+    virtual void disableSensor(InputDeviceSensorType sensorType);
+    virtual void flushSensor(InputDeviceSensorType sensorType);
 
     virtual int32_t getMetaState();
     virtual void updateMetaState(int32_t keyCode);
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
new file mode 100644
index 0000000..7d97014
--- /dev/null
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2020 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 <locale>
+
+#include "../Macros.h"
+
+#include "SensorInputMapper.h"
+
+// Log detailed debug messages about each sensor event notification to the dispatcher.
+constexpr bool DEBUG_SENSOR_EVENT_DETAILS = false;
+
+namespace android {
+
+// Mask for the LSB 2nd, 3rd and fourth bits.
+constexpr int REPORTING_MODE_MASK = 0xE;
+constexpr int REPORTING_MODE_SHIFT = 1;
+constexpr float GRAVITY_MS2_UNIT = 9.80665f;
+constexpr float DEGREE_RADIAN_UNIT = 0.0174533f;
+
+/* Convert the sensor data from Linux to Android
+ * Linux accelerometer unit is per g,  Android unit is m/s^2
+ * Linux gyroscope unit is degree/second, Android unit is radians/second
+ */
+static void convertFromLinuxToAndroid(std::vector<float>& values,
+                                      InputDeviceSensorType sensorType) {
+    for (size_t i = 0; i < values.size(); i++) {
+        switch (sensorType) {
+            case InputDeviceSensorType::ACCELEROMETER:
+                values[i] *= GRAVITY_MS2_UNIT;
+                break;
+            case InputDeviceSensorType::GYROSCOPE:
+                values[i] *= DEGREE_RADIAN_UNIT;
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+SensorInputMapper::SensorInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext) {}
+
+SensorInputMapper::~SensorInputMapper() {}
+
+uint32_t SensorInputMapper::getSources() {
+    return AINPUT_SOURCE_SENSOR;
+}
+
+template <typename T>
+bool SensorInputMapper::tryGetProperty(std::string keyName, T& outValue) {
+    const auto& config = getDeviceContext().getConfiguration();
+    return config.tryGetProperty(String8(keyName.c_str()), outValue);
+}
+
+void SensorInputMapper::parseSensorConfiguration(InputDeviceSensorType sensorType, int32_t absCode,
+                                                 int32_t sensorDataIndex, const Axis& axis) {
+    auto it = mSensors.find(sensorType);
+    if (it == mSensors.end()) {
+        Sensor sensor = createSensor(sensorType, axis);
+        sensor.dataVec[sensorDataIndex] = absCode;
+        mSensors.emplace(sensorType, sensor);
+    } else {
+        it->second.dataVec[sensorDataIndex] = absCode;
+    }
+}
+
+void SensorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    for (const auto& [sensorType, sensor] : mSensors) {
+        info->addSensorInfo(sensor.sensorInfo);
+        info->setHasSensor(true);
+    }
+}
+
+void SensorInputMapper::dump(std::string& dump) {
+    dump += INDENT2 "Sensor Input Mapper:\n";
+    dump += StringPrintf(INDENT3 " isDeviceEnabled %d\n", getDeviceContext().isDeviceEnabled());
+    dump += StringPrintf(INDENT3 " mHasHardwareTimestamp %d\n", mHasHardwareTimestamp);
+    dump += INDENT3 "Sensors:\n";
+    for (const auto& [sensorType, sensor] : mSensors) {
+        dump += StringPrintf(INDENT4 "%s\n", NamedEnum::string(sensorType).c_str());
+        dump += StringPrintf(INDENT5 "enabled: %d\n", sensor.enabled);
+        dump += StringPrintf(INDENT5 "samplingPeriod: %lld\n", sensor.samplingPeriod.count());
+        dump += StringPrintf(INDENT5 "maxBatchReportLatency: %lld\n",
+                             sensor.maxBatchReportLatency.count());
+        dump += StringPrintf(INDENT5 "maxRange: %f\n", sensor.sensorInfo.maxRange);
+        dump += StringPrintf(INDENT5 "power: %f\n", sensor.sensorInfo.power);
+        for (ssize_t i = 0; i < SENSOR_VEC_LEN; i++) {
+            int32_t rawAxis = sensor.dataVec[i];
+            dump += StringPrintf(INDENT5 "[%zd]: rawAxis: %d \n", i, rawAxis);
+            const auto it = mAxes.find(rawAxis);
+            if (it != mAxes.end()) {
+                const Axis& axis = it->second;
+                dump += StringPrintf(INDENT5 " min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f,"
+                                             "resolution=%0.5f\n",
+                                     axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
+                dump += StringPrintf(INDENT5 "  scale=%0.5f, offset=%0.5f\n", axis.scale,
+                                     axis.offset);
+                dump += StringPrintf(INDENT5 " rawMin=%d, rawMax=%d, "
+                                             "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
+                                     axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
+                                     axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz,
+                                     axis.rawAxisInfo.resolution);
+            }
+        }
+    }
+}
+
+void SensorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
+                                  uint32_t changes) {
+    InputMapper::configure(when, config, changes);
+
+    if (!changes) { // first time only
+        mDeviceEnabled = true;
+        // Check if device has MSC_TIMESTAMP event.
+        mHasHardwareTimestamp = getDeviceContext().hasMscEvent(MSC_TIMESTAMP);
+        // Collect all axes.
+        for (int32_t abs = ABS_X; abs <= ABS_MAX; abs++) {
+            // axis must be claimed by sensor class device
+            if (!(getAbsAxisUsage(abs, getDeviceContext().getDeviceClasses())
+                          .test(InputDeviceClass::SENSOR))) {
+                continue;
+            }
+            RawAbsoluteAxisInfo rawAxisInfo;
+            getAbsoluteAxisInfo(abs, &rawAxisInfo);
+            if (rawAxisInfo.valid) {
+                AxisInfo axisInfo;
+                // Axis doesn't need to be mapped, as sensor mapper doesn't generate any motion
+                // input events
+                axisInfo.mode = AxisInfo::MODE_NORMAL;
+                axisInfo.axis = -1;
+                // Check key layout map for sensor data mapping to axes
+                auto ret = getDeviceContext().mapSensor(abs);
+                if (ret) {
+                    InputDeviceSensorType sensorType = (*ret).first;
+                    int32_t sensorDataIndex = (*ret).second;
+                    const Axis& axis = createAxis(axisInfo, rawAxisInfo);
+                    parseSensorConfiguration(sensorType, abs, sensorDataIndex, axis);
+
+                    mAxes.insert({abs, axis});
+                }
+            }
+        }
+    }
+}
+
+SensorInputMapper::Axis SensorInputMapper::createAxis(const AxisInfo& axisInfo,
+                                                      const RawAbsoluteAxisInfo& rawAxisInfo) {
+    // Apply flat override.
+    int32_t rawFlat = axisInfo.flatOverride < 0 ? rawAxisInfo.flat : axisInfo.flatOverride;
+
+    float scale = std::numeric_limits<float>::signaling_NaN();
+    float offset = 0;
+
+    // resolution is 1 of sensor's unit.  For accelerometer, it is G, for gyroscope,
+    // it is degree/s.
+    scale = 1.0f / rawAxisInfo.resolution;
+    offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
+
+    const float max = rawAxisInfo.maxValue / rawAxisInfo.resolution;
+    const float min = rawAxisInfo.minValue / rawAxisInfo.resolution;
+    const float flat = rawFlat * scale;
+    const float fuzz = rawAxisInfo.fuzz * scale;
+    const float resolution = rawAxisInfo.resolution;
+
+    // To eliminate noise while the Sensor is at rest, filter out small variations
+    // in axis values up front.
+    const float filter = fuzz ? fuzz : flat * 0.25f;
+    return Axis(rawAxisInfo, axisInfo, scale, offset, min, max, flat, fuzz, resolution, filter);
+}
+
+void SensorInputMapper::reset(nsecs_t when) {
+    // Recenter all axes.
+    for (std::pair<const int32_t, Axis>& pair : mAxes) {
+        Axis& axis = pair.second;
+        axis.resetValue();
+    }
+    mHardwareTimestamp = 0;
+    mPrevMscTime = 0;
+    InputMapper::reset(when);
+}
+
+SensorInputMapper::Sensor SensorInputMapper::createSensor(InputDeviceSensorType sensorType,
+                                                          const Axis& axis) {
+    InputDeviceIdentifier identifier = getDeviceContext().getDeviceIdentifier();
+    // Sensor Id will be assigned to device Id to distinguish same sensor from multiple input
+    // devices, in such a way that the sensor Id will be same as input device Id.
+    // The sensorType is to distinguish different sensors within one device.
+    // One input device can only have 1 sensor for each sensor Type.
+    InputDeviceSensorInfo sensorInfo(identifier.name, std::to_string(identifier.vendor),
+                                     identifier.version, sensorType,
+                                     InputDeviceSensorAccuracy::ACCURACY_HIGH,
+                                     axis.max /* maxRange */, axis.scale /* resolution */,
+                                     0.0f /* power */, 0 /* minDelay */,
+                                     0 /* fifoReservedEventCount */, 0 /* fifoMaxEventCount */,
+                                     NamedEnum::string(sensorType), 0 /* maxDelay */, 0 /* flags */,
+                                     getDeviceId());
+
+    std::string prefix = "sensor." + NamedEnum::string(sensorType);
+    transform(prefix.begin(), prefix.end(), prefix.begin(), ::tolower);
+
+    int32_t reportingMode = 0;
+    if (!tryGetProperty(prefix + ".reportingMode", reportingMode)) {
+        sensorInfo.flags |= (reportingMode & REPORTING_MODE_MASK) << REPORTING_MODE_SHIFT;
+    }
+
+    tryGetProperty(prefix + ".maxDelay", sensorInfo.maxDelay);
+
+    tryGetProperty(prefix + ".minDelay", sensorInfo.minDelay);
+
+    tryGetProperty(prefix + ".power", sensorInfo.power);
+
+    tryGetProperty(prefix + ".fifoReservedEventCount", sensorInfo.fifoReservedEventCount);
+
+    tryGetProperty(prefix + ".fifoMaxEventCount", sensorInfo.fifoMaxEventCount);
+
+    return Sensor(sensorInfo);
+}
+
+void SensorInputMapper::processHardWareTimestamp(nsecs_t evTime, int32_t mscTime) {
+    // Since MSC_TIMESTAMP initial state is different from the system time, we
+    // calculate the difference between two MSC_TIMESTAMP events, and use that
+    // to calculate the system time that should be tagged on the event.
+    // if the first time MSC_TIMESTAMP, store it
+    // else calculate difference between previous and current MSC_TIMESTAMP
+    if (mPrevMscTime == 0) {
+        mHardwareTimestamp = evTime;
+        if (DEBUG_SENSOR_EVENT_DETAILS) {
+            ALOGD("Initialize hardware timestamp = %" PRId64, mHardwareTimestamp);
+        }
+    } else {
+        // Calculate the difference between current msc_timestamp and
+        // previous msc_timestamp, including when msc_timestamp wraps around.
+        uint32_t timeDiff = (mPrevMscTime > static_cast<uint32_t>(mscTime))
+                ? (UINT32_MAX - mPrevMscTime + static_cast<uint32_t>(mscTime + 1))
+                : (static_cast<uint32_t>(mscTime) - mPrevMscTime);
+
+        mHardwareTimestamp += timeDiff * 1000LL;
+    }
+    mPrevMscTime = static_cast<uint32_t>(mscTime);
+}
+
+void SensorInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+        case EV_ABS: {
+            auto it = mAxes.find(rawEvent->code);
+            if (it != mAxes.end()) {
+                Axis& axis = it->second;
+                axis.newValue = rawEvent->value * axis.scale + axis.offset;
+            }
+            break;
+        }
+
+        case EV_SYN:
+            switch (rawEvent->code) {
+                case SYN_REPORT:
+                    for (std::pair<const int32_t, Axis>& pair : mAxes) {
+                        Axis& axis = pair.second;
+                        axis.currentValue = axis.newValue;
+                    }
+                    sync(rawEvent->when, false /*force*/);
+                    break;
+            }
+            break;
+
+        case EV_MSC:
+            switch (rawEvent->code) {
+                case MSC_TIMESTAMP:
+                    // hardware timestamp is nano seconds
+                    processHardWareTimestamp(rawEvent->when, rawEvent->value);
+                    break;
+            }
+    }
+}
+
+bool SensorInputMapper::setSensorEnabled(InputDeviceSensorType sensorType, bool enabled) {
+    auto it = mSensors.find(sensorType);
+    if (it == mSensors.end()) {
+        return false;
+    }
+
+    it->second.enabled = enabled;
+    if (!enabled) {
+        it->second.resetValue();
+    }
+
+    /* Currently we can't enable/disable sensors individually. Enabling any sensor will enable
+     * the device
+     */
+    mDeviceEnabled = false;
+    for (const auto& [sensorType, sensor] : mSensors) {
+        // If any sensor is on we will turn on the device.
+        if (sensor.enabled) {
+            mDeviceEnabled = true;
+            break;
+        }
+    }
+    return true;
+}
+
+void SensorInputMapper::flushSensor(InputDeviceSensorType sensorType) {
+    auto it = mSensors.find(sensorType);
+    if (it == mSensors.end()) {
+        return;
+    }
+    auto& sensor = it->second;
+    sensor.lastSampleTimeNs = 0;
+    for (size_t i = 0; i < SENSOR_VEC_LEN; i++) {
+        int32_t abs = sensor.dataVec[i];
+        auto itAxis = mAxes.find(abs);
+        if (itAxis != mAxes.end()) {
+            Axis& axis = itAxis->second;
+            axis.resetValue();
+        }
+    }
+}
+
+bool SensorInputMapper::enableSensor(InputDeviceSensorType sensorType,
+                                     std::chrono::microseconds samplingPeriod,
+                                     std::chrono::microseconds maxBatchReportLatency) {
+    if (DEBUG_SENSOR_EVENT_DETAILS) {
+        ALOGD("Enable Sensor %s samplingPeriod %lld maxBatchReportLatency %lld",
+              NamedEnum::string(sensorType).c_str(), samplingPeriod.count(),
+              maxBatchReportLatency.count());
+    }
+
+    if (!setSensorEnabled(sensorType, true /* enabled */)) {
+        return false;
+    }
+
+    // Enable device
+    if (mDeviceEnabled) {
+        getDeviceContext().enableDevice();
+    }
+
+    // We know the sensor exists now, update the sampling period and batch report latency.
+    auto it = mSensors.find(sensorType);
+    it->second.samplingPeriod =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(samplingPeriod);
+    it->second.maxBatchReportLatency =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(maxBatchReportLatency);
+    return true;
+}
+
+void SensorInputMapper::disableSensor(InputDeviceSensorType sensorType) {
+    if (DEBUG_SENSOR_EVENT_DETAILS) {
+        ALOGD("Disable Sensor %s", NamedEnum::string(sensorType).c_str());
+    }
+
+    if (!setSensorEnabled(sensorType, false /* enabled */)) {
+        return;
+    }
+
+    // Disable device
+    if (!mDeviceEnabled) {
+        mHardwareTimestamp = 0;
+        mPrevMscTime = 0;
+        getDeviceContext().disableDevice();
+    }
+}
+
+void SensorInputMapper::sync(nsecs_t when, bool force) {
+    for (auto& [sensorType, sensor] : mSensors) {
+        // Skip if sensor not enabled
+        if (!sensor.enabled) {
+            continue;
+        }
+        std::vector<float> values;
+        for (ssize_t i = 0; i < SENSOR_VEC_LEN; i++) {
+            int32_t abs = sensor.dataVec[i];
+            auto it = mAxes.find(abs);
+            if (it != mAxes.end()) {
+                const Axis& axis = it->second;
+                values.push_back(axis.currentValue);
+            }
+        }
+
+        nsecs_t timestamp = mHasHardwareTimestamp ? mHardwareTimestamp : when;
+        if (DEBUG_SENSOR_EVENT_DETAILS) {
+            ALOGD("Sensor %s timestamp %" PRIu64 " values [%f %f %f]",
+                  NamedEnum::string(sensorType).c_str(), timestamp, values[0], values[1],
+                  values[2]);
+        }
+        if (sensor.lastSampleTimeNs.has_value() &&
+            timestamp - sensor.lastSampleTimeNs.value() < sensor.samplingPeriod.count()) {
+            if (DEBUG_SENSOR_EVENT_DETAILS) {
+                ALOGD("Sensor %s Skip a sample.", NamedEnum::string(sensorType).c_str());
+            }
+        } else {
+            // Convert to Android unit
+            convertFromLinuxToAndroid(values, sensorType);
+            // Notify dispatcher for sensor event
+            NotifySensorArgs args(getContext()->getNextId(), when, getDeviceId(),
+                                  AINPUT_SOURCE_SENSOR, sensorType, sensor.sensorInfo.accuracy,
+                                  sensor.accuracy !=
+                                          sensor.sensorInfo.accuracy /* accuracyChanged */,
+                                  timestamp /* hwTimestamp */, values);
+
+            getListener()->notifySensor(&args);
+            sensor.lastSampleTimeNs = timestamp;
+            sensor.accuracy = sensor.sensorInfo.accuracy;
+        }
+    }
+}
+
+} // namespace android
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.h b/services/inputflinger/reader/mapper/SensorInputMapper.h
new file mode 100644
index 0000000..3371002
--- /dev/null
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef _UI_INPUTREADER_SENSOR_INPUT_MAPPER_H
+#define _UI_INPUTREADER_SENSOR_INPUT_MAPPER_H
+
+#include "InputMapper.h"
+
+namespace android {
+// sensor data vector length
+static constexpr ssize_t SENSOR_VEC_LEN = 3;
+
+class SensorInputMapper : public InputMapper {
+public:
+    explicit SensorInputMapper(InputDeviceContext& deviceContext);
+    ~SensorInputMapper() override;
+
+    uint32_t getSources() override;
+    void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+    void dump(std::string& dump) override;
+    void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) override;
+    void reset(nsecs_t when) override;
+    void process(const RawEvent* rawEvent) override;
+    bool enableSensor(InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod,
+                      std::chrono::microseconds maxBatchReportLatency) override;
+    void disableSensor(InputDeviceSensorType sensorType) override;
+    void flushSensor(InputDeviceSensorType sensorType) override;
+
+private:
+    struct Axis {
+        explicit Axis(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo, float scale,
+                      float offset, float min, float max, float flat, float fuzz, float resolution,
+                      float filter)
+              : rawAxisInfo(rawAxisInfo),
+                axisInfo(axisInfo),
+                scale(scale),
+                offset(offset),
+                min(min),
+                max(max),
+                flat(flat),
+                fuzz(fuzz),
+                resolution(resolution),
+                filter(filter) {
+            resetValue();
+        }
+
+        RawAbsoluteAxisInfo rawAxisInfo;
+        AxisInfo axisInfo;
+
+        float scale;  // scale factor from raw to normalized values
+        float offset; // offset to add after scaling for normalization
+
+        float min;        // normalized inclusive minimum
+        float max;        // normalized inclusive maximum
+        float flat;       // normalized flat region size
+        float fuzz;       // normalized error tolerance
+        float resolution; // normalized resolution in units
+
+        float filter;       // filter out small variations of this size
+        float currentValue; // current value
+        float newValue;     // most recent value
+
+        void resetValue() {
+            this->currentValue = 0;
+            this->newValue = 0;
+        }
+    };
+
+    struct Sensor {
+        explicit Sensor(const InputDeviceSensorInfo& sensorInfo) : sensorInfo(sensorInfo) {
+            resetValue();
+        }
+        bool enabled;
+        InputDeviceSensorAccuracy accuracy;
+        std::chrono::nanoseconds samplingPeriod;
+        std::chrono::nanoseconds maxBatchReportLatency;
+        // last sample time in nano seconds
+        std::optional<nsecs_t> lastSampleTimeNs;
+        InputDeviceSensorInfo sensorInfo;
+        // Sensor X, Y, Z data mapping to abs
+        std::array<int32_t, SENSOR_VEC_LEN> dataVec;
+        void resetValue() {
+            this->enabled = false;
+            this->accuracy = InputDeviceSensorAccuracy::ACCURACY_NONE;
+            this->samplingPeriod = std::chrono::nanoseconds(0);
+            this->maxBatchReportLatency = std::chrono::nanoseconds(0);
+            this->lastSampleTimeNs = std::nullopt;
+            this->dataVec.fill(0);
+        }
+    };
+
+    static Axis createAxis(const AxisInfo& AxisInfo, const RawAbsoluteAxisInfo& rawAxisInfo);
+
+    // Axes indexed by raw ABS_* axis index.
+    std::unordered_map<int32_t, Axis> mAxes;
+
+    // hardware timestamp from MSC_TIMESTAMP
+    nsecs_t mHardwareTimestamp;
+    uint32_t mPrevMscTime;
+
+    bool mDeviceEnabled;
+    // Does device support MSC_TIMESTAMP
+    bool mHasHardwareTimestamp;
+
+    // Sensor list
+    std::unordered_map<InputDeviceSensorType, Sensor> mSensors;
+
+    void sync(nsecs_t when, bool force);
+
+    template <typename T>
+    bool tryGetProperty(std::string keyName, T& outValue);
+
+    void parseSensorConfiguration(InputDeviceSensorType sensorType, int32_t absCode,
+                                  int32_t sensorDataIndex, const Axis& axis);
+
+    void processHardWareTimestamp(nsecs_t evTime, int32_t evValue);
+
+    Sensor createSensor(InputDeviceSensorType sensorType, const Axis& axis);
+
+    bool setSensorEnabled(InputDeviceSensorType sensorType, bool enabled);
+};
+
+} // namespace android
+
+#endif // _UI_INPUTREADER_SENSOR_INPUT_MAPPER_H
\ No newline at end of file