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

Commit 93a0f91b authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Cancel touchscreen gestures from Dispatcher when display rotates

When the display rotates, previously, touchscreen devices were reset,
and a notifyDeviceReset is sent to Displatcher. When that happens,
Dispatcher cancells all active gestures from that device.

With this CL, we skip a device reset when the display rotates because
there is nothing that changes for the touchscreen device. Instead, when
we get a new set of input windows from SF in dispatcher, we track if the
orientation changes, and if it does, issue a cancellation for all
pointer events.

Bug: 185943742
Test: manual
Change-Id: Ic8ff19c0dc9cca7b1053a137ea041e5a0da82a76
parent 6a9a8312
Loading
Loading
Loading
Loading
+34 −0
Original line number Original line Diff line number Diff line
@@ -90,6 +90,14 @@ using com::android::internal::compat::IPlatformCompatNative;


namespace android::inputdispatcher {
namespace android::inputdispatcher {


// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
static bool isPerWindowInputRotationEnabled() {
    static const bool PER_WINDOW_INPUT_ROTATION =
            base::GetBoolProperty("persist.debug.per_window_input_rotation", false);
    return PER_WINDOW_INPUT_ROTATION;
}

// Default input dispatching timeout if there is no focused application or paused window
// Default input dispatching timeout if there is no focused application or paused window
// from which to determine an appropriate dispatching timeout.
// from which to determine an appropriate dispatching timeout.
const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
@@ -4441,6 +4449,13 @@ void InputDispatcher::setInputWindowsLocked(
    // Copy old handles for release if they are no longer present.
    // Copy old handles for release if they are no longer present.
    const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
    const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);


    // Save the old windows' orientation by ID before it gets updated.
    std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
    for (const sp<InputWindowHandle>& handle : oldWindowHandles) {
        oldWindowOrientations.emplace(handle->getId(),
                                      handle->getInfo()->transform.getOrientation());
    }

    updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
    updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);


    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
@@ -4489,6 +4504,25 @@ void InputDispatcher::setInputWindowsLocked(
        }
        }
    }
    }


    if (isPerWindowInputRotationEnabled()) {
        // Determine if the orientation of any of the input windows have changed, and cancel all
        // pointer events if necessary.
        for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
            const sp<InputWindowHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
            if (newWindowHandle != nullptr &&
                newWindowHandle->getInfo()->transform.getOrientation() !=
                        oldWindowOrientations[oldWindowHandle->getId()]) {
                std::shared_ptr<InputChannel> inputChannel =
                        getInputChannelLocked(newWindowHandle->getToken());
                if (inputChannel != nullptr) {
                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                                               "touched window's orientation changed");
                    synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
                }
            }
        }
    }

    // Release information for windows that are no longer present.
    // Release information for windows that are no longer present.
    // This ensures that unused input channels are released promptly.
    // This ensures that unused input channels are released promptly.
    // Otherwise, they might stick around until the window handle is destroyed
    // Otherwise, they might stick around until the window handle is destroyed
+10 −1
Original line number Original line Diff line number Diff line
@@ -682,7 +682,9 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
    int32_t rawHeight = mRawPointerAxes.getRawHeight();
    int32_t rawHeight = mRawPointerAxes.getRawHeight();


    bool viewportChanged = mViewport != *newViewport;
    bool viewportChanged = mViewport != *newViewport;
    bool skipViewportUpdate = false;
    if (viewportChanged) {
    if (viewportChanged) {
        bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation;
        mViewport = *newViewport;
        mViewport = *newViewport;


        if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) {
        if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) {
@@ -746,6 +748,8 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
            mPhysicalLeft = naturalPhysicalLeft;
            mPhysicalLeft = naturalPhysicalLeft;
            mPhysicalTop = naturalPhysicalTop;
            mPhysicalTop = naturalPhysicalTop;


            const int32_t oldSurfaceWidth = mRawSurfaceWidth;
            const int32_t oldSurfaceHeight = mRawSurfaceHeight;
            mRawSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
            mRawSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
            mRawSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
            mRawSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
@@ -763,6 +767,11 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
                mSurfaceOrientation = mParameters.orientationAware
                mSurfaceOrientation = mParameters.orientationAware
                        ? DISPLAY_ORIENTATION_0
                        ? DISPLAY_ORIENTATION_0
                        : getInverseRotation(mViewport.orientation);
                        : getInverseRotation(mViewport.orientation);
                // For orientation-aware devices that work in the un-rotated coordinate space, the
                // viewport update should be skipped if it is only a change in the orientation.
                skipViewportUpdate = mParameters.orientationAware &&
                        mRawSurfaceWidth == oldSurfaceWidth &&
                        mRawSurfaceHeight == oldSurfaceHeight && viewportOrientationChanged;
            } else {
            } else {
                mSurfaceOrientation = mParameters.orientationAware ? mViewport.orientation
                mSurfaceOrientation = mParameters.orientationAware ? mViewport.orientation
                                                                   : DISPLAY_ORIENTATION_0;
                                                                   : DISPLAY_ORIENTATION_0;
@@ -802,7 +811,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
        mPointerController.reset();
        mPointerController.reset();
    }
    }


    if (viewportChanged || deviceModeChanged) {
    if ((viewportChanged && !skipViewportUpdate) || 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(), mRawSurfaceWidth, mRawSurfaceHeight,
              getDeviceId(), getDeviceName().c_str(), mRawSurfaceWidth, mRawSurfaceHeight,