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

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

Merge "TouchedWindow: store tool type in addition to pointer id" into main

parents 88dd3ae7 1ff00cce
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -515,6 +515,8 @@ struct PointerProperties {
    PointerProperties& operator=(const PointerProperties&) = default;
};

std::ostream& operator<<(std::ostream& out, const PointerProperties& properties);

// TODO(b/211379801) : Use a strong type from ftl/mixins.h instead
using DeviceId = int32_t;

+5 −0
Original line number Diff line number Diff line
@@ -379,6 +379,11 @@ std::ostream& operator<<(std::ostream& out, const KeyEvent& event) {
    return out;
}

std::ostream& operator<<(std::ostream& out, const PointerProperties& properties) {
    out << "Pointer(id=" << properties.id << ", " << ftl::enum_string(properties.toolType) << ")";
    return out;
}

// --- PointerCoords ---

float PointerCoords::getAxisValue(int32_t axis) const {
+45 −39
Original line number Diff line number Diff line
@@ -253,6 +253,14 @@ Result<void> validateInputEvent(const InputEvent& event) {
    }
}

std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) {
    std::bitset<MAX_POINTER_ID + 1> pointerIds;
    for (const PointerProperties& pointer : pointers) {
        pointerIds.set(pointer.id);
    }
    return pointerIds;
}

std::string dumpRegion(const Region& region) {
    if (region.isEmpty()) {
        return "<empty>";
@@ -631,15 +639,15 @@ std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
    }

    // We should consider all hovering pointers here. But for now, just use the first one
    const int32_t pointerId = entry.pointerProperties[0].id;
    const PointerProperties& pointer = entry.pointerProperties[0];

    std::set<sp<WindowInfoHandle>> oldWindows;
    if (oldState != nullptr) {
        oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId);
        oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
    }

    std::set<sp<WindowInfoHandle>> newWindows =
            newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointerId);
            newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id);

    // If the pointer is no longer in the new window set, send HOVER_EXIT.
    for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
@@ -673,7 +681,7 @@ std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
            }
            touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
        }
        touchedWindow.addHoveringPointer(entry.deviceId, pointerId);
        touchedWindow.addHoveringPointer(entry.deviceId, pointer);
        if (canReceiveForegroundTouches(*newWindow->getInfo())) {
            touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
        }
@@ -2320,7 +2328,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
        /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
        const auto [x, y] = resolveTouchedPosition(entry);
        const int32_t pointerIndex = MotionEvent::getActionIndex(action);
        const int32_t pointerId = entry.pointerProperties[pointerIndex].id;
        const PointerProperties& pointer = entry.pointerProperties[pointerIndex];
        // Outside targets should be added upon first dispatched DOWN event. That means, this should
        // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
        const bool isStylus = isPointerFromStylus(entry, pointerIndex);
@@ -2328,7 +2336,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
                findTouchedWindowAtLocked(displayId, x, y, isStylus);

        if (isDown) {
            targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointerId);
            targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id);
        }
        // Handle the case where we did not find a window.
        if (newTouchedWindowHandle == nullptr) {
@@ -2386,7 +2394,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(

            if (isHoverAction) {
                // The "windowHandle" is the target of this hovering pointer.
                tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointerId);
                tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer);
            }

            // Set target flags.
@@ -2409,12 +2417,10 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
            // Update the temporary touch state.

            if (!isHoverAction) {
                std::bitset<MAX_POINTER_ID + 1> pointerIds;
                pointerIds.set(pointerId);
                const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
                        maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
                tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS,
                                                 targetFlags, entry.deviceId, pointerIds,
                                                 targetFlags, entry.deviceId, {pointer},
                                                 isDownOrPointerDown
                                                         ? std::make_optional(entry.eventTime)
                                                         : std::nullopt);
@@ -2437,7 +2443,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
                        }
                        tempTouchState.addOrUpdateWindow(wallpaper,
                                                         InputTarget::DispatchMode::AS_IS,
                                                         wallpaperFlags, entry.deviceId, pointerIds,
                                                         wallpaperFlags, entry.deviceId, {pointer},
                                                         entry.eventTime);
                    }
                }
@@ -2448,12 +2454,12 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
        // make it pilfering. This will prevent other non-spy windows from getting this pointer,
        // which is a specific behaviour that we want.
        for (TouchedWindow& touchedWindow : tempTouchState.windows) {
            if (touchedWindow.hasTouchingPointer(entry.deviceId, pointerId) &&
            if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) &&
                touchedWindow.hasPilferingPointers(entry.deviceId)) {
                // This window is already pilfering some pointers, and this new pointer is also
                // going to it. Therefore, take over this pointer and don't give it to anyone
                // else.
                touchedWindow.addPilferingPointer(entry.deviceId, pointerId);
                touchedWindow.addPilferingPointer(entry.deviceId, pointer.id);
            }
        }

