From b5e316c3e43aaeca1a83be46eb4fde0be2e7d7d6 Mon Sep 17 00:00:00 2001 From: chaviw Date: Wed, 26 Dec 2018 15:39:15 -0800 Subject: [PATCH] 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 --- .../core/java/com/android/server/wm/DragState.java | 3 +++ .../server/wm/TaskPositioningController.java | 13 ++++++------- .../android/server/wm/WindowManagerInternal.java | 3 ++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 607ee767869f1..786a3064ab4e4 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -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; } /** diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java index e15bf5b9a6f09..916316549f391 100644 --- a/services/core/java/com/android/server/wm/TaskPositioningController.java +++ b/services/core/java/com/android/server/wm/TaskPositioningController.java @@ -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; diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 646fdd960adc0..1691dc0e38065 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -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; } /**