diff options
author | 2025-01-09 18:17:24 -0800 | |
---|---|---|
committer | 2025-01-09 18:17:24 -0800 | |
commit | a5bd2ed77cc68383896e3634d01b81b6c2eb5f07 (patch) | |
tree | dfe1f993e690663a1b8756a4229d44d8036666d3 | |
parent | 7e678dcb0e459f37810a9d009aa9bfa6c4e1ac1a (diff) | |
parent | 8214656176a12d309d40b961ca7e5f4106c8fb1d (diff) |
Merge "[DnD] Pass displayId to DragEvent" into main
7 files changed, 53 insertions, 25 deletions
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java index b65e3ebc3871..77af312eac4a 100644 --- a/core/java/android/view/DragEvent.java +++ b/core/java/android/view/DragEvent.java @@ -157,6 +157,11 @@ public class DragEvent implements Parcelable { private float mOffsetY; /** + * The id of the display where the `mX` and `mY` of this event belongs to. + */ + private int mDisplayId; + + /** * The View#DRAG_FLAG_* flags used to start the current drag, only provided if the target window * has the {@link WindowManager.LayoutParams#PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP} flag * and is only sent with {@link #ACTION_DRAG_STARTED} and {@link #ACTION_DROP}. @@ -297,14 +302,15 @@ public class DragEvent implements Parcelable { private DragEvent() { } - private void init(int action, float x, float y, float offsetX, float offsetY, int flags, - ClipDescription description, ClipData data, SurfaceControl dragSurface, + private void init(int action, float x, float y, float offsetX, float offsetY, int displayId, + int flags, ClipDescription description, ClipData data, SurfaceControl dragSurface, IDragAndDropPermissions dragAndDropPermissions, Object localState, boolean result) { mAction = action; mX = x; mY = y; mOffsetX = offsetX; mOffsetY = offsetY; + mDisplayId = displayId; mFlags = flags; mClipDescription = description; mClipData = data; @@ -315,20 +321,20 @@ public class DragEvent implements Parcelable { } static DragEvent obtain() { - return DragEvent.obtain(0, 0f, 0f, 0f, 0f, 0, null, null, null, null, null, false); + return DragEvent.obtain(0, 0f, 0f, 0f, 0f, 0, 0, null, null, null, null, null, false); } /** @hide */ public static DragEvent obtain(int action, float x, float y, float offsetX, float offsetY, - int flags, Object localState, ClipDescription description, ClipData data, + int displayId, int flags, Object localState, ClipDescription description, ClipData data, SurfaceControl dragSurface, IDragAndDropPermissions dragAndDropPermissions, boolean result) { final DragEvent ev; synchronized (gRecyclerLock) { if (gRecyclerTop == null) { ev = new DragEvent(); - ev.init(action, x, y, offsetX, offsetY, flags, description, data, dragSurface, - dragAndDropPermissions, localState, result); + ev.init(action, x, y, offsetX, offsetY, displayId, flags, description, data, + dragSurface, dragAndDropPermissions, localState, result); return ev; } ev = gRecyclerTop; @@ -339,7 +345,7 @@ public class DragEvent implements Parcelable { ev.mRecycled = false; ev.mNext = null; - ev.init(action, x, y, offsetX, offsetY, flags, description, data, dragSurface, + ev.init(action, x, y, offsetX, offsetY, displayId, flags, description, data, dragSurface, dragAndDropPermissions, localState, result); return ev; @@ -349,8 +355,9 @@ public class DragEvent implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static DragEvent obtain(DragEvent source) { return obtain(source.mAction, source.mX, source.mY, source.mOffsetX, source.mOffsetY, - source.mFlags, source.mLocalState, source.mClipDescription, source.mClipData, - source.mDragSurface, source.mDragAndDropPermissions, source.mDragResult); + source.mDisplayId, source.mFlags, source.mLocalState, source.mClipDescription, + source.mClipData, source.mDragSurface, source.mDragAndDropPermissions, + source.mDragResult); } /** @@ -398,6 +405,11 @@ public class DragEvent implements Parcelable { return mOffsetY; } + /** @hide */ + public int getDisplayId() { + return mDisplayId; + } + /** * Returns the {@link android.content.ClipData} object sent to the system as part of the call * to diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index 2cc05b0bc4b0..1c36eaf99afa 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -177,7 +177,7 @@ public abstract class InputEventReceiver { * drag * if true, the window associated with this input channel has just lost drag */ - public void onDragEvent(boolean isExiting, float x, float y) { + public void onDragEvent(boolean isExiting, float x, float y, int displayId) { } /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 8ef0b0eebb8c..36671b901a6b 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -10561,13 +10561,13 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void onDragEvent(boolean isExiting, float x, float y) { + public void onDragEvent(boolean isExiting, float x, float y, int displayId) { // force DRAG_EXITED_EVENT if appropriate DragEvent event = DragEvent.obtain( - isExiting ? DragEvent.ACTION_DRAG_EXITED : DragEvent.ACTION_DRAG_LOCATION, - x, y, 0 /* offsetX */, 0 /* offsetY */, 0 /* flags */, null/* localState */, - null/* description */, null /* data */, null /* dragSurface */, - null /* dragAndDropPermissions */, false /* result */); + isExiting ? DragEvent.ACTION_DRAG_EXITED : DragEvent.ACTION_DRAG_LOCATION, x, y, + 0 /* offsetX */, 0 /* offsetY */, displayId, 0 /* flags */, + null/* localState */, null/* description */, null /* data */, + null /* dragSurface */, null /* dragAndDropPermissions */, false /* result */); dispatchDragEvent(event); } diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index 3a1e8835c8db..6272fb1947c1 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -441,7 +441,8 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, } env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onDragEvent, jboolean(dragEvent->isExiting()), dragEvent->getX(), - dragEvent->getY()); + dragEvent->getY(), + static_cast<jint>(dragEvent->getDisplayId().val())); finishInputEvent(seq, /*handled=*/true); continue; } @@ -643,7 +644,7 @@ int register_android_view_InputEventReceiver(JNIEnv* env) { GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onPointerCaptureEvent", "(Z)V"); gInputEventReceiverClassInfo.onDragEvent = - GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onDragEvent", "(ZFF)V"); + GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onDragEvent", "(ZFFI)V"); gInputEventReceiverClassInfo.onTouchModeChanged = GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onTouchModeChanged", "(Z)V"); gInputEventReceiverClassInfo.onBatchedInputEventPending = diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/GlobalDragListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/GlobalDragListenerTest.kt index d410151b4602..5389c94bc15d 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/GlobalDragListenerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/GlobalDragListenerTest.kt @@ -43,7 +43,7 @@ import org.mockito.kotlin.verify */ @SmallTest @RunWith(AndroidJUnit4::class) -class UnhandledDragControllerTest : ShellTestCase() { +class GlobalDragListenerTest : ShellTestCase() { private val mIWindowManager = mock<IWindowManager>() private val mMainExecutor = mock<ShellExecutor>() @@ -74,7 +74,7 @@ class UnhandledDragControllerTest : ShellTestCase() { @Test fun onUnhandledDrop_noListener_expectNotifyUnhandled() { // Simulate an unhandled drop - val dropEvent = DragEvent.obtain(ACTION_DROP, 0f, 0f, 0f, 0f, 0, null, null, null, + val dropEvent = DragEvent.obtain(ACTION_DROP, 0f, 0f, 0f, 0f, 0, 0, null, null, null, null, null, false) val wmCallback = mock<IUnhandledDragCallback>() mController.onUnhandledDrop(dropEvent, wmCallback) @@ -98,7 +98,7 @@ class UnhandledDragControllerTest : ShellTestCase() { // Simulate an unhandled drop val dragSurface = mock<SurfaceControl>() - val dropEvent = DragEvent.obtain(ACTION_DROP, 0f, 0f, 0f, 0f, 0, null, null, null, + val dropEvent = DragEvent.obtain(ACTION_DROP, 0f, 0f, 0f, 0f, 0, 0, null, null, null, dragSurface, null, false) val wmCallback = mock<IUnhandledDragCallback>() mController.onUnhandledDrop(dropEvent, wmCallback) diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 4a4e2461c2ca..d48b9b4a5d10 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -253,7 +253,8 @@ class DragState { } } DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED, inWindowX, - inWindowY, mThumbOffsetX, mThumbOffsetY, mFlags, null, null, null, + inWindowY, mThumbOffsetX, mThumbOffsetY, + mCurrentDisplayContent.getDisplayId(), mFlags, null, null, null, dragSurface, null, mDragResult); try { if (DEBUG_DRAG) Slog.d(TAG_WM, "Sending DRAG_ENDED to " + ws); @@ -791,10 +792,10 @@ class DragState { ClipData data, boolean includeDragSurface, boolean includeDragFlags, IDragAndDropPermissions dragAndDropPermissions) { return DragEvent.obtain(action, x, y, mThumbOffsetX, mThumbOffsetY, - includeDragFlags ? mFlags : 0, + mCurrentDisplayContent.getDisplayId(), includeDragFlags ? mFlags : 0, null /* localState */, description, data, - includeDragSurface ? mSurfaceControl : null, - dragAndDropPermissions, false /* result */); + includeDragSurface ? mSurfaceControl : null, dragAndDropPermissions, + false /* result */); } private ValueAnimator createReturnAnimationLocked() { 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 63c745ea6cd0..dc16de1aab5e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -415,8 +415,14 @@ public class DragDropControllerTests extends WindowTestsBase { assertEquals(ACTION_DROP, dropEvent.getAction()); assertEquals(dropCoordsPx, dropEvent.getX(), 0.0 /* delta */); assertEquals(dropCoordsPx, dropEvent.getY(), 0.0 /* delta */); + assertEquals(window2.getDisplayId(), dropEvent.getDisplayId()); mTarget.reportDropResult(iwindow2, true); + // Verify both windows received ACTION_DRAG_ENDED event. + assertEquals(ACTION_DRAG_ENDED, last(dragEvents).getAction()); + assertEquals(window2.getDisplayId(), last(dragEvents).getDisplayId()); + assertEquals(ACTION_DRAG_ENDED, last(dragEvents2).getAction()); + assertEquals(window2.getDisplayId(), last(dragEvents2).getDisplayId()); } finally { mTarget.mDeferDragStateClosed = false; } @@ -458,10 +464,12 @@ public class DragDropControllerTests extends WindowTestsBase { try { mTarget.mDeferDragStateClosed = true; + mTarget.handleMotionEvent(true, testDisplay.getDisplayId(), dropCoordsPx, + dropCoordsPx); // x, y is window-local coordinate. mTarget.reportDropWindow(window2.mInputChannelToken, dropCoordsPx, dropCoordsPx); - mTarget.handleMotionEvent(false, window2.getDisplayId(), dropCoordsPx, + mTarget.handleMotionEvent(false, testDisplay.getDisplayId(), dropCoordsPx, dropCoordsPx); mToken = window2.mClient.asBinder(); // Verify only window2 received the DROP event and coords are sent as-is @@ -471,8 +479,14 @@ public class DragDropControllerTests extends WindowTestsBase { assertEquals(ACTION_DROP, dropEvent.getAction()); assertEquals(dropCoordsPx, dropEvent.getX(), 0.0 /* delta */); assertEquals(dropCoordsPx, dropEvent.getY(), 0.0 /* delta */); + assertEquals(testDisplay.getDisplayId(), dropEvent.getDisplayId()); mTarget.reportDropResult(iwindow2, true); + // Verify both windows received ACTION_DRAG_ENDED event. + assertEquals(ACTION_DRAG_ENDED, last(dragEvents).getAction()); + assertEquals(testDisplay.getDisplayId(), last(dragEvents).getDisplayId()); + assertEquals(ACTION_DRAG_ENDED, last(dragEvents2).getAction()); + assertEquals(testDisplay.getDisplayId(), last(dragEvents2).getDisplayId()); } finally { mTarget.mDeferDragStateClosed = false; } |