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

Commit c734e4f2 authored by Garfield Tan's avatar Garfield Tan
Browse files

Clear cooked state and touch spots when disabled

Bug: 177403144
Test: Touch spots are gone after pressing power button with a finger on
the display.

Change-Id: I8c7991d728ba3ff84f982185ac6a30d1e2cae33e
parent 0ee421d7
Loading
Loading
Loading
Loading
+32 −13
Original line number Diff line number Diff line
@@ -608,8 +608,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
        if (hasStylus()) {
            mSource |= AINPUT_SOURCE_STYLUS;
        }
    } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN &&
               mParameters.hasAssociatedDisplay) {
    } else if (isTouchScreen()) {
        mSource = AINPUT_SOURCE_TOUCHSCREEN;
        mDeviceMode = DeviceMode::DIRECT;
        if (hasStylus()) {
@@ -1453,8 +1452,11 @@ void TouchInputMapper::sync(nsecs_t when) {
void TouchInputMapper::processRawTouches(bool timeout) {
    if (mDeviceMode == DeviceMode::DISABLED) {
        // Drop all input if the device is disabled.
        cancelTouch(mCurrentRawState.when);
        mCurrentRawState.clear();
        mRawStatesPending.clear();
        mCurrentCookedState.clear();
        updateTouchSpots();
        return;
    }

@@ -1586,17 +1588,7 @@ void TouchInputMapper::cookAndDispatch(nsecs_t when) {

        dispatchPointerUsage(when, policyFlags, pointerUsage);
    } else {
        if (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches &&
            mPointerController != nullptr) {
            mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT);
            mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);

            mPointerController->setButtonState(mCurrentRawState.buttonState);
            mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
                                         mCurrentCookedState.cookedPointerData.idToIndex,
                                         mCurrentCookedState.cookedPointerData.touchingIdBits,
                                         mViewport.displayId);
        }
        updateTouchSpots();

        if (!mCurrentMotionAborted) {
            dispatchButtonRelease(when, policyFlags);
@@ -1625,6 +1617,33 @@ void TouchInputMapper::cookAndDispatch(nsecs_t when) {
    mLastCookedState.copyFrom(mCurrentCookedState);
}

void TouchInputMapper::updateTouchSpots() {
    if (!mConfig.showTouches || mPointerController == nullptr) {
        return;
    }

    // Update touch spots when this is a touchscreen even when it's not enabled so that we can
    // clear touch spots.
    if (mDeviceMode != DeviceMode::DIRECT &&
        (mDeviceMode != DeviceMode::DISABLED || !isTouchScreen())) {
        return;
    }

    mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT);
    mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);

    mPointerController->setButtonState(mCurrentRawState.buttonState);
    mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
                                 mCurrentCookedState.cookedPointerData.idToIndex,
                                 mCurrentCookedState.cookedPointerData.touchingIdBits,
                                 mViewport.displayId);
}

bool TouchInputMapper::isTouchScreen() {
    return mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN &&
            mParameters.hasAssociatedDisplay;
}

void TouchInputMapper::applyExternalStylusButtonState(nsecs_t when) {
    if (mDeviceMode == DeviceMode::DIRECT && hasExternalStylus() && mExternalStylusId != -1) {
        mCurrentRawState.buttonState |= mExternalStylusState.buttons;
+6 −0
Original line number Diff line number Diff line
@@ -757,6 +757,12 @@ private:
                             PointerCoords* outCoords, const uint32_t* outIdToIndex,
                             BitSet32 idBits) const;

    // Returns if this touch device is a touch screen with an associated display.
    bool isTouchScreen();
    // Updates touch spots if they are enabled. Should only be used when this device is a
    // touchscreen.
    void updateTouchSpots();

    bool isPointInsideSurface(int32_t x, int32_t y);
    const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);

+51 −0
Original line number Diff line number Diff line
@@ -7362,6 +7362,57 @@ TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
    mFakeListener->assertNotifyMotionWasNotCalled();
}

TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
                                    DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, NO_PORT,
                                    ViewportType::INTERNAL);
    std::optional<DisplayViewport> optionalDisplayViewport =
            mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
    ASSERT_TRUE(optionalDisplayViewport.has_value());
    DisplayViewport displayViewport = *optionalDisplayViewport;

    configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
    prepareAxes(POSITION);
    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();

    // Finger down
    int32_t x = 100, y = 100;
    processPosition(mapper, x, y);
    processSync(mapper);

    NotifyMotionArgs motionArgs;
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);

    // Deactivate display viewport
    displayViewport.isActive = false;
    ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
    configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);

    // Finger move
    x += 10, y += 10;
    processPosition(mapper, x, y);
    processSync(mapper);

    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);

    // Reactivate display viewport
    displayViewport.isActive = true;
    ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
    configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);

    // Finger move again
    x += 10, y += 10;
    processPosition(mapper, x, y);
    processSync(mapper);

    // Gesture is aborted, so events after display is activated won't be dispatched until there is
    // no pointer on the touch device.
    mFakeListener->assertNotifyMotionWasNotCalled();
}

TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
    // Setup the first touch screen device.
    prepareAxes(POSITION | ID | SLOT);