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

Commit 692bbdb3 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Get mouse cursor position from PointerController instead of WM

PointerController is the source of truth of the mouse cursor position.
When the VirtualDevice APIs queried the cursor position, we were
previously getting the position from WM. WM's values only update once
system_server's global monitor has processed the input event, which
leads us into a race condition.

Remove the race consition by querying the mouse cursor position directly
from PointerController.

Bug: 266687189
Test: atest VirtualMouseTest
Change-Id: Id0e0e20a0d547f969d3a27d43fdfdca34d0fa7c0
parent 07937a00
Loading
Loading
Loading
Loading
+27 −12
Original line number Diff line number Diff line
@@ -262,6 +262,13 @@ void PointerController::reloadPointerResources() {
}

void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
    struct PointerDisplayChangeArgs {
        int32_t displayId;
        float x, y;
    };
    std::optional<PointerDisplayChangeArgs> pointerDisplayChanged;

    { // acquire lock
        std::scoped_lock lock(getLock());

        bool getAdditionalMouseResources = false;
@@ -273,8 +280,16 @@ void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
        if (viewport.displayId != mLocked.pointerDisplayId) {
            float xPos, yPos;
            mCursorController.getPosition(&xPos, &yPos);
        mContext.getPolicy()->onPointerDisplayIdChanged(viewport.displayId, xPos, yPos);
            mLocked.pointerDisplayId = viewport.displayId;
            pointerDisplayChanged = {viewport.displayId, xPos, yPos};
        }
    } // release lock

    if (pointerDisplayChanged) {
        // Notify the policy without holding the pointer controller lock.
        mContext.getPolicy()->onPointerDisplayIdChanged(pointerDisplayChanged->displayId,
                                                        pointerDisplayChanged->x,
                                                        pointerDisplayChanged->y);
    }
}

+5 −1
Original line number Diff line number Diff line
@@ -96,7 +96,11 @@ public abstract class InputManagerInternal {
     */
    public abstract int getVirtualMousePointerDisplayId();

    /** Gets the current position of the mouse cursor. */
    /**
     * Gets the current position of the mouse cursor.
     *
     * Returns NaN-s as the coordinates if the cursor is not available.
     */
    public abstract PointF getCursorPosition();

    /**
+5 −4
Original line number Diff line number Diff line
@@ -2863,9 +2863,6 @@ public class InputManagerService extends IInputManager.Stub

        int getPointerDisplayId();

        /** Gets the x and y coordinates of the cursor's current position. */
        PointF getCursorPosition();

        /**
         * Notifies window manager that a {@link android.view.MotionEvent#ACTION_DOWN} pointer event
         * occurred on a window that did not have focus.
@@ -3189,7 +3186,11 @@ public class InputManagerService extends IInputManager.Stub

        @Override
        public PointF getCursorPosition() {
            return mWindowManagerCallbacks.getCursorPosition();
            final float[] p = mNative.getMouseCursorPosition();
            if (p == null || p.length != 2) {
                throw new IllegalStateException("Failed to get mouse cursor position");
            }
            return new PointF(p[0], p[1]);
        }

        @Override
+13 −0
Original line number Diff line number Diff line
@@ -224,6 +224,16 @@ interface NativeInputManagerService {
    /** Set whether stylus button reporting through motion events should be enabled. */
    void setStylusButtonMotionEventsEnabled(boolean enabled);

    /**
     * Get the current position of the mouse cursor.
     *
     * If the mouse cursor is not currently shown, the coordinate values will be NaN-s.
     *
     * NOTE: This will grab the PointerController's lock, so we must be careful about calling this
     * from the InputReader or Display threads, which may result in a deadlock.
     */
    float[] getMouseCursorPosition();

    /** The native implementation of InputManagerService methods. */
    class NativeImpl implements NativeInputManagerService {
        /** Pointer to native input manager service object, used by native code. */
@@ -465,5 +475,8 @@ interface NativeInputManagerService {

        @Override
        public native void setStylusButtonMotionEventsEnabled(boolean enabled);

        @Override
        public native float[] getMouseCursorPosition();
    }
}
+0 −6
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static com.android.server.wm.WindowManagerService.H.ON_POINTER_DOWN_OUTSI

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.PointF;
import android.os.Debug;
import android.os.IBinder;
import android.util.Slog;
@@ -220,11 +219,6 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
        }
    }

    @Override
    public PointF getCursorPosition() {
        return mService.getLatestMousePosition();
    }

    @Override
    public void onPointerDownOutsideFocus(IBinder touchedToken) {
        mService.mH.obtainMessage(ON_POINTER_DOWN_OUTSIDE_FOCUS, touchedToken).sendToTarget();
Loading