Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67e1ae63 authored by Harry Cutts's avatar Harry Cutts
Browse files

InputDevice: return std::optional from getAbsoluteAxisInfo

This also allows us to remove the valid field from RawAbsoluteAxisInfo,
since we can represent "invalid" axes (which usually just meant absent
ones) using std::nullopt.

Test: atest inputflinger_tests
Test: m checkinput
Test: Check "Raw Touch Axes" section of touch input mapper info in
      dumpsys input
Bug: 245989146
Flag: EXEMPT refactor
Change-Id: I045a2e0b61a84657f2f8171c1fee3cc3e331ac86
parent 290b072d
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -513,10 +513,10 @@ ftl::Flags<InputDeviceClass> getAbsAxisUsage(int32_t axis,

// --- RawAbsoluteAxisInfo ---

std::ostream& operator<<(std::ostream& out, const RawAbsoluteAxisInfo& info) {
    if (info.valid) {
        out << "min=" << info.minValue << ", max=" << info.maxValue << ", flat=" << info.flat
            << ", fuzz=" << info.fuzz << ", resolution=" << info.resolution;
std::ostream& operator<<(std::ostream& out, const std::optional<RawAbsoluteAxisInfo>& info) {
    if (info) {
        out << "min=" << info->minValue << ", max=" << info->maxValue << ", flat=" << info->flat
            << ", fuzz=" << info->fuzz << ", resolution=" << info->resolution;
    } else {
        out << "unknown range";
    }
@@ -645,7 +645,6 @@ void EventHub::Device::populateAbsoluteAxisStates() {
            continue;
        }
        auto& [axisInfo, value] = absState[axis];
        axisInfo.valid = true;
        axisInfo.minValue = info.minimum;
        axisInfo.maxValue = info.maximum;
        axisInfo.flat = info.flat;
+1 −5
Original line number Diff line number Diff line
@@ -71,18 +71,14 @@ struct RawEvent {

/* Describes an absolute axis. */
struct RawAbsoluteAxisInfo {
    bool valid{false}; // true if the information is valid, false otherwise

    int32_t minValue{};   // minimum value
    int32_t maxValue{};   // maximum value
    int32_t flat{};       // center flat position, eg. flat == 8 means center is between -8 and 8
    int32_t fuzz{};       // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
    int32_t resolution{}; // resolution in units per mm or radians per mm

    inline void clear() { *this = RawAbsoluteAxisInfo(); }
};

std::ostream& operator<<(std::ostream& out, const RawAbsoluteAxisInfo& info);
std::ostream& operator<<(std::ostream& out, const std::optional<RawAbsoluteAxisInfo>& info);

/*
 * Input device classes.
+5 −11
Original line number Diff line number Diff line
@@ -305,22 +305,17 @@ public:
    inline int32_t getDeviceControllerNumber() const {
        return mEventHub->getDeviceControllerNumber(mId);
    }
    inline status_t getAbsoluteAxisInfo(int32_t code, RawAbsoluteAxisInfo* axisInfo) const {
    inline std::optional<RawAbsoluteAxisInfo> getAbsoluteAxisInfo(int32_t code) const {
        std::optional<RawAbsoluteAxisInfo> info = mEventHub->getAbsoluteAxisInfo(mId, code);
        if (!info.has_value()) {
            axisInfo->clear();
            return NAME_NOT_FOUND;
        }
        *axisInfo = *info;

        // Validate axis info for InputDevice.
        if (axisInfo->valid && axisInfo->minValue == axisInfo->maxValue) {
        if (info && info->minValue == info->maxValue) {
            // Historically, we deem axes with the same min and max values as invalid to avoid
            // dividing by zero when scaling by max - min.
            // TODO(b/291772515): Perform axis info validation on a per-axis basis when it is used.
            axisInfo->valid = false;
            return std::nullopt;
        }
        return OK;
        return info;
    }
    inline bool hasRelativeAxis(int32_t code) const {
        return mEventHub->hasRelativeAxis(mId, code);
@@ -435,8 +430,7 @@ public:
    }

    inline bool hasAbsoluteAxis(int32_t code) const {
        std::optional<RawAbsoluteAxisInfo> info = mEventHub->getAbsoluteAxisInfo(mId, code);
        return info.has_value() && info->valid;
        return mEventHub->getAbsoluteAxisInfo(mId, code).has_value();
    }
    inline bool isKeyPressed(int32_t scanCode) const {
        return mEventHub->getScanCodeState(mId, scanCode) == AKEY_STATE_DOWN;
+30 −31
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include "CapturedTouchpadEventConverter.h"

#include <optional>
#include <sstream>

#include <android-base/stringprintf.h>
@@ -53,32 +54,33 @@ CapturedTouchpadEventConverter::CapturedTouchpadEventConverter(
        mMotionAccumulator(motionAccumulator),
        mHasTouchMinor(deviceContext.hasAbsoluteAxis(ABS_MT_TOUCH_MINOR)),
        mHasToolMinor(deviceContext.hasAbsoluteAxis(ABS_MT_WIDTH_MINOR)) {
    RawAbsoluteAxisInfo orientationInfo;
    deviceContext.getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &orientationInfo);
    if (orientationInfo.valid) {
        if (orientationInfo.maxValue > 0) {
            mOrientationScale = M_PI_2 / orientationInfo.maxValue;
        } else if (orientationInfo.minValue < 0) {
            mOrientationScale = -M_PI_2 / orientationInfo.minValue;
    if (std::optional<RawAbsoluteAxisInfo> orientation =
                deviceContext.getAbsoluteAxisInfo(ABS_MT_ORIENTATION);
        orientation) {
        if (orientation->maxValue > 0) {
            mOrientationScale = M_PI_2 / orientation->maxValue;
        } else if (orientation->minValue < 0) {
            mOrientationScale = -M_PI_2 / orientation->minValue;
        }
    }

    // TODO(b/275369880): support touch.pressure.calibration and .scale properties when captured.
    RawAbsoluteAxisInfo pressureInfo;
    deviceContext.getAbsoluteAxisInfo(ABS_MT_PRESSURE, &pressureInfo);
    if (pressureInfo.valid && pressureInfo.maxValue > 0) {
        mPressureScale = 1.0 / pressureInfo.maxValue;
    if (std::optional<RawAbsoluteAxisInfo> pressure =
                deviceContext.getAbsoluteAxisInfo(ABS_MT_PRESSURE);
        pressure && pressure->maxValue > 0) {
        mPressureScale = 1.0 / pressure->maxValue;
    }

    RawAbsoluteAxisInfo touchMajorInfo, toolMajorInfo;
    deviceContext.getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &touchMajorInfo);
    deviceContext.getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &toolMajorInfo);
    mHasTouchMajor = touchMajorInfo.valid;
    mHasToolMajor = toolMajorInfo.valid;
    if (mHasTouchMajor && touchMajorInfo.maxValue != 0) {
        mSizeScale = 1.0f / touchMajorInfo.maxValue;
    } else if (mHasToolMajor && toolMajorInfo.maxValue != 0) {
        mSizeScale = 1.0f / toolMajorInfo.maxValue;
    std::optional<RawAbsoluteAxisInfo> touchMajor =
            deviceContext.getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR);
    std::optional<RawAbsoluteAxisInfo> toolMajor =
            deviceContext.getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR);
    mHasTouchMajor = touchMajor.has_value();
    mHasToolMajor = toolMajor.has_value();
    if (mHasTouchMajor && touchMajor->maxValue != 0) {
        mSizeScale = 1.0f / touchMajor->maxValue;
    } else if (mHasToolMajor && toolMajor->maxValue != 0) {
        mSizeScale = 1.0f / toolMajor->maxValue;
    }
}

@@ -113,15 +115,13 @@ void CapturedTouchpadEventConverter::populateMotionRanges(InputDeviceInfo& info)
    tryAddRawMotionRange(/*byref*/ info, AMOTION_EVENT_AXIS_TOOL_MAJOR, ABS_MT_WIDTH_MAJOR);
    tryAddRawMotionRange(/*byref*/ info, AMOTION_EVENT_AXIS_TOOL_MINOR, ABS_MT_WIDTH_MINOR);

    RawAbsoluteAxisInfo pressureInfo;
    mDeviceContext.getAbsoluteAxisInfo(ABS_MT_PRESSURE, &pressureInfo);
    if (pressureInfo.valid) {
    if (mDeviceContext.hasAbsoluteAxis(ABS_MT_PRESSURE)) {
        info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, SOURCE, 0, 1, 0, 0, 0);
    }

    RawAbsoluteAxisInfo orientationInfo;
    mDeviceContext.getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &orientationInfo);
    if (orientationInfo.valid && (orientationInfo.maxValue > 0 || orientationInfo.minValue < 0)) {
    if (std::optional<RawAbsoluteAxisInfo> orientation =
                mDeviceContext.getAbsoluteAxisInfo(ABS_MT_ORIENTATION);
        orientation && (orientation->maxValue > 0 || orientation->minValue < 0)) {
        info.addMotionRange(AMOTION_EVENT_AXIS_ORIENTATION, SOURCE, -M_PI_2, M_PI_2, 0, 0, 0);
    }

@@ -133,11 +133,10 @@ void CapturedTouchpadEventConverter::populateMotionRanges(InputDeviceInfo& info)
void CapturedTouchpadEventConverter::tryAddRawMotionRange(InputDeviceInfo& deviceInfo,
                                                          int32_t androidAxis,
                                                          int32_t evdevAxis) const {
    RawAbsoluteAxisInfo info;
    mDeviceContext.getAbsoluteAxisInfo(evdevAxis, &info);
    if (info.valid) {
        deviceInfo.addMotionRange(androidAxis, SOURCE, info.minValue, info.maxValue, info.flat,
                                  info.fuzz, info.resolution);
    std::optional<RawAbsoluteAxisInfo> info = mDeviceContext.getAbsoluteAxisInfo(evdevAxis);
    if (info) {
        deviceInfo.addMotionRange(androidAxis, SOURCE, info->minValue, info->maxValue, info->flat,
                                  info->fuzz, info->resolution);
    }
}

+5 −5
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ uint32_t ExternalStylusInputMapper::getSources() const {

void ExternalStylusInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
    InputMapper::populateDeviceInfo(info);
    if (mRawPressureAxis.valid) {
    if (mRawPressureAxis) {
        info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_STYLUS, 0.0f, 1.0f, 0.0f,
                            0.0f, 0.0f);
    }
@@ -50,7 +50,7 @@ void ExternalStylusInputMapper::dump(std::string& dump) {
std::list<NotifyArgs> ExternalStylusInputMapper::reconfigure(nsecs_t when,
                                                             const InputReaderConfiguration& config,
                                                             ConfigurationChanges changes) {
    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPressureAxis);
    mRawPressureAxis = getAbsoluteAxisInfo(ABS_PRESSURE);
    mTouchButtonAccumulator.configure();
    return {};
}
@@ -82,10 +82,10 @@ std::list<NotifyArgs> ExternalStylusInputMapper::sync(nsecs_t when) {
        mStylusState.toolType = ToolType::STYLUS;
    }

    if (mRawPressureAxis.valid) {
    if (mRawPressureAxis) {
        auto rawPressure = static_cast<float>(mSingleTouchMotionAccumulator.getAbsolutePressure());
        mStylusState.pressure = (rawPressure - mRawPressureAxis.minValue) /
                static_cast<float>(mRawPressureAxis.maxValue - mRawPressureAxis.minValue);
        mStylusState.pressure = (rawPressure - mRawPressureAxis->minValue) /
                static_cast<float>(mRawPressureAxis->maxValue - mRawPressureAxis->minValue);
    } else if (mTouchButtonAccumulator.hasButtonTouch()) {
        mStylusState.pressure = mTouchButtonAccumulator.isHovering() ? 0.0f : 1.0f;
    }
Loading