@@ -2522,8 +2528,8 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(

                // Make a slippery exit from the old window.
                std::bitset<MAX_POINTER_ID + 1> pointerIds;
                const int32_t pointerId = entry.pointerProperties[0].id;
                pointerIds.set(pointerId);
                const PointerProperties& pointer = entry.pointerProperties[0];
                pointerIds.set(pointer.id);

                const TouchedWindow& touchedWindow =
                        tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
@@ -2553,13 +2559,13 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(

                tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
                                                 InputTarget::DispatchMode::SLIPPERY_ENTER,
                                                 targetFlags, entry.deviceId, pointerIds,
                                                 targetFlags, entry.deviceId, {pointer},
                                                 entry.eventTime);

                // Check if the wallpaper window should deliver the corresponding event.
                slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
                                   tempTouchState, entry.deviceId, pointerId, targets);
                tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointerId,
                                   tempTouchState, entry.deviceId, pointer, targets);
                tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id,
                                                               oldTouchedWindowHandle);
            }
        }
@@ -2568,14 +2574,12 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
        if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
            // If no split, we suppose all touched windows should receive pointer down.
            const int32_t pointerIndex = MotionEvent::getActionIndex(action);
            for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
                TouchedWindow& touchedWindow = tempTouchState.windows[i];
            std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]};
            for (TouchedWindow& touchedWindow : tempTouchState.windows) {
                // Ignore drag window for it should just track one pointer.
                if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
                    continue;
                }
                std::bitset<MAX_POINTER_ID + 1> touchingPointers;
                touchingPointers.set(entry.pointerProperties[pointerIndex].id);
                touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
            }
        }
@@ -2646,13 +2650,13 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(

    // Output targets from the touch state.
    for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
        std::bitset<MAX_POINTER_ID + 1> touchingPointers =
        std::vector<PointerProperties> touchingPointers =
                touchedWindow.getTouchingPointers(entry.deviceId);
        if (touchingPointers.none()) {
        if (touchingPointers.empty()) {
            continue;
        }
        addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
                                     touchedWindow.targetFlags, touchingPointers,
                                     touchedWindow.targetFlags, getPointerIds(touchingPointers),
                                     touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
    }

@@ -5481,7 +5485,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<

        // Erase old window.
        ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
        std::bitset<MAX_POINTER_ID + 1> pointerIds = touchedWindow->getTouchingPointers(deviceId);
        std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId);
        sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
        state->removeWindowByToken(fromToken);

@@ -5493,17 +5497,17 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<
            newTargetFlags |= InputTarget::Flags::FOREGROUND;
        }
        state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
                                 deviceId, pointerIds, downTimeInTarget);
                                 deviceId, pointers, downTimeInTarget);

        // Store the dragging window.
        if (isDragDrop) {
            if (pointerIds.count() != 1) {
            if (pointers.size() != 1) {
                ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
                      " pointer on the window.");
                return false;
            }
            // Track the pointer id for drag window and generate the drag state.
            const size_t id = firstMarkedBit(pointerIds);
            const size_t id = pointers.begin()->id;
            mDragState = std::make_unique<DragState>(toWindowHandle, id);
        }

@@ -5520,7 +5524,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<

            // Check if the wallpaper window should deliver the corresponding event.
            transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
                                   *state, deviceId, pointerIds);
                                   *state, deviceId, pointers);
        }
    } // release lock

@@ -5997,8 +6001,10 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
                                   "input channel stole pointer stream");
        options.deviceId = deviceId;
        options.displayId = displayId;
        std::bitset<MAX_POINTER_ID + 1> pointerIds = window.getTouchingPointers(deviceId);
        std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId);
        std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
        options.pointerIds = pointerIds;

        std::string canceledWindows;
        for (const TouchedWindow& w : state.windows) {
            const std::shared_ptr<InputChannel> channel =
@@ -6794,10 +6800,10 @@ void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanosecon
void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
                                         const sp<WindowInfoHandle>& oldWindowHandle,
                                         const sp<WindowInfoHandle>& newWindowHandle,
                                         TouchState& state, int32_t deviceId, int32_t pointerId,
                                         TouchState& state, int32_t deviceId,
                                         const PointerProperties& pointerProperties,
                                         std::vector<InputTarget>& targets) const {
    std::bitset<MAX_POINTER_ID + 1> pointerIds;
    pointerIds.set(pointerId);
    std::vector<PointerProperties> pointers{pointerProperties};
    const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
            gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
    const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
@@ -6814,16 +6820,16 @@ void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFl
    if (oldWallpaper != nullptr) {
        const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
        addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
                                     oldTouchedWindow.targetFlags, pointerIds,
                                     oldTouchedWindow.targetFlags, getPointerIds(pointers),
                                     oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
        state.removeTouchingPointerFromWindow(deviceId, pointerId, oldWallpaper);
        state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper);
    }

    if (newWallpaper != nullptr) {
        state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
                                InputTarget::Flags::WINDOW_IS_OBSCURED |
                                        InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
                                deviceId, pointerIds);
                                deviceId, pointers);
    }
}

