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

Commit 15cf6453 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Fix tap is wrong in landscape with cutout disabled" into rvc-dev am: e983bd43

Change-Id: I281e34af89044f5c5674d704c231b0d0a713db11
parents a254e15d e983bd43
Loading
Loading
Loading
Loading
+57 −49
Original line number Original line Diff line number Diff line
@@ -160,8 +160,8 @@ TouchInputMapper::TouchInputMapper(InputDeviceContext& deviceContext)
      : InputMapper(deviceContext),
      : InputMapper(deviceContext),
        mSource(0),
        mSource(0),
        mDeviceMode(DEVICE_MODE_DISABLED),
        mDeviceMode(DEVICE_MODE_DISABLED),
        mSurfaceWidth(-1),
        mRawSurfaceWidth(-1),
        mSurfaceHeight(-1),
        mRawSurfaceHeight(-1),
        mSurfaceLeft(0),
        mSurfaceLeft(0),
        mSurfaceTop(0),
        mSurfaceTop(0),
        mPhysicalWidth(-1),
        mPhysicalWidth(-1),
@@ -680,7 +680,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
                    naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
                    naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
                    naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
                    naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
                    naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
                    naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
                    naturalPhysicalLeft = mViewport.deviceHeight - naturalPhysicalWidth;
                    naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
                    naturalPhysicalTop = mViewport.physicalLeft;
                    naturalPhysicalTop = mViewport.physicalLeft;
                    naturalDeviceWidth = mViewport.deviceHeight;
                    naturalDeviceWidth = mViewport.deviceHeight;
                    naturalDeviceHeight = mViewport.deviceWidth;
                    naturalDeviceHeight = mViewport.deviceWidth;
@@ -701,7 +701,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
                    naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
                    naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
                    naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
                    naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
                    naturalPhysicalLeft = mViewport.physicalTop;
                    naturalPhysicalLeft = mViewport.physicalTop;
                    naturalPhysicalTop = mViewport.deviceWidth - naturalPhysicalHeight;
                    naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
                    naturalDeviceWidth = mViewport.deviceHeight;
                    naturalDeviceWidth = mViewport.deviceHeight;
                    naturalDeviceHeight = mViewport.deviceWidth;
                    naturalDeviceHeight = mViewport.deviceWidth;
                    break;
                    break;
@@ -729,10 +729,12 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
            mPhysicalLeft = naturalPhysicalLeft;
            mPhysicalLeft = naturalPhysicalLeft;
            mPhysicalTop = naturalPhysicalTop;
            mPhysicalTop = naturalPhysicalTop;


            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
            mRawSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
            mRawSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
            mSurfaceRight = mSurfaceLeft + naturalLogicalWidth;
            mSurfaceBottom = mSurfaceTop + naturalLogicalHeight;


            mSurfaceOrientation =
            mSurfaceOrientation =
                    mParameters.orientationAware ? mViewport.orientation : DISPLAY_ORIENTATION_0;
                    mParameters.orientationAware ? mViewport.orientation : DISPLAY_ORIENTATION_0;
@@ -742,8 +744,8 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
            mPhysicalLeft = 0;
            mPhysicalLeft = 0;
            mPhysicalTop = 0;
            mPhysicalTop = 0;


            mSurfaceWidth = rawWidth;
            mRawSurfaceWidth = rawWidth;
            mSurfaceHeight = rawHeight;
            mRawSurfaceHeight = rawHeight;
            mSurfaceLeft = 0;
            mSurfaceLeft = 0;
            mSurfaceTop = 0;
            mSurfaceTop = 0;
            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
