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

Commit d5dc0406 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Updated MotionEvent to use Transform"

parents 60a04cae 9eaa22cf
Loading
Loading
Loading
Loading
+6 −12
Original line number Diff line number Diff line
@@ -527,13 +527,11 @@ public:

    inline void setActionButton(int32_t button) { mActionButton = button; }

    inline float getXScale() const { return mXScale; }
    inline float getXOffset() const { return mTransform.tx(); }

    inline float getYScale() const { return mYScale; }
    inline float getYOffset() const { return mTransform.ty(); }

    inline float getXOffset() const { return mXOffset; }

    inline float getYOffset() const { return mYOffset; }
    inline ui::Transform getTransform() const { return mTransform; }

    inline float getXPrecision() const { return mXPrecision; }

@@ -695,8 +693,8 @@ public:
    void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
                    std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
                    int32_t flags, int32_t edgeFlags, int32_t metaState, int32_t buttonState,
                    MotionClassification classification, float xScale, float yScale, float xOffset,
                    float yOffset, float xPrecision, float yPrecision, float rawXCursorPosition,
                    MotionClassification classification, const ui::Transform& transform,
                    float xPrecision, float yPrecision, float rawXCursorPosition,
                    float rawYCursorPosition, nsecs_t downTime, nsecs_t eventTime,
                    size_t pointerCount, const PointerProperties* pointerProperties,
                    const PointerCoords* pointerCoords);
@@ -713,7 +711,7 @@ public:

    // Apply 3x3 perspective matrix transformation.
    // Matrix is in row-major form and compatible with SkMatrix.
    void transform(const float matrix[9]);
    void transform(const std::array<float, 9>& matrix);

#ifdef __ANDROID__
    status_t readFromParcel(Parcel* parcel);
@@ -747,10 +745,6 @@ protected:
    int32_t mMetaState;
    int32_t mButtonState;
    MotionClassification mClassification;
    float mXScale;
    float mYScale;
    float mXOffset;
    float mYOffset;
    ui::Transform mTransform;
    float mXPrecision;
    float mYPrecision;
+11 −9
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <binder/Parcelable.h>
#include <input/Input.h>
#include <sys/stat.h>
#include <ui/Transform.h>
#include <utils/BitSet.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -115,10 +116,12 @@ struct InputMessage {
            uint8_t empty2[3];                   // 3 bytes to fill gap created by classification
            int32_t edgeFlags;
            nsecs_t downTime __attribute__((aligned(8)));
            float xScale;
            float yScale;
            float xOffset;
            float yOffset;
            float dsdx;
            float dtdx;
            float dtdy;
            float dsdy;
            float tx;
            float ty;
            float xPrecision;
            float yPrecision;
            float xCursorPosition;
