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

Commit d02eebc6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "InputDispatcher: Provide a way to transfer the entire gesture" into main

parents a6e2d76f 93b27491
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -112,6 +112,16 @@ flag {
  bug: "330752824"
}

flag {
  name: "allow_transfer_of_entire_gesture"
  namespace: "input"
  description: "When calling 'transferTouchGesture', the entire gesture (including new POINTER_DOWN events from the same device) will be automatically transferred to the destination window"
  bug: "397979572"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "enable_keyboard_classifier"
  namespace: "input"
+39 −10
Original line number Diff line number Diff line
@@ -2510,6 +2510,24 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
            return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
        }

        if (newTouchedWindowHandle != nullptr &&
            maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
            // Check if this should be redirected to another window, in case this window previously
            // called 'transferTouch' for this gesture.
            const auto it =
                    std::find_if(tempTouchState.windows.begin(), tempTouchState.windows.end(),
                                 [&](const TouchedWindow& touchedWindow) {
                                     return touchedWindow.forwardingWindowToken ==
                                             newTouchedWindowHandle->getToken() &&
                                             touchedWindow.hasTouchingPointers(entry.deviceId);
                                 });
            if (it != tempTouchState.windows.end()) {
                LOG(INFO) << "Forwarding pointer from " << newTouchedWindowHandle->getName()
                          << " to " << it->windowHandle->getName();
                newTouchedWindowHandle = it->windowHandle;
            }
        }

        std::vector<sp<WindowInfoHandle>> newTouchedWindows =
                findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId, mWindowInfos);
        if (newTouchedWindowHandle != nullptr) {
@@ -2550,7 +2568,8 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
                                                         isDownOrPointerDown
                                                                 ? std::make_optional(
                                                                           entry.eventTime)
                                                                 : std::nullopt);
                                                                 : std::nullopt,
                                                         /*forwardingWindowToken=*/nullptr);
                if (!addResult.ok()) {
                    LOG(ERROR) << "Error while processing " << entry << " for "
                               << windowHandle->getName();
@@ -2577,7 +2596,8 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
                        tempTouchState.addOrUpdateWindow(wallpaper,
                                                         InputTarget::DispatchMode::AS_IS,
                                                         wallpaperFlags, entry.deviceId, {pointer},
                                                         entry.eventTime);
                                                         entry.eventTime,
                                                         /*forwardingWindowToken=*/nullptr);
                    }
                }
            }
@@ -2676,7 +2696,8 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
                tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
                                                 InputTarget::DispatchMode::SLIPPERY_ENTER,
                                                 targetFlags, entry.deviceId, {pointer},
                                                 entry.eventTime);
                                                 entry.eventTime,
                                                 /*forwardingWindowToken=*/nullptr);

                // Check if the wallpaper window should deliver the corresponding event.
                slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
@@ -5833,7 +5854,7 @@ void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
}

bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
                                           bool isDragDrop) {
                                           bool isDragDrop, bool transferEntireGesture) {
    if (fromToken == toToken) {
        LOG_IF(INFO, DEBUG_FOCUS) << "Trivial transfer to same window.";
        return true;
@@ -5847,7 +5868,7 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s
                                   "transferring touch from this window to another window",
                                   traceContext.getTracker());

        auto result = mTouchStates.transferTouchGesture(fromToken, toToken);
        auto result = mTouchStates.transferTouchGesture(fromToken, toToken, transferEntireGesture);
        if (!result.has_value()) {
            return false;
        }
@@ -5891,7 +5912,8 @@ std::optional<std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<Pointe
                         std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>,
                         std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>>>
InputDispatcher::DispatcherTouchState::transferTouchGesture(const sp<android::IBinder>& fromToken,
                                                            const sp<android::IBinder>& toToken) {
                                                            const sp<android::IBinder>& toToken,
                                                            bool transferEntireGesture) {
    // Find the target touch state and touched window by fromToken.
    auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay(fromToken);
    if (!touchStateWindowAndDisplay.has_value()) {
@@ -5934,8 +5956,12 @@ InputDispatcher::DispatcherTouchState::transferTouchGesture(const sp<android::IB
    }
    // Transferring touch focus using this API should not effect the focused window.
    newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE;
    sp<IBinder> forwardingWindowToken;
    if (transferEntireGesture && com::android::input::flags::allow_transfer_of_entire_gesture()) {
        forwardingWindowToken = fromToken;
    }
    state.addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
                            deviceId, pointers, downTimeInTarget);
                            deviceId, pointers, downTimeInTarget, forwardingWindowToken);

    // Synthesize cancel for old window and down for new window.
    std::shared_ptr<Connection> fromConnection = mConnectionManager.getConnection(fromToken);
@@ -6017,7 +6043,8 @@ bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken
        fromToken = from->getToken();
    } // release lock

    return transferTouchGesture(fromToken, destChannelToken);
    return transferTouchGesture(fromToken, destChannelToken, /*isDragDrop=*/false,
                                /*transferEntireGesture=*/false);
}

