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

Commit 7797e699 authored by Mady Mellor's avatar Mady Mellor Committed by Automerger Merge Worker
Browse files

Merge "Collapse bubbles when drag and drop is initiated" into tm-dev am:...

Merge "Collapse bubbles when drag and drop is initiated" into tm-dev am: ef1cc885 am: 4437048f am: bf3d3a99

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17715693



Change-Id: I0be5cafbabdf811a88a3331bfa744005fa3844e6
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 31f4460d bf3d3a99
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
@@ -214,6 +215,8 @@ public class BubbleController {

    /** One handed mode controller to register transition listener. */
    private Optional<OneHandedController> mOneHandedOptional;
    /** Drag and drop controller to register listener for onDragStarted. */
    private DragAndDropController mDragAndDropController;

    /**
     * Creates an instance of the BubbleController.
@@ -230,6 +233,7 @@ public class BubbleController {
            ShellTaskOrganizer organizer,
            DisplayController displayController,
            Optional<OneHandedController> oneHandedOptional,
            DragAndDropController dragAndDropController,
            ShellExecutor mainExecutor,
            Handler mainHandler,
            TaskViewTransitions taskViewTransitions,
@@ -241,8 +245,8 @@ public class BubbleController {
                new BubbleDataRepository(context, launcherApps, mainExecutor),
                statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
                logger, taskStackListener, organizer, positioner, displayController,
                oneHandedOptional, mainExecutor, mainHandler, taskViewTransitions,
                syncQueue);
                oneHandedOptional, dragAndDropController, mainExecutor, mainHandler,
                taskViewTransitions, syncQueue);
    }

    /**
@@ -264,6 +268,7 @@ public class BubbleController {
            BubblePositioner positioner,
            DisplayController displayController,
            Optional<OneHandedController> oneHandedOptional,
            DragAndDropController dragAndDropController,
            ShellExecutor mainExecutor,
            Handler mainHandler,
            TaskViewTransitions taskViewTransitions,
@@ -293,6 +298,7 @@ public class BubbleController {
        mDisplayController = displayController;
        mTaskViewTransitions = taskViewTransitions;
        mOneHandedOptional = oneHandedOptional;
        mDragAndDropController = dragAndDropController;
        mSyncQueue = syncQueue;
    }

@@ -433,6 +439,7 @@ public class BubbleController {
                });

        mOneHandedOptional.ifPresent(this::registerOneHandedState);
        mDragAndDropController.addListener(this::collapseStack);
    }

    @VisibleForTesting
@@ -884,7 +891,6 @@ public class BubbleController {
        return mBubbleData.isExpanded();
    }

    @VisibleForTesting
    public void collapseStack() {
        mBubbleData.setExpanded(false /* expanded */);
    }
+3 −1
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.freeform.FreeformTaskListener;
import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
@@ -110,6 +111,7 @@ public class WMShellModule {
            ShellTaskOrganizer organizer,
            DisplayController displayController,
            @DynamicOverride Optional<OneHandedController> oneHandedOptional,
            DragAndDropController dragAndDropController,
            @ShellMainThread ShellExecutor mainExecutor,
            @ShellMainThread Handler mainHandler,
            TaskViewTransitions taskViewTransitions,
@@ -118,7 +120,7 @@ public class WMShellModule {
                floatingContentCoordinator, statusBarService, windowManager,
                windowManagerShellWrapper, launcherApps, taskStackListener,
                uiEventLogger, organizer, displayController, oneHandedOptional,
                mainExecutor, mainHandler, taskViewTransitions, syncQueue);
                dragAndDropController, mainExecutor, mainHandler, taskViewTransitions, syncQueue);
    }

    //
+37 −6
Original line number Diff line number Diff line
@@ -35,9 +35,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.ClipDescription;
import android.content.Context;
import android.content.res.Configuration;
@@ -52,17 +49,19 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;

import androidx.annotation.VisibleForTesting;

import com.android.internal.logging.InstanceId;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.protolog.common.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;

import java.util.ArrayList;
import java.util.Optional;

/**
@@ -80,10 +79,19 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
    private SplitScreenController mSplitScreen;
    private ShellExecutor mMainExecutor;
    private DragAndDropImpl mImpl;
    private ArrayList<DragAndDropListener> mListeners = new ArrayList<>();

    private final SparseArray<PerDisplay> mDisplayDropTargets = new SparseArray<>();
    private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();

    /**
     * Listener called during drag events, currently just onDragStarted.
     */
    public interface DragAndDropListener {
        /** Called when a drag has started. */
        void onDragStarted();
    }

    public DragAndDropController(Context context, DisplayController displayController,
            UiEventLogger uiEventLogger, IconProvider iconProvider, ShellExecutor mainExecutor) {
        mContext = context;
@@ -103,6 +111,22 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
        mDisplayController.addDisplayWindowListener(this);
    }

    /** Adds a listener to be notified of drag and drop events. */
    public void addListener(DragAndDropListener listener) {
        mListeners.add(listener);
    }

    /** Removes a drag and drop listener. */
    public void removeListener(DragAndDropListener listener) {
        mListeners.remove(listener);
    }

    private void notifyListeners() {
        for (int i = 0; i < mListeners.size(); i++) {
            mListeners.get(i).onDragStarted();
        }
    }

    @Override
    public void onDisplayAdded(int displayId) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Display added: %d", displayId);