@@ -769,12 +771,12 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
    if (viewportChanged || deviceModeChanged) {
    if (viewportChanged || deviceModeChanged) {
        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
              "display id %d",
              "display id %d",
              getDeviceId(), getDeviceName().c_str(), mSurfaceWidth, mSurfaceHeight,
              getDeviceId(), getDeviceName().c_str(), mRawSurfaceWidth, mRawSurfaceHeight,
              mSurfaceOrientation, mDeviceMode, mViewport.displayId);
              mSurfaceOrientation, mDeviceMode, mViewport.displayId);


        // Configure X and Y factors.
        // Configure X and Y factors.
        mXScale = float(mSurfaceWidth) / rawWidth;
        mXScale = float(mRawSurfaceWidth) / rawWidth;
        mYScale = float(mSurfaceHeight) / rawHeight;
        mYScale = float(mRawSurfaceHeight) / rawHeight;
        mXTranslate = -mSurfaceLeft;
        mXTranslate = -mSurfaceLeft;
        mYTranslate = -mSurfaceTop;
        mYTranslate = -mSurfaceTop;
        mXPrecision = 1.0f / mXScale;
        mXPrecision = 1.0f / mXScale;
@@ -793,7 +795,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
        mGeometricScale = avg(mXScale, mYScale);
        mGeometricScale = avg(mXScale, mYScale);


        // Size of diagonal axis.
        // Size of diagonal axis.
        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
        float diagonalSize = hypotf(mRawSurfaceWidth, mRawSurfaceHeight);


        // Size factors.
        // Size factors.
        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
@@ -956,13 +958,13 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
                mOrientedYPrecision = mXPrecision;
                mOrientedYPrecision = mXPrecision;


                mOrientedRanges.x.min = mYTranslate;
                mOrientedRanges.x.min = mYTranslate;
                mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
                mOrientedRanges.x.max = mRawSurfaceHeight + mYTranslate - 1;
                mOrientedRanges.x.flat = 0;
                mOrientedRanges.x.flat = 0;
                mOrientedRanges.x.fuzz = 0;
                mOrientedRanges.x.fuzz = 0;
                mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
                mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;


                mOrientedRanges.y.min = mXTranslate;
                mOrientedRanges.y.min = mXTranslate;
                mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
                mOrientedRanges.y.max = mRawSurfaceWidth + mXTranslate - 1;
                mOrientedRanges.y.flat = 0;
                mOrientedRanges.y.flat = 0;
                mOrientedRanges.y.fuzz = 0;
                mOrientedRanges.y.fuzz = 0;
                mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
                mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
@@ -973,13 +975,13 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
                mOrientedYPrecision = mYPrecision;
                mOrientedYPrecision = mYPrecision;


                mOrientedRanges.x.min = mXTranslate;
                mOrientedRanges.x.min = mXTranslate;
                mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
                mOrientedRanges.x.max = mRawSurfaceWidth + mXTranslate - 1;
                mOrientedRanges.x.flat = 0;
                mOrientedRanges.x.flat = 0;
                mOrientedRanges.x.fuzz = 0;
                mOrientedRanges.x.fuzz = 0;
                mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
                mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;


                mOrientedRanges.y.min = mYTranslate;
                mOrientedRanges.y.min = mYTranslate;
                mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
                mOrientedRanges.y.max = mRawSurfaceHeight + mYTranslate - 1;
                mOrientedRanges.y.flat = 0;
                mOrientedRanges.y.flat = 0;
                mOrientedRanges.y.fuzz = 0;
                mOrientedRanges.y.fuzz = 0;
                mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
                mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
