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

Commit 2b5d249b authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Remove non-split touch from input code

The behaviour  was changed to permanently split since 24Q4. Therefore,
all of the existing complexity around supporting non-split can now be
removed.

Bug: 239934827
Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
Flag: NONE removing flag
Change-Id: I8ca23d502a4c23de2dfafbd7653318b8909912ce
parent a5bbaad8
Loading
Loading
Loading
Loading
+0 −4
Original line number Original line Diff line number Diff line
@@ -73,10 +73,6 @@ void WindowInfo::addTouchableRegion(const Rect& region) {
    touchableRegion.orSelf(region);
    touchableRegion.orSelf(region);
}
}


bool WindowInfo::supportsSplitTouch() const {
    return !inputConfig.test(InputConfig::PREVENT_SPLITTING);
}

bool WindowInfo::isSpy() const {
bool WindowInfo::isSpy() const {
    return inputConfig.test(InputConfig::SPY);
    return inputConfig.test(InputConfig::SPY);
}
}
+0 −2
Original line number Original line Diff line number Diff line
@@ -150,8 +150,6 @@ struct WindowInfo : public Parcelable {
                static_cast<uint32_t>(os::InputConfig::NOT_FOCUSABLE),
                static_cast<uint32_t>(os::InputConfig::NOT_FOCUSABLE),
        NOT_TOUCHABLE =
        NOT_TOUCHABLE =
                static_cast<uint32_t>(os::InputConfig::NOT_TOUCHABLE),
                static_cast<uint32_t>(os::InputConfig::NOT_TOUCHABLE),
        PREVENT_SPLITTING =
                static_cast<uint32_t>(os::InputConfig::PREVENT_SPLITTING),
        DUPLICATE_TOUCH_TO_WALLPAPER =
        DUPLICATE_TOUCH_TO_WALLPAPER =
                static_cast<uint32_t>(os::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER),
                static_cast<uint32_t>(os::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER),
        IS_WALLPAPER =
        IS_WALLPAPER =
+3 −10
Original line number Original line Diff line number Diff line
@@ -57,16 +57,9 @@ enum InputConfig {
    NOT_TOUCHABLE                = 1 << 3,
    NOT_TOUCHABLE                = 1 << 3,


    /**
    /**
     * Indicates that this window will not accept a touch event that is split between
     * This flag is now deprecated and should not be used.
     * more than one window. When set:
     */
     *  - If this window receives a DOWN event with the first pointer, all successive
    DEPRECATED_PREVENT_SPLITTING = 1 << 4,
     *    pointers that go down, regardless of their location on the screen, will be
     *    directed to this window;
     *  - If the DOWN event lands outside the touchable bounds of this window, no
     *    successive pointers that go down, regardless of their location on the screen,
     *    will be directed to this window.
     */
    PREVENT_SPLITTING            = 1 << 4,


    /**
    /**
     * Indicates that this window shows the wallpaper behind it, so all touch events
     * Indicates that this window shows the wallpaper behind it, so all touch events
+2 −2
Original line number Original line Diff line number Diff line
@@ -37,9 +37,9 @@ flag {
}
}


flag {
flag {
  name: "split_all_touches"
  name: "deprecate_split_touch_apis"
  namespace: "input"
  namespace: "input"
  description: "Set FLAG_SPLIT_TOUCHES to true for all windows, regardless of what they specify. This is essentially deprecating this flag by forcefully enabling the split functionality"
  description: "Deprecate all public APIs related to split touch because now all windows behave as if split touch is permanently enabled and there's no way for a window to disable split touch."
  bug: "239934827"
  bug: "239934827"
}
}


+13 −98
Original line number Original line Diff line number Diff line
@@ -788,38 +788,14 @@ void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& ta
    });
    });
}
}


/**
bool shouldSplitTouch(int32_t source) {
 * In general, touch should be always split between windows. Some exceptions:
    // We should never split mouse events. This is because the events that are produced by touchpad
 * 1. Don't split touch if all of the below is true:
    // are sent to InputDispatcher as two fingers (for example, pinch zoom), but they need to be
 *     (a) we have an active pointer down *and*
    // dispatched to the same window. In those cases, the behaviour is also slightly different from
 *     (b) a new pointer is going down that's from the same device *and*
    // default because the events should be sent to the cursor position rather than the x,y values
 *     (c) the window that's receiving the current pointer does not support split touch.
    // of each of the fingers.
 * 2. Don't split mouse events
    // The "normal" (uncaptured) events produced by touchpad and by mouse have SOURCE_MOUSE.
 */
    return !isFromSource(source, AINPUT_SOURCE_MOUSE);
bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) {
    if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) {
        // We should never split mouse events
        return false;
    }
    for (const TouchedWindow& touchedWindow : touchState.windows) {
        if (touchedWindow.windowHandle->getInfo()->isSpy()) {
            // Spy windows should not affect whether or not touch is split.
            continue;
        }
        if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) {
            continue;
        }
        if (touchedWindow.windowHandle->getInfo()->inputConfig.test(
                    gui::WindowInfo::InputConfig::IS_WALLPAPER)) {
            // Wallpaper window should not affect whether or not touch is split
            continue;
        }

        if (touchedWindow.hasTouchingPointers(entry.deviceId)) {
            return false;
        }
    }
    return true;
}
}