@@ -137,13 +161,19 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
                new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        try {
            wm.addView(rootView, layoutParams);
            mDisplayDropTargets.put(displayId,
                    new PerDisplay(displayId, context, wm, rootView, dragLayout));
            addDisplayDropTarget(displayId, context, wm, rootView, dragLayout);
        } catch (WindowManager.InvalidDisplayException e) {
            Slog.w(TAG, "Unable to add view for display id: " + displayId);
        }
    }

    @VisibleForTesting
    void addDisplayDropTarget(int displayId, Context context, WindowManager wm,
            FrameLayout rootView, DragLayout dragLayout) {
        mDisplayDropTargets.put(displayId,
                new PerDisplay(displayId, context, wm, rootView, dragLayout));
    }

    @Override
    public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Display changed: %d", displayId);
@@ -206,6 +236,7 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
                pd.dragLayout.prepare(mDisplayController.getDisplayLayout(displayId),
                        event.getClipData(), loggerSessionId);
                setDropTargetWindowVisibility(pd, View.VISIBLE);
                notifyListeners();
                break;
            case ACTION_DRAG_ENTERED:
                pd.dragLayout.show();
+61 −0
Original line number Diff line number Diff line
@@ -16,15 +16,28 @@

package com.android.wm.shell.draganddrop;

import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.DragEvent.ACTION_DRAG_STARTED;

import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.view.Display;
import android.view.DragEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -33,6 +46,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.splitscreen.SplitScreenController;

import org.junit.Before;
import org.junit.Test;
@@ -40,6 +54,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Optional;

/**
 * Tests for the drag and drop controller.
 */
@@ -56,6 +72,9 @@ public class DragAndDropControllerTest {
    @Mock
    private UiEventLogger mUiEventLogger;

    @Mock
    private DragAndDropController.DragAndDropListener mDragAndDropListener;

    private DragAndDropController mController;

    @Before
@@ -63,6 +82,7 @@ public class DragAndDropControllerTest {
        MockitoAnnotations.initMocks(this);
        mController = new DragAndDropController(mContext, mDisplayController, mUiEventLogger,
                mock(IconProvider.class), mock(ShellExecutor.class));
        mController.initialize(Optional.of(mock(SplitScreenController.class)));
    }

    @Test
@@ -77,4 +97,45 @@ public class DragAndDropControllerTest {
        mController.onDisplayAdded(nonDefaultDisplayId);
        assertFalse(mController.onDrag(dragLayout, mock(DragEvent.class)));
    }

    @Test
    public void testListenerOnDragStarted() {
        final View dragLayout = mock(View.class);
        final Display display = mock(Display.class);
        doReturn(display).when(dragLayout).getDisplay();
        doReturn(DEFAULT_DISPLAY).when(display).getDisplayId();

        final ClipData clipData = createClipData();
        final DragEvent event = mock(DragEvent.class);
        doReturn(ACTION_DRAG_STARTED).when(event).getAction();
        doReturn(clipData).when(event).getClipData();
        doReturn(clipData.getDescription()).when(event).getClipDescription();

        mController.addListener(mDragAndDropListener);

        // Ensure there's a target so that onDrag will execute
        mController.addDisplayDropTarget(0, mContext, mock(WindowManager.class),
                mock(FrameLayout.class), mock(DragLayout.class));

        // Verify the listener is called on a valid drag action.
        mController.onDrag(dragLayout, event);
        verify(mDragAndDropListener, times(1)).onDragStarted();

        // Verify the listener isn't called after removal.
        reset(mDragAndDropListener);
        mController.removeListener(mDragAndDropListener);
        mController.onDrag(dragLayout, event);
        verify(mDragAndDropListener, never()).onDragStarted();
    }

    private ClipData createClipData() {
        ClipDescription clipDescription = new ClipDescription(MIMETYPE_APPLICATION_SHORTCUT,
                new String[] { MIMETYPE_APPLICATION_SHORTCUT });
        Intent i = new Intent();
        i.putExtra(Intent.EXTRA_PACKAGE_NAME, "pkg");
        i.putExtra(Intent.EXTRA_SHORTCUT_ID, "shortcutId");
        i.putExtra(Intent.EXTRA_USER, android.os.Process.myUserHandle());
        ClipData.Item item = new ClipData.Item(i);
        return new ClipData(clipDescription, item);
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.onehanded.OneHandedController;

import com.google.common.collect.ImmutableList;
@@ -367,6 +368,7 @@ public class BubblesTest extends SysuiTestCase {
                mPositioner,
                mock(DisplayController.class),
                mOneHandedOptional,
                mock(DragAndDropController.class),
                syncExecutor,
                mock(Handler.class),
                mTaskViewTransitions,
Loading