void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
@@ -7195,7 +7222,8 @@ void InputDispatcher::DispatcherTouchState::slipWallpaperTouch(
        state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
                                InputTarget::Flags::WINDOW_IS_OBSCURED |
                                        InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
                                deviceId, pointers, entry.eventTime);
                                deviceId, pointers, entry.eventTime,
                                /*forwardingWindowToken=*/nullptr);
    }
}

@@ -7236,7 +7264,8 @@ InputDispatcher::DispatcherTouchState::transferWallpaperTouch(
        wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
                InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
        state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
                                deviceId, pointers, downTimeInTarget);
                                deviceId, pointers, downTimeInTarget,
                                /*forwardingWindowToken=*/nullptr);
        std::shared_ptr<Connection> wallpaperConnection =
                mConnectionManager.getConnection(newWallpaper->getToken());
        if (wallpaperConnection != nullptr) {
+3 −2
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ public:
    void setMaximumObscuringOpacityForTouch(float opacity) override;

    bool transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
                              bool isDragDrop = false) override;
                              bool isDragDrop, bool transferEntireGesture) override;
    bool transferTouchOnDisplay(const sp<IBinder>& destChannelToken,
                                ui::LogicalDisplayId displayId) override;

@@ -440,7 +440,8 @@ private:
        std::optional<
                std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<PointerProperties>,
                           std::list<CancellationArgs>, std::list<PointerDownArgs>>>
        transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
        transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
                             bool transferEntireGesture);

        base::Result<std::list<CancellationArgs>, status_t> pilferPointers(
                const sp<IBinder>& token, const Connection& requestingConnection);
+3 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ android::base::Result<void> TouchState::addOrUpdateWindow(
        const sp<WindowInfoHandle>& windowHandle, InputTarget::DispatchMode dispatchMode,
        ftl::Flags<InputTarget::Flags> targetFlags, DeviceId deviceId,
        const std::vector<PointerProperties>& touchingPointers,
        std::optional<nsecs_t> firstDownTimeInTarget) {
        std::optional<nsecs_t> firstDownTimeInTarget, sp<IBinder> forwardingWindowToken) {
    if (touchingPointers.empty()) {
        LOG(FATAL) << __func__ << "No pointers specified for " << windowHandle->getName();
        return android::base::Error();
@@ -88,6 +88,7 @@ android::base::Result<void> TouchState::addOrUpdateWindow(
        if (touchedWindow.windowHandle == windowHandle) {
            touchedWindow.dispatchMode = dispatchMode;
            touchedWindow.targetFlags |= targetFlags;
            touchedWindow.forwardingWindowToken = forwardingWindowToken;
            // For cases like hover enter/exit or DISPATCH_AS_OUTSIDE a touch window might not have
            // downTime set initially. Need to update existing window when a pointer is down for the
            // window.
@@ -103,6 +104,7 @@ android::base::Result<void> TouchState::addOrUpdateWindow(
    touchedWindow.windowHandle = windowHandle;
    touchedWindow.dispatchMode = dispatchMode;
    touchedWindow.targetFlags = targetFlags;
    touchedWindow.forwardingWindowToken = forwardingWindowToken;
    touchedWindow.addTouchingPointers(deviceId, touchingPointers);
    if (firstDownTimeInTarget) {
        touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget);
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ struct TouchState {
            const sp<android::gui::WindowInfoHandle>& windowHandle,
            InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
            DeviceId deviceId, const std::vector<PointerProperties>& touchingPointers,
            std::optional<nsecs_t> firstDownTimeInTarget);
            std::optional<nsecs_t> firstDownTimeInTarget, sp<IBinder> forwardingWindowToken);
    void addHoveringPointerToWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
                                    DeviceId deviceId, const PointerProperties& pointer, float x,
                                    float y);
Loading