@@ -319,11 +322,10 @@ public:
                                int32_t displayId, std::array<uint8_t, 32> hmac, int32_t action,
                                int32_t actionButton, int32_t flags, int32_t edgeFlags,
                                int32_t metaState, int32_t buttonState,
                                MotionClassification classification, float xScale, float yScale,
                                float xOffset, float yOffset, float xPrecision, float yPrecision,
                                float xCursorPosition, float yCursorPosition, nsecs_t downTime,
                                nsecs_t eventTime, uint32_t pointerCount,
                                const PointerProperties* pointerProperties,
                                MotionClassification classification, const ui::Transform& transform,
                                float xPrecision, float yPrecision, float xCursorPosition,
                                float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
                                uint32_t pointerCount, const PointerProperties* pointerProperties,
                                const PointerCoords* pointerCoords);

    /* Publishes a focus event to the input channel.
+87 −83
Original line number Diff line number Diff line
@@ -325,10 +325,10 @@ void PointerProperties::copyFrom(const PointerProperties& other) {
void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
                             std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
                             int32_t flags, int32_t edgeFlags, int32_t metaState,
                             int32_t buttonState, MotionClassification classification, float xScale,
                             float yScale, float xOffset, float yOffset, float xPrecision,
                             float yPrecision, float rawXCursorPosition, float rawYCursorPosition,
                             nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
                             int32_t buttonState, MotionClassification classification,
                             const ui::Transform& transform, float xPrecision, float yPrecision,
                             float rawXCursorPosition, float rawYCursorPosition, nsecs_t downTime,
                             nsecs_t eventTime, size_t pointerCount,
                             const PointerProperties* pointerProperties,
                             const PointerCoords* pointerCoords) {
    InputEvent::initialize(id, deviceId, source, displayId, hmac);
@@ -339,10 +339,7 @@ void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int3
    mMetaState = metaState;
    mButtonState = buttonState;
    mClassification = classification;
    mXScale = xScale;
    mYScale = yScale;
    mXOffset = xOffset;
    mYOffset = yOffset;
    mTransform = transform;
    mXPrecision = xPrecision;
    mYPrecision = yPrecision;
    mRawXCursorPosition = rawXCursorPosition;
@@ -365,10 +362,7 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
    mMetaState = other->mMetaState;
    mButtonState = other->mButtonState;
    mClassification = other->mClassification;
    mXScale = other->mXScale;
    mYScale = other->mYScale;
    mXOffset = other->mXOffset;
    mYOffset = other->mYOffset;
    mTransform = other->mTransform;
    mXPrecision = other->mXPrecision;
    mYPrecision = other->mYPrecision;
    mRawXCursorPosition = other->mRawXCursorPosition;
@@ -398,18 +392,20 @@ void MotionEvent::addSample(
}

float MotionEvent::getXCursorPosition() const {
    const float rawX = getRawXCursorPosition();
    return rawX * mXScale + mXOffset;
    vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
    return vals.x;
}

float MotionEvent::getYCursorPosition() const {
    const float rawY = getRawYCursorPosition();
    return rawY * mYScale + mYOffset;
    vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
    return vals.y;
}

void MotionEvent::setCursorPosition(float x, float y) {
    mRawXCursorPosition = (x - mXOffset) / mXScale;
    mRawYCursorPosition = (y - mYOffset) / mYScale;
    ui::Transform inverse = mTransform.inverse();
    vec2 vals = inverse.transform(x, y);
    mRawXCursorPosition = vals.x;
    mRawYCursorPosition = vals.y;
}

const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
@@ -421,14 +417,7 @@ float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
}

float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
    switch (axis) {
    case AMOTION_EVENT_AXIS_X:
        return value * mXScale + mXOffset;
    case AMOTION_EVENT_AXIS_Y:
        return value * mYScale + mYOffset;
    }
    return value;
    return getHistoricalAxisValue(axis, pointerIndex, getHistorySize());
}

const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
@@ -443,14 +432,23 @@ float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,

float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
        size_t historicalIndex) const {
    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
    if (axis != AMOTION_EVENT_AXIS_X && axis != AMOTION_EVENT_AXIS_Y) {
        return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
    }

    float rawX = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getX();
    float rawY = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getY();
    vec2 vals = mTransform.transform(rawX, rawY);

    switch (axis) {
    case AMOTION_EVENT_AXIS_X:
        return value * mXScale + mXOffset;
        return vals.x;
    case AMOTION_EVENT_AXIS_Y:
        return value * mYScale + mYOffset;
        return vals.y;
    }
    return value;

    // This should never happen
    return 0;
}

ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
@@ -464,23 +462,24 @@ ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
}

void MotionEvent::offsetLocation(float xOffset, float yOffset) {
    mXOffset += xOffset;
    mYOffset += yOffset;
    float currXOffset = mTransform.tx();
    float currYOffset = mTransform.ty();
    mTransform.set(currXOffset + xOffset, currYOffset + yOffset);
}

void MotionEvent::scale(float globalScaleFactor) {
    mXOffset *= globalScaleFactor;
    mYOffset *= globalScaleFactor;
    mTransform.set(mTransform.tx() * globalScaleFactor, mTransform.ty() * globalScaleFactor);
    mXPrecision *= globalScaleFactor;
    mYPrecision *= globalScaleFactor;

    size_t numSamples = mSamplePointerCoords.size();
    for (size_t i = 0; i < numSamples; i++) {
        mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
        mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor, globalScaleFactor,
                                                 globalScaleFactor);
    }
}

static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
static vec2 transformPoint(const std::array<float, 9>& matrix, float x, float y) {
    // Apply perspective transform like Skia.
    float newX = matrix[0] * x + matrix[1] * y + matrix[2];
    float newY = matrix[3] * x + matrix[4] * y + matrix[5];
@@ -488,22 +487,25 @@ static void transformPoint(const float matrix[9], float x, float y, float *outX,
    if (newZ) {
        newZ = 1.0f / newZ;
    }
    *outX = newX * newZ;
    *outY = newY * newZ;
    vec2 transformedPoint;
    transformedPoint.x = newX * newZ;
    transformedPoint.y = newY * newZ;
    return transformedPoint;
}

static float transformAngle(const float matrix[9], float angleRadians,
        float originX, float originY) {
static float transformAngle(const std::array<float, 9>& matrix, float angleRadians, float originX,
                            float originY) {
    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
    // Coordinate system: down is increasing Y, right is increasing X.
    float x = sinf(angleRadians);
    float y = -cosf(angleRadians);
    transformPoint(matrix, x, y, &x, &y);
    x -= originX;
    y -= originY;
    vec2 transformedPoint = transformPoint(matrix, x, y);

    transformedPoint.x -= originX;
    transformedPoint.y -= originY;

    // Derive the transformed vector's clockwise angle from vertical.
    float result = atan2f(x, -y);
    float result = atan2f(transformedPoint.x, -transformedPoint.y);
    if (result < - M_PI_2) {
        result += M_PI;
    } else if (result > M_PI_2) {
@@ -512,51 +514,51 @@ static float transformAngle(const float matrix[9], float angleRadians,
    return result;
}

void MotionEvent::transform(const float matrix[9]) {
    // The tricky part of this implementation is to preserve the value of
    // rawX and rawY.  So we apply the transformation to the first point
    // then derive an appropriate new X/Y offset that will preserve rawX
     // and rawY for that point.
    float oldXOffset = mXOffset;
    float oldYOffset = mYOffset;
    float newX, newY;
    float scaledRawX = getRawX(0) * mXScale;
    float scaledRawY = getRawY(0) * mYScale;
    transformPoint(matrix, scaledRawX + oldXOffset, scaledRawY + oldYOffset, &newX, &newY);
    mXOffset = newX - scaledRawX;
    mYOffset = newY - scaledRawY;
void MotionEvent::transform(const std::array<float, 9>& matrix) {
    // We want to preserve the rawX and rawY so we just update the transform
    // using the values of the transform passed in
    ui::Transform newTransform;
    newTransform.set(matrix);
    mTransform = newTransform * mTransform;

    // Determine how the origin is transformed by the matrix so that we
    // can transform orientation vectors.
    float originX, originY;
    transformPoint(matrix, 0, 0, &originX, &originY);

    // Apply the transformation to cursor position.
    if (isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) {
        float x = mRawXCursorPosition * mXScale + oldXOffset;
        float y = mRawYCursorPosition * mYScale + oldYOffset;
        transformPoint(matrix, x, y, &x, &y);
        mRawXCursorPosition = (x - mXOffset) / mXScale;
        mRawYCursorPosition = (y - mYOffset) / mYScale;
    }
    vec2 origin = transformPoint(matrix, 0, 0);

    // Apply the transformation to all samples.
    size_t numSamples = mSamplePointerCoords.size();
    for (size_t i = 0; i < numSamples; i++) {
        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) * mXScale + oldXOffset;
        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) * mYScale + oldYOffset;
        transformPoint(matrix, x, y, &x, &y);
        c.setAxisValue(AMOTION_EVENT_AXIS_X, (x - mXOffset) / mXScale);
        c.setAxisValue(AMOTION_EVENT_AXIS_Y, (y - mYOffset) / mYScale);

        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
                transformAngle(matrix, orientation, originX, originY));
                       transformAngle(matrix, orientation, origin.x, origin.y));
    }
}

#ifdef __ANDROID__
static status_t readFromParcel(ui::Transform& transform, const Parcel& parcel) {
    float dsdx, dtdx, tx, dtdy, dsdy, ty;
    status_t status = parcel.readFloat(&dsdx);
    status |= parcel.readFloat(&dtdx);
    status |= parcel.readFloat(&tx);
    status |= parcel.readFloat(&dtdy);
    status |= parcel.readFloat(&dsdy);
    status |= parcel.readFloat(&ty);

    transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
    return status;
}

static status_t writeToParcel(const ui::Transform& transform, Parcel& parcel) {
    status_t status = parcel.writeFloat(transform.dsdx());
    status |= parcel.writeFloat(transform.dtdx());
    status |= parcel.writeFloat(transform.tx());
    status |= parcel.writeFloat(transform.dtdy());
    status |= parcel.writeFloat(transform.dsdy());
    status |= parcel.writeFloat(transform.ty());
    return status;
}

status_t MotionEvent::readFromParcel(Parcel* parcel) {
    size_t pointerCount = parcel->readInt32();
    size_t sampleCount = parcel->readInt32();
@@ -582,10 +584,11 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) {
    mMetaState = parcel->readInt32();
    mButtonState = parcel->readInt32();
    mClassification = static_cast<MotionClassification>(parcel->readByte());
    mXScale = parcel->readFloat();
    mYScale = parcel->readFloat();
    mXOffset = parcel->readFloat();
    mYOffset = parcel->readFloat();

    result = android::readFromParcel(mTransform, *parcel);
    if (result != OK) {
        return result;
    }
    mXPrecision = parcel->readFloat();
    mYPrecision = parcel->readFloat();
    mRawXCursorPosition = parcel->readFloat();
@@ -640,10 +643,11 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {
    parcel->writeInt32(mMetaState);
    parcel->writeInt32(mButtonState);
    parcel->writeByte(static_cast<int8_t>(mClassification));
    parcel->writeFloat(mXScale);
    parcel->writeFloat(mYScale);
    parcel->writeFloat(mXOffset);
    parcel->writeFloat(mYOffset);

    status_t result = android::writeToParcel(mTransform, *parcel);
    if (result != OK) {
        return result;
    }
    parcel->writeFloat(mXPrecision);
    parcel->writeFloat(mYPrecision);
    parcel->writeFloat(mRawXCursorPosition);
+32 −27
Original line number Diff line number Diff line
@@ -195,14 +195,14 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const {
            msg->body.motion.edgeFlags = body.motion.edgeFlags;
            // nsecs_t downTime
            msg->body.motion.downTime = body.motion.downTime;
            // float xScale
            msg->body.motion.xScale = body.motion.xScale;
            // float yScale
            msg->body.motion.yScale = body.motion.yScale;
            // float xOffset
            msg->body.motion.xOffset = body.motion.xOffset;
            // float yOffset
            msg->body.motion.yOffset = body.motion.yOffset;

            msg->body.motion.dsdx = body.motion.dsdx;
            msg->body.motion.dtdx = body.motion.dtdx;
            msg->body.motion.dtdy = body.motion.dtdy;
            msg->body.motion.dsdy = body.motion.dsdy;
            msg->body.motion.tx = body.motion.tx;
            msg->body.motion.ty = body.motion.ty;

            // float xPrecision
            msg->body.motion.xPrecision = body.motion.xPrecision;
            // float yPrecision
@@ -469,10 +469,10 @@ status_t InputPublisher::publishMotionEvent(
        uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source, int32_t displayId,
        std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
        int32_t edgeFlags, int32_t metaState, int32_t buttonState,
        MotionClassification classification, float xScale, float yScale, float xOffset,
        float yOffset, float xPrecision, float yPrecision, float xCursorPosition,
        float yCursorPosition, nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
        MotionClassification classification, const ui::Transform& transform, float xPrecision,
        float yPrecision, float xCursorPosition, float yCursorPosition, nsecs_t downTime,
        nsecs_t eventTime, uint32_t pointerCount, const PointerProperties* pointerProperties,
        const PointerCoords* pointerCoords) {
    if (ATRACE_ENABLED()) {
        std::string message = StringPrintf(
                "publishMotionEvent(inputChannel=%s, action=%" PRId32 ")",
@@ -480,17 +480,18 @@ status_t InputPublisher::publishMotionEvent(
        ATRACE_NAME(message.c_str());
    }
    if (DEBUG_TRANSPORT_ACTIONS) {
        std::string transformString;
        transform.dump(transformString, "");
        ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
              "displayId=%" PRId32 ", "
              "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
              "metaState=0x%x, buttonState=0x%x, classification=%s, xScale=%.1f, yScale=%.1f, "
              "xOffset=%.1f, yOffset=%.1f, "
              "metaState=0x%x, buttonState=0x%x, classification=%s,"
              "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
              "pointerCount=%" PRIu32,
              "pointerCount=%" PRIu32 " transform=%s",
              mChannel->getName().c_str(), seq, deviceId, source, displayId, action, actionButton,
              flags, edgeFlags, metaState, buttonState,
              motionClassificationToString(classification), xScale, yScale, xOffset, yOffset,
              xPrecision, yPrecision, downTime, eventTime, pointerCount);
              motionClassificationToString(classification), xPrecision, yPrecision, downTime,
              eventTime, pointerCount, transformString.c_str());
    }

    if (!seq) {
@@ -519,10 +520,12 @@ status_t InputPublisher::publishMotionEvent(
    msg.body.motion.metaState = metaState;
    msg.body.motion.buttonState = buttonState;
    msg.body.motion.classification = classification;
    msg.body.motion.xScale = xScale;
    msg.body.motion.yScale = yScale;
    msg.body.motion.xOffset = xOffset;
    msg.body.motion.yOffset = yOffset;
    msg.body.motion.dsdx = transform.dsdx();
    msg.body.motion.dtdx = transform.dtdx();
    msg.body.motion.dtdy = transform.dtdy();
    msg.body.motion.dsdy = transform.dsdy();
    msg.body.motion.tx = transform.tx();
    msg.body.motion.ty = transform.ty();
    msg.body.motion.xPrecision = xPrecision;
    msg.body.motion.yPrecision = yPrecision;
    msg.body.motion.xCursorPosition = xCursorPosition;
@@ -1166,16 +1169,18 @@ void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage
        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
    }

    ui::Transform transform;
    transform.set({msg->body.motion.dsdx, msg->body.motion.dtdx, msg->body.motion.tx,
                   msg->body.motion.dtdy, msg->body.motion.dsdy, msg->body.motion.ty, 0, 0, 1});
    event->initialize(msg->body.motion.eventId, msg->body.motion.deviceId, msg->body.motion.source,
                      msg->body.motion.displayId, msg->body.motion.hmac, msg->body.motion.action,
                      msg->body.motion.actionButton, msg->body.motion.flags,
                      msg->body.motion.edgeFlags, msg->body.motion.metaState,
                      msg->body.motion.buttonState, msg->body.motion.classification,
                      msg->body.motion.xScale, msg->body.motion.yScale, msg->body.motion.xOffset,
                      msg->body.motion.yOffset, msg->body.motion.xPrecision,
                      msg->body.motion.yPrecision, msg->body.motion.xCursorPosition,
                      msg->body.motion.yCursorPosition, msg->body.motion.downTime,
                      msg->body.motion.eventTime, pointerCount, pointerProperties, pointerCoords);
                      msg->body.motion.buttonState, msg->body.motion.classification, transform,
                      msg->body.motion.xPrecision, msg->body.motion.yPrecision,
                      msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
                      msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
                      pointerProperties, pointerCoords);
}

void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
+1 −1
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) {
    }

    touchableRegionCropHandle = parcel->readStrongBinder();
    transform.set(std::array<float, 9>{dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
    transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});

    return OK;
}
Loading