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

Commit 7aeb642c authored by Winson Chung's avatar Winson Chung
Browse files

Fix regression in app drag target windows

- Only disallow non-local, non-global intercepting windows from
  receiving drags.  The window which originated the drag still might
  want to receive drag events to kick off animations/etc.

Bug: 178690347
Test: atest DragDropControllerTests
Change-Id: I856d179993e687ba343e35d87bd1f3c613e637db
parent b9034aba
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -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;
            }
        }
+13 −7
Original line number Diff line number Diff line
@@ -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<DragEvent> dragEvents = new ArrayList<>();
        iwindow.setDragEventJournal(dragEvents);
        TestIWindow localIWindow = (TestIWindow) mWindow.mClient;
        final ArrayList<DragEvent> localWindowDragEvents = new ArrayList<>();
        localIWindow.setDragEventJournal(localWindowDragEvents);
        TestIWindow nonLocalIWindow = (TestIWindow) nonLocalWindow.mClient;
        final ArrayList<DragEvent> nonLocalWindowDragEvents = new ArrayList<>();
        nonLocalIWindow.setDragEventJournal(nonLocalWindowDragEvents);
        TestIWindow globalInterceptIWindow = (TestIWindow) globalInterceptWindow.mClient;
        final ArrayList<DragEvent> 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);