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

Commit 25040239 authored by Hiroki Sato's avatar Hiroki Sato
Browse files

Use input token in PointerCaptureRequest

Instead of sending boolean to indicate the capture state,
InputDispatcher now sends an input window token that requests a
pointer capture, or nullptr otherwise.

This is useful for some InputReader implementations.
Also, this token can be used to verify if a pointer capture changed
event from a reader is valid.

Bug: 259346762
Bug: 301628662
Test: inputflinger_tests
Test: android.view.cts.PointerCaptureTest WindowFocusTests#testPointerCapture
Change-Id: Ie8343db6744dc2080f7f1dcff5a630be5c87fa3e
parent 48d4be6d
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -1192,15 +1192,17 @@ public:
 */
struct PointerCaptureRequest {
public:
    inline PointerCaptureRequest() : enable(false), seq(0) {}
    inline PointerCaptureRequest(bool enable, uint32_t seq) : enable(enable), seq(seq) {}
    inline PointerCaptureRequest() : window(), seq(0) {}
    inline PointerCaptureRequest(sp<IBinder> window, uint32_t seq) : window(window), seq(seq) {}
    inline bool operator==(const PointerCaptureRequest& other) const {
        return enable == other.enable && seq == other.seq;
        return window == other.window && seq == other.seq;
    }
    explicit inline operator bool() const { return enable; }
    inline bool isEnable() const { return window != nullptr; }

    // True iff this is a request to enable Pointer Capture.
    bool enable;
    // The requesting window.
    // If the request is to enable the capture, this is the input token of the window that requested
    // pointer capture. Otherwise, this is nullptr.
    sp<IBinder> window;

    // The sequence number for the request.
    uint32_t seq;
+1 −1
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args)

void PointerChoreographer::notifyPointerCaptureChanged(
        const NotifyPointerCaptureChangedArgs& args) {
    if (args.request.enable) {
    if (args.request.isEnable()) {
        std::scoped_lock _l(mLock);
        for (const auto& [_, mousePointerController] : mMousePointersByDisplay) {
            mousePointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ PointerCaptureChangedEntry::PointerCaptureChangedEntry(int32_t id, nsecs_t event

std::string PointerCaptureChangedEntry::getDescription() const {
    return StringPrintf("PointerCaptureChangedEvent(pointerCaptureEnabled=%s)",
                        pointerCaptureRequest.enable ? "true" : "false");
                        pointerCaptureRequest.isEnable() ? "true" : "false");
}

// --- DragEntry ---
+21 −18
Original line number Diff line number Diff line
@@ -1715,7 +1715,7 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked(
    const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
    sp<IBinder> token;

    if (entry->pointerCaptureRequest.enable) {
    if (entry->pointerCaptureRequest.isEnable()) {
        // Enable Pointer Capture.
        if (haveWindowWithPointerCapture &&
            (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
@@ -1724,7 +1724,7 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked(
            ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
            return;
        }
        if (!mCurrentPointerCaptureRequest.enable) {
        if (!mCurrentPointerCaptureRequest.isEnable()) {
            // This can happen if a window requests capture and immediately releases capture.
            ALOGW("No window requested Pointer Capture.");
            dropReason = DropReason::NO_POINTER_CAPTURE;
@@ -1737,6 +1737,8 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked(

        token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
        LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
        LOG_ALWAYS_FATAL_IF(token != entry->pointerCaptureRequest.window,
                            "Unexpected requested window for Pointer Capture.");
        mWindowTokenWithPointerCapture = token;
    } else {
        // Disable Pointer Capture.
@@ -1756,8 +1758,8 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked(
        }
        token = mWindowTokenWithPointerCapture;
        mWindowTokenWithPointerCapture = nullptr;
        if (mCurrentPointerCaptureRequest.enable) {
            setPointerCaptureLocked(false);
        if (mCurrentPointerCaptureRequest.isEnable()) {
            setPointerCaptureLocked(nullptr);
        }
    }

@@ -1765,8 +1767,8 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked(
    if (connection == nullptr) {
        // Window has gone away, clean up Pointer Capture state.
        mWindowTokenWithPointerCapture = nullptr;
        if (mCurrentPointerCaptureRequest.enable) {
            setPointerCaptureLocked(false);
        if (mCurrentPointerCaptureRequest.isEnable()) {
            setPointerCaptureLocked(nullptr);
        }
        return;
    }
@@ -3832,9 +3834,10 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
            case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
                const auto& captureEntry =
                        static_cast<const PointerCaptureChangedEntry&>(eventEntry);
                status = connection->inputPublisher
                status =
                        connection->inputPublisher
                                .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
                                                      captureEntry.pointerCaptureRequest.enable);
                                                     captureEntry.pointerCaptureRequest.isEnable());
                break;
            }

@@ -4713,7 +4716,7 @@ void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
    if (debugInboundEventDetails()) {
        ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
              args.request.enable ? "true" : "false");
              args.request.isEnable() ? "true" : "false");
    }

    bool needWake = false;
@@ -5784,7 +5787,7 @@ std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
    std::string dump;

    dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
                         toString(mCurrentPointerCaptureRequest.enable));
                         toString(mCurrentPointerCaptureRequest.isEnable()));

    std::string windowName = "None";
    if (mWindowTokenWithPointerCapture) {
@@ -6203,7 +6206,7 @@ void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool
            return;
        }

        if (enabled == mCurrentPointerCaptureRequest.enable) {
        if (enabled == mCurrentPointerCaptureRequest.isEnable()) {
            ALOGW("Ignoring request to %s Pointer Capture: "
                  "window has %s requested pointer capture.",
                  enabled ? "enable" : "disable", enabled ? "already" : "not");
@@ -6219,7 +6222,7 @@ void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool
            }
        }

        setPointerCaptureLocked(enabled);
        setPointerCaptureLocked(enabled ? windowToken : nullptr);
    } // release lock

    // Wake the thread to process command entries.
@@ -6849,14 +6852,14 @@ void InputDispatcher::onFocusChangedLocked(
}

void InputDispatcher::disablePointerCaptureForcedLocked() {
    if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
    if (!mCurrentPointerCaptureRequest.isEnable() && !mWindowTokenWithPointerCapture) {
        return;
    }

    ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");

    if (mCurrentPointerCaptureRequest.enable) {
        setPointerCaptureLocked(false);
    if (mCurrentPointerCaptureRequest.isEnable()) {
        setPointerCaptureLocked(nullptr);
    }

    if (!mWindowTokenWithPointerCapture) {
@@ -6876,8 +6879,8 @@ void InputDispatcher::disablePointerCaptureForcedLocked() {
    mInboundQueue.push_front(std::move(entry));
}

void InputDispatcher::setPointerCaptureLocked(bool enable) {
    mCurrentPointerCaptureRequest.enable = enable;
void InputDispatcher::setPointerCaptureLocked(const sp<IBinder>& windowToken) {
    mCurrentPointerCaptureRequest.window = windowToken;
    mCurrentPointerCaptureRequest.seq++;
    auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
        scoped_unlock unlock(mLock);
+2 −1
Original line number Diff line number Diff line
@@ -421,7 +421,8 @@ private:
    void disablePointerCaptureForcedLocked() REQUIRES(mLock);

    // Set the Pointer Capture state in the Policy.
    void setPointerCaptureLocked(bool enable) REQUIRES(mLock);
    // The window is not nullptr for requests to enable, otherwise it is nullptr.
    void setPointerCaptureLocked(const sp<IBinder>& window) REQUIRES(mLock);

    // Dispatcher state at time of last ANR.
    std::string mLastAnrState GUARDED_BY(mLock);
Loading