diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 63400362d74d6..c674cb85a79ea 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -497,9 +497,10 @@ class DragState { if (targetWin == null) { return false; } - if (!interceptsGlobalDrag && containsAppExtras) { - // App-drags can only go to windows that can intercept global drag, and not to normal - // app windows + final boolean isLocalWindow = mLocalWin == targetWin.mClient.asBinder(); + if (!isLocalWindow && !interceptsGlobalDrag && containsAppExtras) { + // App-drags can only go to local windows or windows that can intercept global drag, and + // not to other app windows return false; } if (!targetWin.isPotentialDragTarget(interceptsGlobalDrag)) { @@ -507,7 +508,7 @@ class DragState { } if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0 || !targetWindowSupportsGlobalDrag(targetWin)) { // Drag is limited to the current window. - if (mLocalWin != targetWin.mClient.asBinder()) { + if (!isLocalWindow) { return false; } } 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 c47ffcff73d3f..8981ab1a0e8ac 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -239,25 +239,31 @@ public class DragDropControllerTests extends WindowTestsBase { } @Test - public void testInterceptGlobalDragDropIgnoresOtherWindows() { + public void testPrivateInterceptGlobalDragDropIgnoresNonLocalWindows() { + WindowState nonLocalWindow = createDropTargetWindow("App drag test window", 0); WindowState globalInterceptWindow = createDropTargetWindow("Global drag test window", 0); globalInterceptWindow.mAttrs.privateFlags |= PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; // Necessary for now since DragState.sendDragStartedLocked() will recycle drag events // immediately after dispatching, which is a problem when using mockito arguments captor // because it returns and modifies the same drag event - TestIWindow iwindow = (TestIWindow) mWindow.mClient; - final ArrayList dragEvents = new ArrayList<>(); - iwindow.setDragEventJournal(dragEvents); + TestIWindow localIWindow = (TestIWindow) mWindow.mClient; + final ArrayList localWindowDragEvents = new ArrayList<>(); + localIWindow.setDragEventJournal(localWindowDragEvents); + TestIWindow nonLocalIWindow = (TestIWindow) nonLocalWindow.mClient; + final ArrayList nonLocalWindowDragEvents = new ArrayList<>(); + nonLocalIWindow.setDragEventJournal(nonLocalWindowDragEvents); TestIWindow globalInterceptIWindow = (TestIWindow) globalInterceptWindow.mClient; final ArrayList globalInterceptWindowDragEvents = new ArrayList<>(); globalInterceptIWindow.setDragEventJournal(globalInterceptWindowDragEvents); startDrag(View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ, createClipDataForActivity(null, mock(UserHandle.class)), () -> { - // Verify the start-drag event is sent for the intercept window but not the - // other window - assertTrue(dragEvents.isEmpty()); + // Verify the start-drag event is sent for the local and global intercept window + // but not the other window + assertTrue(nonLocalWindowDragEvents.isEmpty()); + assertTrue(localWindowDragEvents.get(0).getAction() + == ACTION_DRAG_STARTED); assertTrue(globalInterceptWindowDragEvents.get(0).getAction() == ACTION_DRAG_STARTED);