/**
/**
@@ -1528,21 +1504,9 @@ std::vector<sp<WindowInfoHandle>> InputDispatcher::DispatcherWindowInfo::findTou
        const WindowInfo& info = *windowHandle->getInfo();
        const WindowInfo& info = *windowHandle->getInfo();
        if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus,
        if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus,
                                  getDisplayTransform(displayId))) {
                                  getDisplayTransform(displayId))) {
            // Generally, we would skip any pointer that's outside of the window. However, if the
            // Skip if the pointer is outside of the window.
            // spy prevents splitting, and already has some of the pointers from this device, then
            // it should get more pointers from the same device, even if they are outside of that
            // window
            if (info.supportsSplitTouch()) {
                continue;
            }

            // We know that split touch is not supported. Skip this window only if it doesn't have
            // any touching pointers for this device already.
            if (!windowHasTouchingPointers(windowHandle, deviceId, touchStatesByDisplay)) {
            continue;
            continue;
        }
        }
            // If it already has pointers down for this device, then give it this pointer, too.
        }
        if (!info.isSpy()) {
        if (!info.isSpy()) {
            // The first touched non-spy window was found, so return the spy windows touched so far.
            // The first touched non-spy window was found, so return the spy windows touched so far.
            return spyWindows;
            return spyWindows;
@@ -2448,7 +2412,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio
        tempTouchState = *oldState;
        tempTouchState = *oldState;
    }
    }


    bool isSplit = shouldSplitTouch(tempTouchState, entry);
    bool isSplit = shouldSplitTouch(entry.source);


    const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
    const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
                                maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
                                maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
@@ -2501,17 +2465,6 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio
        LOG_IF(INFO, newTouchedWindowHandle == nullptr)
        LOG_IF(INFO, newTouchedWindowHandle == nullptr)
                << "No new touched window at (" << std::format("{:.1f}, {:.1f}", x, y)
                << "No new touched window at (" << std::format("{:.1f}, {:.1f}", x, y)
                << ") in display " << displayId;
                << ") in display " << displayId;
        // Handle the case where we did not find a window.
        if (!input_flags::split_all_touches()) {
            // If we are force splitting all touches, then touches outside of the window should
            // be dropped, even if this device already has pointers down in another window.
            if (newTouchedWindowHandle == nullptr) {
                // Try to assign the pointer to the first foreground window we find, if there is
                // one.
                newTouchedWindowHandle =
                        tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
            }
        }


        // Verify targeted injection.
        // Verify targeted injection.
        if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
        if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
@@ -2519,24 +2472,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio
            return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
            return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
        }
        }


        // Figure out whether splitting will be allowed for this window.
        if (newTouchedWindowHandle != nullptr) {
            if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
                // New window supports splitting, but we should never split mouse events.
                isSplit = !isFromMouse;
            } else if (isSplit) {
                // New window does not support splitting but we have already split events.
                // Ignore the new window.
                LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName()
                          << " because it doesn't support split touch";
                newTouchedWindowHandle = nullptr;
            }
        } else {
            // No window is touched, so set split to true. This will allow the next pointer down to
            // be delivered to a new window which supports split touch. Pointers from a mouse device
            // should never be split.
        isSplit = !isFromMouse;
        isSplit = !isFromMouse;
        }


        std::vector<sp<WindowInfoHandle>> newTouchedWindows =
        std::vector<sp<WindowInfoHandle>> newTouchedWindows =
                mWindowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId,
                mWindowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId,
@@ -2711,9 +2647,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio
                                             targets);
                                             targets);


                // Make a slippery entrance into the new window.
                // Make a slippery entrance into the new window.
                if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
                isSplit = !isFromMouse;
                isSplit = !isFromMouse;
                }


                ftl::Flags<InputTarget::Flags> targetFlags;
                ftl::Flags<InputTarget::Flags> targetFlags;
                if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
                if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
@@ -5835,18 +5769,6 @@ InputDispatcher::findTouchStateWindowAndDisplay(
                           const_cast<TouchedWindow*>(constTouchedWindow), displayId);
                           const_cast<TouchedWindow*>(constTouchedWindow), displayId);
}
}


bool InputDispatcher::windowHasTouchingPointers(
        const sp<WindowInfoHandle>& windowHandle, DeviceId deviceId,
        const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) {
    const auto& [touchState, touchedWindow, _] =
            findTouchStateWindowAndDisplay(windowHandle->getToken(), touchStatesByDisplay);
    if (touchState == nullptr) {
        // No touching pointers at all
        return false;
    }
    return touchState->hasTouchingPointers(deviceId);
}

bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
                                           bool isDragDrop) {
                                           bool isDragDrop) {
    if (fromToken == toToken) {
    if (fromToken == toToken) {
@@ -7168,13 +7090,6 @@ void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update)
    for (const auto& info : update.windowInfos) {
    for (const auto& info : update.windowInfos) {
        handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
        handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
        handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
        handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
        if (input_flags::split_all_touches()) {
            handlesPerDisplay[info.displayId]
                    .back()
                    ->editInfo()
                    ->setInputConfig(android::gui::WindowInfo::InputConfig::PREVENT_SPLITTING,
                                     false);
        }
    }
    }


    { // acquire lock
    { // acquire lock
Loading