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

Commit b5e316c3 authored by chaviw's avatar chaviw
Browse files

Fix drag and drop (2/3)

Drag and drop requires the touch focus to be transferred from one window to
another. Since InputWindows are now sent through SurfaceFlinger, there's a
possibility that the request to transfer touch focus will happen before the
input window is set in InputFlinger. This will cause the transfer focus window
to fail since the window to transfer focus to doesn't exist yet in
InputFlinger.

This change passes the window that the touch focus should be transferred from
through SurfaceFlinger so when the touch is transferred, InputFlinger is
guaranteed to know about the new window.

Change-Id: I64ac64c060f19ebbb5c4f0efa28bce3164899349
Fixes: 120463595
Fixes: 120493124
Test: Drag and drop view in app
Test: Drag and drop free form
Test: CrossAppDragAndDropTests
parent 59f532ef
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ class DragState {
     * {@code true} when {@link #closeLocked()} is called.
     */
    private boolean mIsClosing;
    IBinder mTransferTouchFromToken;

    DragState(WindowManagerService service, DragDropController controller, IBinder token,
            SurfaceControl surface, int flags, IBinder localWin) {
@@ -177,6 +178,8 @@ class DragState {

        mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
        t.setWindowCrop(mInputSurface, mTmpClipRect);
        t.transferTouchFocus(mTransferTouchFromToken, h.token);
        mTransferTouchFromToken = null;
    }

    /**
+6 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.app.IActivityTaskManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Slog;
@@ -50,6 +51,7 @@ class TaskPositioningController {
    private @Nullable TaskPositioner mTaskPositioner;

    private final Rect mTmpClipRect = new Rect();
    private IBinder mTransferTouchFromToken;

    boolean isPositioningLocked() {
        return mTaskPositioner != null;
@@ -102,6 +104,8 @@ class TaskPositioningController {

        mTmpClipRect.set(0, 0, p.x, p.y);
        t.setWindowCrop(mInputSurface, mTmpClipRect);
        t.transferTouchFocus(mTransferTouchFromToken, h.token);
        mTransferTouchFromToken = null;
    }

    boolean startMovingTask(IWindow window, float startX, float startY) {
@@ -170,7 +174,6 @@ class TaskPositioningController {
        mPositioningDisplay = displayContent;

        mTaskPositioner = TaskPositioner.create(mService);
        mTaskPositioner.register(displayContent);

        // We need to grab the touch focus so that the touch events during the
        // resizing/scrolling are not sent to the app. 'win' is the main window
@@ -181,12 +184,8 @@ class TaskPositioningController {
                && displayContent.mCurrentFocus.mAppToken == win.mAppToken) {
            transferFocusFromWin = displayContent.mCurrentFocus;
        }
        if (!mInputManager.transferTouchFocus(
                transferFocusFromWin.mInputChannel, mTaskPositioner.mServerChannel)) {
            Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus");
            cleanUpTaskPositioner();
            return false;
        }
        mTransferTouchFromToken = transferFocusFromWin.mInputChannel.getToken();
        mTaskPositioner.register(displayContent);

        mTaskPositioner.startDrag(win, resize, preserveOrientation, startX, startY);
        return true;
+2 −1
Original line number Diff line number Diff line
@@ -158,8 +158,9 @@ public abstract class WindowManagerInternal {
        default boolean registerInputChannel(
                DragState state, Display display, InputManagerService service,
                InputChannel source) {
            state.mTransferTouchFromToken = source.getToken();
            state.register(display);
            return service.transferTouchFocus(source, state.getInputChannel());
            return true;
        }

        /**