diff options
8 files changed, 53 insertions, 12 deletions
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index dbacca5def51..9bf43a390d70 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -162,6 +162,8 @@ interface IWindowSession { * @param flags See {@code View#startDragAndDrop} * @param surface Surface containing drag shadow image * @param touchSource See {@code InputDevice#getSource()} + * @param touchDeviceId device ID of last touch event + * @param pointerId pointer ID of last touch event * @param touchX X coordinate of last touch point * @param touchY Y coordinate of last touch point * @param thumbCenterX X coordinate for the position within the shadow image that should be @@ -171,9 +173,9 @@ interface IWindowSession { * @param data Data transferred by drag and drop * @return Token of drag operation which will be passed to cancelDragAndDrop. */ - @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) IBinder performDrag(IWindow window, int flags, in SurfaceControl surface, int touchSource, - float touchX, float touchY, float thumbCenterX, float thumbCenterY, in ClipData data); + int touchDeviceId, int touchPointerId, float touchX, float touchY, float thumbCenterX, + float thumbCenterY, in ClipData data); /** * Drops the content of the current drag operation for accessibility diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 75f8eba01fa2..bb5ee0359b6b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -28340,6 +28340,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, IBinder token = mAttachInfo.mSession.performDrag( mAttachInfo.mWindow, flags, null, mAttachInfo.mViewRootImpl.getLastTouchSource(), + mAttachInfo.mViewRootImpl.getLastTouchDeviceId(), + mAttachInfo.mViewRootImpl.getLastTouchPointerId(), 0f, 0f, 0f, 0f, data); if (ViewDebug.DEBUG_DRAG) { Log.d(VIEW_LOG_TAG, "startDragAndDrop via a11y action returned " + token); @@ -28414,7 +28416,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } token = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, flags, surfaceControl, - root.getLastTouchSource(), lastTouchPoint.x, lastTouchPoint.y, + root.getLastTouchSource(), root.getLastTouchDeviceId(), + root.getLastTouchPointerId(), lastTouchPoint.x, lastTouchPoint.y, shadowTouchPoint.x, shadowTouchPoint.y, data); if (ViewDebug.DEBUG_DRAG) { Log.d(VIEW_LOG_TAG, "performDrag returned " + token); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 588a41d56086..35ef54bf9007 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -808,6 +808,8 @@ public final class ViewRootImpl implements ViewParent, final PointF mDragPoint = new PointF(); final PointF mLastTouchPoint = new PointF(); int mLastTouchSource; + int mLastTouchDeviceId = KeyCharacterMap.VIRTUAL_KEYBOARD; + int mLastTouchPointerId; /** Tracks last {@link MotionEvent#getToolType(int)} with {@link MotionEvent#ACTION_UP}. **/ private int mLastClickToolType; @@ -7098,6 +7100,8 @@ public final class ViewRootImpl implements ViewParent, mLastTouchPoint.x = event.getRawX(); mLastTouchPoint.y = event.getRawY(); mLastTouchSource = event.getSource(); + mLastTouchDeviceId = event.getDeviceId(); + mLastTouchPointerId = event.getPointerId(0); // Register last ACTION_UP. This will be propagated to IME. if (event.getActionMasked() == MotionEvent.ACTION_UP) { @@ -8509,6 +8513,14 @@ public final class ViewRootImpl implements ViewParent, return mLastTouchSource; } + public int getLastTouchDeviceId() { + return mLastTouchDeviceId; + } + + public int getLastTouchPointerId() { + return mLastTouchPointerId; + } + /** * Used by InputMethodManager. * @hide diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index d817e6f51f55..603f7393237d 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -488,8 +488,9 @@ public class WindowlessWindowManager implements IWindowSession { @Override public android.os.IBinder performDrag(android.view.IWindow window, int flags, - android.view.SurfaceControl surface, int touchSource, float touchX, float touchY, - float thumbCenterX, float thumbCenterY, android.content.ClipData data) { + android.view.SurfaceControl surface, int touchSource, int touchDeviceId, + int touchPointerId, float touchX, float touchY, float thumbCenterX, float thumbCenterY, + android.content.ClipData data) { return null; } diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java index 4a3d0c142e1d..32d60c5f52e6 100644 --- a/services/core/java/com/android/server/wm/DragDropController.java +++ b/services/core/java/com/android/server/wm/DragDropController.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static com.android.input.flags.Flags.enablePointerChoreographer; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -23,6 +24,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.content.ClipData; import android.content.Context; +import android.hardware.input.InputManagerGlobal; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -31,6 +33,8 @@ import android.os.Message; import android.util.Slog; import android.view.Display; import android.view.IWindow; +import android.view.InputDevice; +import android.view.PointerIcon; import android.view.SurfaceControl; import android.view.View; import android.view.accessibility.AccessibilityManager; @@ -97,8 +101,8 @@ class DragDropController { } IBinder performDrag(int callerPid, int callerUid, IWindow window, int flags, - SurfaceControl surface, int touchSource, float touchX, float touchY, - float thumbCenterX, float thumbCenterY, ClipData data) { + SurfaceControl surface, int touchSource, int touchDeviceId, int touchPointerId, + float touchX, float touchY, float thumbCenterX, float thumbCenterY, ClipData data) { if (DEBUG_DRAG) { Slog.d(TAG_WM, "perform drag: win=" + window + " surface=" + surface + " flags=" + Integer.toHexString(flags) + " data=" + data + " touch(" + touchX + "," @@ -208,7 +212,17 @@ class DragDropController { final SurfaceControl surfaceControl = mDragState.mSurfaceControl; mDragState.broadcastDragStartedLocked(touchX, touchY); - mDragState.overridePointerIconLocked(touchSource); + if (enablePointerChoreographer()) { + if ((touchSource & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) { + InputManagerGlobal.getInstance().setPointerIcon( + PointerIcon.getSystemIcon( + mService.mContext, PointerIcon.TYPE_GRABBING), + mDragState.mDisplayContent.getDisplayId(), touchDeviceId, + touchPointerId, mDragState.getInputToken()); + } + } else { + mDragState.overridePointerIconLocked(touchSource); + } // remember the thumb offsets for later mDragState.mThumbOffsetX = thumbCenterX; mDragState.mThumbOffsetY = thumbCenterY; diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index a888f8467b3a..adbe3bc1d6b3 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -416,6 +416,13 @@ class DragState { return mInputInterceptor == null ? null : mInputInterceptor.mDragWindowHandle; } + IBinder getInputToken() { + if (mInputInterceptor == null || mInputInterceptor.mClientChannel == null) { + return null; + } + return mInputInterceptor.mClientChannel.getToken(); + } + /** * @param display The Display that the window being dragged is on. */ diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 56f9aa4c6361..57939bc4f348 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -340,7 +340,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { @Override public IBinder performDrag(IWindow window, int flags, SurfaceControl surface, int touchSource, - float touchX, float touchY, float thumbCenterX, float thumbCenterY, ClipData data) { + int touchDeviceId, int touchPointerId, float touchX, float touchY, float thumbCenterX, + float thumbCenterY, ClipData data) { final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); // Validate and resolve ClipDescription data before clearing the calling identity @@ -349,7 +350,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { final long ident = Binder.clearCallingIdentity(); try { return mDragDropController.performDrag(mPid, mUid, window, flags, surface, touchSource, - touchX, touchY, thumbCenterX, thumbCenterY, data); + touchDeviceId, touchPointerId, touchX, touchY, thumbCenterX, thumbCenterY, + data); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java index 50fe0425fe9c..1fb7cd8e6e1c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -553,7 +553,7 @@ public class DragDropControllerTests extends WindowTestsBase { assertTrue(mWm.mInputManager.transferTouchFocus(new InputChannel(), new InputChannel(), true /* isDragDrop */)); mToken = mTarget.performDrag(TEST_PID, 0, mWindow.mClient, - flag, surface, 0, 0, 0, 0, 0, data); + flag, surface, 0, 0, 0, 0, 0, 0, 0, data); assertNotNull(mToken); r.run(); @@ -575,7 +575,7 @@ public class DragDropControllerTests extends WindowTestsBase { private void startA11yDrag(int flags, ClipData data, Runnable r) { mToken = mTarget.performDrag(0, 0, mWindow.mClient, - flags | View.DRAG_FLAG_ACCESSIBILITY_ACTION, null, 0, 0, 0, 0, 0, data); + flags | View.DRAG_FLAG_ACCESSIBILITY_ACTION, null, 0, 0, 0, 0, 0, 0, 0, data); assertNotNull(mToken); r.run(); } |