@@ -6832,7 +6838,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT
                                             const sp<WindowInfoHandle> fromWindowHandle,
                                             const sp<WindowInfoHandle> toWindowHandle,
                                             TouchState& state, int32_t deviceId,
                                             std::bitset<MAX_POINTER_ID + 1> pointerIds) {
                                             const std::vector<PointerProperties>& pointers) {
    const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
            fromWindowHandle->getInfo()->inputConfig.test(
                    gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
@@ -6861,7 +6867,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT
        wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
                InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
        state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
                                deviceId, pointerIds, downTimeInTarget);
                                deviceId, pointers, downTimeInTarget);
        std::shared_ptr<Connection> wallpaperConnection =
                getConnectionLocked(newWallpaper->getToken());
        if (wallpaperConnection != nullptr) {
+3 −2
Original line number Diff line number Diff line
@@ -690,14 +690,15 @@ private:
    void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
                            const sp<android::gui::WindowInfoHandle>& oldWindowHandle,
                            const sp<android::gui::WindowInfoHandle>& newWindowHandle,
                            TouchState& state, int32_t deviceId, int32_t pointerId,
                            TouchState& state, int32_t deviceId,
                            const PointerProperties& pointerProperties,
                            std::vector<InputTarget>& targets) const REQUIRES(mLock);
    void transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
                                ftl::Flags<InputTarget::Flags> newTargetFlags,
                                const sp<android::gui::WindowInfoHandle> fromWindowHandle,
                                const sp<android::gui::WindowInfoHandle> toWindowHandle,
                                TouchState& state, int32_t deviceId,
                                std::bitset<MAX_POINTER_ID + 1> pointerIds) REQUIRES(mLock);
                                const std::vector<PointerProperties>& pointers) REQUIRES(mLock);

    sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow(
            const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
+7 −7
Original line number Diff line number Diff line
@@ -73,9 +73,9 @@ void TouchState::clearWindowsWithoutPointers() {
void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle,
                                   InputTarget::DispatchMode dispatchMode,
                                   ftl::Flags<InputTarget::Flags> targetFlags, DeviceId deviceId,
                                   std::bitset<MAX_POINTER_ID + 1> touchingPointerIds,
                                   const std::vector<PointerProperties>& touchingPointers,
                                   std::optional<nsecs_t> firstDownTimeInTarget) {
    if (touchingPointerIds.none()) {
    if (touchingPointers.empty()) {
        LOG(FATAL) << __func__ << "No pointers specified for " << windowHandle->getName();
        return;
    }
@@ -91,7 +91,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle,
            // 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.
            touchedWindow.addTouchingPointers(deviceId, touchingPointerIds);
            touchedWindow.addTouchingPointers(deviceId, touchingPointers);
            if (firstDownTimeInTarget) {
                touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget);
            }
@@ -102,7 +102,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle,
    touchedWindow.windowHandle = windowHandle;
    touchedWindow.dispatchMode = dispatchMode;
    touchedWindow.targetFlags = targetFlags;
    touchedWindow.addTouchingPointers(deviceId, touchingPointerIds);
    touchedWindow.addTouchingPointers(deviceId, touchingPointers);
    if (firstDownTimeInTarget) {
        touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget);
    }
@@ -110,17 +110,17 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle,
}

void TouchState::addHoveringPointerToWindow(const sp<WindowInfoHandle>& windowHandle,
                                            DeviceId deviceId, int32_t hoveringPointerId) {
                                            DeviceId deviceId, const PointerProperties& pointer) {
    for (TouchedWindow& touchedWindow : windows) {
        if (touchedWindow.windowHandle == windowHandle) {
            touchedWindow.addHoveringPointer(deviceId, hoveringPointerId);
            touchedWindow.addHoveringPointer(deviceId, pointer);
            return;
        }
    }

    TouchedWindow touchedWindow;
    touchedWindow.windowHandle = windowHandle;
    touchedWindow.addHoveringPointer(deviceId, hoveringPointerId);
    touchedWindow.addHoveringPointer(deviceId, pointer);
    windows.push_back(touchedWindow);
}

Loading