@@ -992,7 +994,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
        if (mDeviceMode == DEVICE_MODE_POINTER) {
        if (mDeviceMode == DEVICE_MODE_POINTER) {
            // Compute pointer gesture detection parameters.
            // Compute pointer gesture detection parameters.
            float rawDiagonal = hypotf(rawWidth, rawHeight);
            float rawDiagonal = hypotf(rawWidth, rawHeight);
            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
            float displayDiagonal = hypotf(mRawSurfaceWidth, mRawSurfaceHeight);


            // Scale movements such that one whole swipe of the touch pad covers a
            // Scale movements such that one whole swipe of the touch pad covers a
            // given area relative to the diagonal size of the display when no acceleration
            // given area relative to the diagonal size of the display when no acceleration
@@ -1027,10 +1029,12 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {


void TouchInputMapper::dumpSurface(std::string& dump) {
void TouchInputMapper::dumpSurface(std::string& dump) {
    dump += StringPrintf(INDENT3 "%s\n", mViewport.toString().c_str());
    dump += StringPrintf(INDENT3 "%s\n", mViewport.toString().c_str());
    dump += StringPrintf(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
    dump += StringPrintf(INDENT3 "RawSurfaceWidth: %dpx\n", mRawSurfaceWidth);
    dump += StringPrintf(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
    dump += StringPrintf(INDENT3 "RawSurfaceHeight: %dpx\n", mRawSurfaceHeight);
    dump += StringPrintf(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
    dump += StringPrintf(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
    dump += StringPrintf(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
    dump += StringPrintf(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
    dump += StringPrintf(INDENT3 "SurfaceRight: %d\n", mSurfaceRight);
    dump += StringPrintf(INDENT3 "SurfaceBottom: %d\n", mSurfaceBottom);
    dump += StringPrintf(INDENT3 "PhysicalWidth: %dpx\n", mPhysicalWidth);
    dump += StringPrintf(INDENT3 "PhysicalWidth: %dpx\n", mPhysicalWidth);
    dump += StringPrintf(INDENT3 "PhysicalHeight: %dpx\n", mPhysicalHeight);
    dump += StringPrintf(INDENT3 "PhysicalHeight: %dpx\n", mPhysicalHeight);
    dump += StringPrintf(INDENT3 "PhysicalLeft: %d\n", mPhysicalLeft);
    dump += StringPrintf(INDENT3 "PhysicalLeft: %d\n", mPhysicalLeft);
@@ -1074,16 +1078,16 @@ void TouchInputMapper::configureVirtualKeys() {
        int32_t halfHeight = virtualKeyDefinition.height / 2;
        int32_t halfHeight = virtualKeyDefinition.height / 2;


        virtualKey.hitLeft =
        virtualKey.hitLeft =
                (virtualKeyDefinition.centerX - halfWidth) * touchScreenWidth / mSurfaceWidth +
                (virtualKeyDefinition.centerX - halfWidth) * touchScreenWidth / mRawSurfaceWidth +
                touchScreenLeft;
                touchScreenLeft;
        virtualKey.hitRight =
        virtualKey.hitRight =
                (virtualKeyDefinition.centerX + halfWidth) * touchScreenWidth / mSurfaceWidth +
                (virtualKeyDefinition.centerX + halfWidth) * touchScreenWidth / mRawSurfaceWidth +
                touchScreenLeft;
                touchScreenLeft;
        virtualKey.hitTop =
        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight) * touchScreenHeight /
                (virtualKeyDefinition.centerY - halfHeight) * touchScreenHeight / mSurfaceHeight +
                        mRawSurfaceHeight +
                touchScreenTop;
                touchScreenTop;
        virtualKey.hitBottom =
        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight /
                (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight / mSurfaceHeight +
                        mRawSurfaceHeight +
                touchScreenTop;
                touchScreenTop;
        mVirtualKeys.push_back(virtualKey);
        mVirtualKeys.push_back(virtualKey);
    }
    }
@@ -2188,13 +2192,10 @@ void TouchInputMapper::cookPointerData() {
        rotateAndScale(xTransformed, yTransformed);
        rotateAndScale(xTransformed, yTransformed);


        // Adjust X, Y, and coverage coords for surface orientation.
        // Adjust X, Y, and coverage coords for surface orientation.
        float x, y;
        float left, top, right, bottom;
        float left, top, right, bottom;


        switch (mSurfaceOrientation) {
        switch (mSurfaceOrientation) {
            case DISPLAY_ORIENTATION_90:
            case DISPLAY_ORIENTATION_90:
                x = yTransformed + mYTranslate;
                y = xTransformed + mXTranslate;
                left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
                left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
                right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
                right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
                bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
                bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
@@ -2207,8 +2208,6 @@ void TouchInputMapper::cookPointerData() {
                }
                }
                break;
                break;
            case DISPLAY_ORIENTATION_180:
            case DISPLAY_ORIENTATION_180:
                x = xTransformed + mXTranslate;
                y = yTransformed + mYTranslate;
                left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
                bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
@@ -2221,8 +2220,6 @@ void TouchInputMapper::cookPointerData() {
                }
                }
                break;
                break;
            case DISPLAY_ORIENTATION_270:
            case DISPLAY_ORIENTATION_270:
                x = yTransformed + mYTranslate;
                y = xTransformed + mXTranslate;
                left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
                bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
@@ -2235,8 +2232,6 @@ void TouchInputMapper::cookPointerData() {
                }
                }
                break;
                break;
            default:
            default:
                x = xTransformed + mXTranslate;
                y = yTransformed + mYTranslate;
                left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
                left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
                right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
                right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
                bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
                bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
@@ -2247,8 +2242,8 @@ void TouchInputMapper::cookPointerData() {
        // Write output coords.
        // Write output coords.
        PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
        PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
        out.clear();
        out.clear();
        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
        out.setAxisValue(AMOTION_EVENT_AXIS_X, xTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
        out.setAxisValue(AMOTION_EVENT_AXIS_Y, yTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
@@ -3624,34 +3619,47 @@ void TouchInputMapper::cancelTouch(nsecs_t when) {
    abortTouches(when, 0 /* policyFlags*/);
    abortTouches(when, 0 /* policyFlags*/);
}
}


// Transform raw coordinate to surface coordinate
void TouchInputMapper::rotateAndScale(float& x, float& y) {
void TouchInputMapper::rotateAndScale(float& x, float& y) {
    // Scale to surface coordinate.
    const float xScaled = float(x - mRawPointerAxes.x.minValue) * mXScale;
    const float yScaled = float(y - mRawPointerAxes.y.minValue) * mYScale;

    // Rotate to surface coordinate.
    // 0 - no swap and reverse.
    // 90 - swap x/y and reverse y.
    // 180 - reverse x, y.
    // 270 - swap x/y and reverse x.
    switch (mSurfaceOrientation) {
    switch (mSurfaceOrientation) {
        case DISPLAY_ORIENTATION_0:
            x = xScaled + mXTranslate;
            y = yScaled + mYTranslate;
            break;
        case DISPLAY_ORIENTATION_90:
        case DISPLAY_ORIENTATION_90:
            x = float(mRawPointerAxes.x.maxValue - x) * mXScale;
            y = mSurfaceRight - xScaled;
            y = float(y - mRawPointerAxes.y.minValue) * mYScale;
            x = yScaled + mYTranslate;
            break;
            break;
        case DISPLAY_ORIENTATION_180:
        case DISPLAY_ORIENTATION_180:
            x = float(mRawPointerAxes.x.maxValue - x) * mXScale;
            x = mSurfaceRight - xScaled;
            y = float(mRawPointerAxes.y.maxValue - y) * mYScale;
            y = mSurfaceBottom - yScaled;
            break;
            break;
        case DISPLAY_ORIENTATION_270:
        case DISPLAY_ORIENTATION_270:
            x = float(x - mRawPointerAxes.x.minValue) * mXScale;
            y = xScaled + mXTranslate;
            y = float(mRawPointerAxes.y.maxValue - y) * mYScale;
            x = mSurfaceBottom - yScaled;
            break;
            break;
        default:
        default:
            x = float(x - mRawPointerAxes.x.minValue) * mXScale;
            assert(false);
            y = float(y - mRawPointerAxes.y.minValue) * mYScale;
            break;
    }
    }
}
}


bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
    float xTransformed = x, yTransformed = y;
    const float xScaled = (x - mRawPointerAxes.x.minValue) * mXScale;
    rotateAndScale(xTransformed, yTransformed);
    const float yScaled = (y - mRawPointerAxes.y.minValue) * mYScale;

    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue &&
    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue &&
            xTransformed >= mSurfaceLeft && xTransformed <= mSurfaceLeft + mSurfaceWidth &&
            xScaled >= mSurfaceLeft && xScaled <= mSurfaceRight &&
            y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue &&
            y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue &&
            yTransformed >= mSurfaceTop && yTransformed <= mSurfaceTop + mSurfaceHeight;
            yScaled >= mSurfaceTop && yScaled <= mSurfaceBottom;
}
}


const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) {
const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) {
+6 −2
Original line number Original line Diff line number Diff line
@@ -407,12 +407,16 @@ private:
    // The surface orientation, width and height set by configureSurface().
    // The surface orientation, width and height set by configureSurface().
    // The width and height are derived from the viewport but are specified
    // The width and height are derived from the viewport but are specified
    // in the natural orientation.
    // in the natural orientation.
    // They could be used for calculating diagonal, scaling factors, and virtual keys.
    int32_t mRawSurfaceWidth;
    int32_t mRawSurfaceHeight;

    // The surface origin specifies how the surface coordinates should be translated
    // The surface origin specifies how the surface coordinates should be translated
    // to align with the logical display coordinate space.
    // to align with the logical display coordinate space.
    int32_t mSurfaceWidth;
    int32_t mSurfaceHeight;
    int32_t mSurfaceLeft;
    int32_t mSurfaceLeft;
    int32_t mSurfaceTop;
    int32_t mSurfaceTop;
    int32_t mSurfaceRight;
    int32_t mSurfaceBottom;


    // Similar to the surface coordinates, but in the raw display coordinate space rather than in
    // Similar to the surface coordinates, but in the raw display coordinate space rather than in
    // the logical coordinate space.
    // the logical coordinate space.
+126 −44
Original line number Original line Diff line number Diff line
@@ -6990,51 +6990,7 @@ TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
    ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
    ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
}
}


/**
 * Test touch should not work if outside of surface.
 */
TEST_F(MultiTouchInputMapperTest, Viewports_SurfaceRange) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(DISPLAY_ORIENTATION_0);
    prepareAxes(POSITION);
    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();


    // Touch on left-top area should work.
    int32_t rawX = DISPLAY_WIDTH / 2 - 1;
    int32_t rawY = DISPLAY_HEIGHT / 2 - 1;
    processPosition(mapper, rawX, rawY);
    processSync(mapper);

    NotifyMotionArgs args;
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));

    // Reset.
    mapper.reset(ARBITRARY_TIME);

    // Let logical display be different to physical display and rotate 90-degrees.
    std::optional<DisplayViewport> internalViewport =
            mFakePolicy->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
    internalViewport->orientation = DISPLAY_ORIENTATION_90;
    internalViewport->logicalLeft = 0;
    internalViewport->logicalTop = 0;
    internalViewport->logicalRight = DISPLAY_HEIGHT;
    internalViewport->logicalBottom = DISPLAY_WIDTH / 2;

    internalViewport->physicalLeft = DISPLAY_HEIGHT;
    internalViewport->physicalTop = DISPLAY_WIDTH / 2;
    internalViewport->physicalRight = DISPLAY_HEIGHT;
    internalViewport->physicalBottom = DISPLAY_WIDTH;

    internalViewport->deviceWidth = DISPLAY_HEIGHT;
    internalViewport->deviceHeight = DISPLAY_WIDTH;
    mFakePolicy->updateViewport(internalViewport.value());
    configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);

    // Display align to right-top after rotate 90-degrees, touch on left-top area should not work.
    processPosition(mapper, rawX, rawY);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}


TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    addConfigurationProperty("touch.deviceType", "touchScreen");
@@ -7161,4 +7117,130 @@ TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
    ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
}
}

/**
 * Test touch should not work if outside of surface.
 */
class MultiTouchInputMapperTest_SurfaceRange : public MultiTouchInputMapperTest {
protected:
    void halfDisplayToCenterHorizontal(int32_t orientation) {
        std::optional<DisplayViewport> internalViewport =
                mFakePolicy->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);

        // Half display to (width/4, 0, width * 3/4, height) to make display has offset.
        internalViewport->orientation = orientation;
        if (orientation == DISPLAY_ORIENTATION_90 || orientation == DISPLAY_ORIENTATION_270) {
            internalViewport->logicalLeft = 0;
            internalViewport->logicalTop = 0;
            internalViewport->logicalRight = DISPLAY_HEIGHT;
            internalViewport->logicalBottom = DISPLAY_WIDTH / 2;

            internalViewport->physicalLeft = 0;
            internalViewport->physicalTop = DISPLAY_WIDTH / 4;
            internalViewport->physicalRight = DISPLAY_HEIGHT;
            internalViewport->physicalBottom = DISPLAY_WIDTH * 3 / 4;

            internalViewport->deviceWidth = DISPLAY_HEIGHT;
            internalViewport->deviceHeight = DISPLAY_WIDTH;
        } else {
            internalViewport->logicalLeft = 0;
            internalViewport->logicalTop = 0;
            internalViewport->logicalRight = DISPLAY_WIDTH / 2;
            internalViewport->logicalBottom = DISPLAY_HEIGHT;

            internalViewport->physicalLeft = DISPLAY_WIDTH / 4;
            internalViewport->physicalTop = 0;
            internalViewport->physicalRight = DISPLAY_WIDTH * 3 / 4;
            internalViewport->physicalBottom = DISPLAY_HEIGHT;

            internalViewport->deviceWidth = DISPLAY_WIDTH;
            internalViewport->deviceHeight = DISPLAY_HEIGHT;
        }

        mFakePolicy->updateViewport(internalViewport.value());
        configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
    }

    void processPositionAndVerify(MultiTouchInputMapper& mapper, int32_t xInside, int32_t yInside,
                                  int32_t xOutside, int32_t yOutside, int32_t xExpected,
                                  int32_t yExpected) {
        // touch on outside area should not work.
        processPosition(mapper, toRawX(xOutside), toRawY(yOutside));
        processSync(mapper);
        ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());

        // touch on inside area should receive the event.
        NotifyMotionArgs args;
        processPosition(mapper, toRawX(xInside), toRawY(yInside));
        processSync(mapper);
        ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
        ASSERT_NEAR(xExpected, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
        ASSERT_NEAR(yExpected, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);

        // Reset.
        mapper.reset(ARBITRARY_TIME);
    }
};

TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(DISPLAY_ORIENTATION_0);
    prepareAxes(POSITION);
    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();

    // Touch on center of normal display should work.
    const int32_t x = DISPLAY_WIDTH / 4;
    const int32_t y = DISPLAY_HEIGHT / 2;
    processPosition(mapper, toRawX(x), toRawY(y));
    processSync(mapper);
    NotifyMotionArgs args;
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], x, y, 1.0f, 0.0f, 0.0f, 0.0f,
                                                0.0f, 0.0f, 0.0f, 0.0f));
    // Reset.
    mapper.reset(ARBITRARY_TIME);

    // Let physical display be different to device, and make surface and physical could be 1:1.
    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_0);

    const int32_t xExpected = (x + 1) - (DISPLAY_WIDTH / 4);
    const int32_t yExpected = y;
    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
}

TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_90) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(DISPLAY_ORIENTATION_0);
    prepareAxes(POSITION);
    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();

    // Half display to (width/4, 0, width * 3/4, height) and rotate 90-degrees.
    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_90);

    const int32_t x = DISPLAY_WIDTH / 4;
    const int32_t y = DISPLAY_HEIGHT / 2;

    // expect x/y = swap x/y then reverse y.
    const int32_t xExpected = y;
    const int32_t yExpected = (DISPLAY_WIDTH * 3 / 4) - (x + 1);
    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
}

TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_270) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(DISPLAY_ORIENTATION_0);
    prepareAxes(POSITION);
    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();

    // Half display to (width/4, 0, width * 3/4, height) and rotate 270-degrees.
    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_270);

    const int32_t x = DISPLAY_WIDTH / 4;
    const int32_t y = DISPLAY_HEIGHT / 2;

    // expect x/y = swap x/y then reverse x.
    constexpr int32_t xExpected = DISPLAY_HEIGHT - y;
    constexpr int32_t yExpected = (x + 1) - DISPLAY_WIDTH / 4;
    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
}
} // namespace android
} // namespace android