Merge "Remove logs for bug investigation" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index e004acc..c54bb7e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -174,6 +174,9 @@
 
         mSlideInView = (TaskbarAllAppsSlideInView) mOverlayContext.getLayoutInflater().inflate(
                 R.layout.taskbar_all_apps_sheet, mOverlayContext.getDragLayer(), false);
+        // Ensures All Apps gets touch events in case it is not the top floating view. Floating
+        // views above it may not be able to intercept the touch, so All Apps should try to.
+        mOverlayContext.getDragLayer().addTouchController(mSlideInView);
         mSlideInView.addOnCloseListener(() -> {
             mControllers.getSharedState().allAppsVisible = false;
             cleanUpOverlay();
@@ -212,6 +215,7 @@
             mSearchSessionController = null;
         }
         if (mOverlayContext != null) {
+            mOverlayContext.getDragLayer().removeTouchController(mSlideInView);
             mOverlayContext.setSearchSessionController(null);
             mOverlayContext = null;
         }
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 001c3bc..c6c4f77 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -220,7 +220,9 @@
     @Override
     public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            mNoIntercept = !mAppsView.shouldContainerScroll(ev);
+            mNoIntercept = !mAppsView.shouldContainerScroll(ev)
+                    || getTopOpenViewWithType(
+                            mActivityContext, TYPE_ACCESSIBLE & ~TYPE_TASKBAR_ALL_APPS) != null;
         }
         return super.onControllerInterceptTouchEvent(ev);
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index 3a6d613..6d740c0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -84,7 +84,7 @@
     private void setUpTaskbarStashing() {
         if (DisplayController.isTransientTaskbar(mContext)) {
             mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true);
-            mTaskbarStashController.applyState(mOverlayController.getOpenDuration());
+            mTaskbarStashController.applyState();
         }
 
         mNavbarButtonsViewController.setSlideInViewVisible(true);
@@ -95,7 +95,7 @@
 
             if (DisplayController.isTransientTaskbar(mContext)) {
                 mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false);
-                mTaskbarStashController.applyState(mOverlayController.getCloseDuration());
+                mTaskbarStashController.applyState();
             }
         });
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index 9126c4b..c4eeea7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -23,7 +23,6 @@
 import static com.android.launcher3.LauncherState.ALL_APPS;
 
 import android.annotation.SuppressLint;
-import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.view.Gravity;
@@ -60,12 +59,6 @@
 
     private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
-        public void onTaskCreated(int taskId, ComponentName componentName) {
-            // Created task will be below existing overlay, so move out of the way.
-            hideWindowOnTaskStackChange();
-        }
-
-        @Override
         public void onTaskMovedToFront(int taskId) {
             // New front task will be below existing overlay, so move out of the way.
             hideWindowOnTaskStackChange();
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index ff00560..e742a3d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -38,6 +38,7 @@
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.views.BaseDragLayer;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -69,6 +70,7 @@
             return true;
         }
     };
+    private final List<TouchController> mTouchControllers = new ArrayList<>();
 
     TaskbarOverlayDragLayer(Context context) {
         super(context, null, 1);
@@ -93,10 +95,13 @@
 
     @Override
     public void recreateControllers() {
-        mControllers = mOnClickListeners.isEmpty()
-                ? new TouchController[]{mActivity.getDragController()}
-                : new TouchController[] {
-                        mActivity.getDragController(), mClickListenerTouchController};
+        List<TouchController> controllers = new ArrayList<>();
+        controllers.add(mActivity.getDragController());
+        controllers.addAll(mTouchControllers);
+        if (!mOnClickListeners.isEmpty()) {
+            controllers.add(mClickListenerTouchController);
+        }
+        mControllers = controllers.toArray(new TouchController[0]);
     }
 
     @Override
@@ -183,6 +188,18 @@
         });
     }
 
+    /** Adds a {@link TouchController} to this drag layer. */
+    public void addTouchController(@NonNull TouchController touchController) {
+        mTouchControllers.add(touchController);
+        recreateControllers();
+    }
+
+    /** Removes a {@link TouchController} from this drag layer. */
+    public void removeTouchController(@NonNull TouchController touchController) {
+        mTouchControllers.remove(touchController);
+        recreateControllers();
+    }
+
     /**
      * Taskbar automatically stashes when opening all apps, but we don't report the insets as
      * changing to avoid moving the underlying app. But internally, the apps view should still
diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java
index 0c5b722..06cb00e 100644
--- a/src/com/android/launcher3/util/SettingsCache.java
+++ b/src/com/android/launcher3/util/SettingsCache.java
@@ -154,7 +154,7 @@
      */
     public void unregister(Uri uri, OnChangeListener listener) {
         List<OnChangeListener> listenersToRemoveFrom = mListenerMap.get(uri);
-        if (!listenersToRemoveFrom.contains(listener)) {
+        if (listenersToRemoveFrom == null) {
             return;
         }
 
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index f64fd05..1aa49c7 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -112,7 +112,7 @@
         if (Utilities.ATLEAST_Q && Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) {
             setOnLightBackground(true);
         }
-        mColorExtractor = LocalColorExtractor.newInstance(getContext());
+        mColorExtractor = new LocalColorExtractor(); // no-op
     }
 
     @Override
diff --git a/tests/Android.bp b/tests/Android.bp
index 9bb8787..fe04527 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -43,6 +43,7 @@
     name: "launcher-oop-tests-src",
     srcs: [
       "src/com/android/launcher3/allapps/OopTaplOpenCloseAllApps.java",
+      "src/com/android/launcher3/dragging/TaplDragTest.java",
       "src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
       "src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
       "src/com/android/launcher3/ui/TaplTestsLauncher3.java",
diff --git a/tests/src/com/android/launcher3/dragging/TaplDragTest.java b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
new file mode 100644
index 0000000..1e28d98
--- /dev/null
+++ b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.dragging;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.APP_NAME;
+import static com.android.launcher3.ui.TaplTestsLauncher3.GMAIL_APP_NAME;
+import static com.android.launcher3.ui.TaplTestsLauncher3.MAPS_APP_NAME;
+import static com.android.launcher3.ui.TaplTestsLauncher3.STORE_APP_NAME;
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Point;
+import android.os.SystemClock;
+import android.platform.test.annotations.PlatinumTest;
+import android.util.Log;
+
+import com.android.launcher3.tapl.Folder;
+import com.android.launcher3.tapl.FolderIcon;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.tapl.HomeAppIcon;
+import com.android.launcher3.tapl.HomeAppIconMenuItem;
+import com.android.launcher3.tapl.Workspace;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.TestUtil;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This test run in both Out of process (Oop) and in-process (Ipc).
+ * Tests multiple facets of the drag interaction in the Launcher:
+ *    * Can create a folder by dragging items.
+ *    * Can create a shortcut by dragging it to Workspace.
+ *    * Can create shortcuts in multiple spaces in the Workspace.
+ *    * Can cancel a drag icon to workspace by dragging outside of the Workspace.
+ *    * Can drag an icon from AllApps into the workspace
+ *    * Can drag an icon on the Workspace to other positions of the Workspace.
+ */
+public class TaplDragTest extends AbstractLauncherUiTest {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        initialize(this);
+    }
+
+    /**
+     * Adds two icons to the Workspace and combines them into a folder, then makes sure the icons
+     * are no longer in the Workspace then adds a third one to test adding an icon to an existing
+     * folder instead of creating one and drags it to the folder.
+     */
+    @Test
+    @PortraitLandscape
+    @ScreenRecord
+    @Ignore // b/233075289
+    @PlatinumTest(focusArea = "launcher")
+    public void testDragToFolder() {
+        // TODO: add the use case to drag an icon to an existing folder. Currently it either fails
+        // on tablets or phones due to difference in resolution.
+        final HomeAppIcon playStoreIcon = createShortcutIfNotExist(STORE_APP_NAME, 0, 1);
+        final HomeAppIcon gmailIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
+
+        FolderIcon folderIcon = gmailIcon.dragToIcon(playStoreIcon);
+        Folder folder = folderIcon.open();
+        folder.getAppIcon(STORE_APP_NAME);
+        folder.getAppIcon(GMAIL_APP_NAME);
+        Workspace workspace = folder.close();
+
+        workspace.verifyWorkspaceAppIconIsGone(STORE_APP_NAME + " should be moved to a folder.",
+                STORE_APP_NAME);
+        workspace.verifyWorkspaceAppIconIsGone(GMAIL_APP_NAME + " should be moved to a folder.",
+                GMAIL_APP_NAME);
+
+        final HomeAppIcon mapIcon = createShortcutInCenterIfNotExist(MAPS_APP_NAME);
+        folderIcon = mapIcon.dragToIcon(folderIcon);
+        folder = folderIcon.open();
+        folder.getAppIcon(MAPS_APP_NAME);
+        workspace = folder.close();
+
+        workspace.verifyWorkspaceAppIconIsGone(MAPS_APP_NAME + " should be moved to a folder.",
+                MAPS_APP_NAME);
+    }
+
+
+    /** Drags a shortcut from a long press menu into the workspace.
+     * 1. Open all apps and wait for load complete.
+     * 2. Find the app and long press it to show shortcuts.
+     * 3. Press icon center until shortcuts appear
+     * 4. Drags shortcut to any free space in the Workspace.
+     */
+    @Test
+    @PortraitLandscape
+    @PlatinumTest(focusArea = "launcher")
+    public void testDragShortcut() {
+
+        final HomeAllApps allApps = mLauncher
+                .getWorkspace()
+                .switchToAllApps();
+        allApps.freeze();
+        try {
+            final HomeAppIconMenuItem menuItem = allApps
+                    .getAppIcon(APP_NAME)
+                    .openDeepShortcutMenu()
+                    .getMenuItem(0);
+            final String actualShortcutName = menuItem.getText();
+            final String expectedShortcutName = "Shortcut 1";
+
+            assertEquals(expectedShortcutName, actualShortcutName);
+            menuItem.dragToWorkspace(false, false);
+            mLauncher.getWorkspace().getWorkspaceAppIcon(expectedShortcutName)
+                    .launch(getAppPackageName());
+        } finally {
+            allApps.unfreeze();
+        }
+    }
+
+    /**
+     * Similar to testDragShortcut but it adds shortcuts to multiple positions of the Workspace
+     * namely the corners and the center.
+     */
+    @Test
+    @PortraitLandscape
+    @PlatinumTest(focusArea = "launcher")
+    public void testDragShortcutToMultipleWorkspaceCells() {
+        Point[] targets = TestUtil.getCornersAndCenterPositions(mLauncher);
+
+        for (Point target : targets) {
+            final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+            allApps.freeze();
+            try {
+                allApps.getAppIcon(APP_NAME)
+                        .openDeepShortcutMenu()
+                        .getMenuItem(0)
+                        .dragToWorkspace(target.x, target.y);
+            } finally {
+                allApps.unfreeze();
+            }
+        }
+    }
+
+    /**
+     * Drags an icon to the workspace but instead of submitting it, it gets dragged outside of the
+     * Workspace to cancel it.
+     */
+
+    @Test
+    @PortraitLandscape
+    @PlatinumTest(focusArea = "launcher")
+    public void testDragAndCancelAppIcon() {
+        final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
+        Point positionBeforeDrag =
+                mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
+        assertNotNull("App not found in Workspace before dragging.", positionBeforeDrag);
+
+        mLauncher.getWorkspace().dragAndCancelAppIcon(homeAppIcon);
+
+        Point positionAfterDrag =
+                mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
+        assertNotNull("App not found in Workspace after dragging.", positionAfterDrag);
+        assertEquals("App not returned to same position in Workspace after drag & cancel",
+                positionBeforeDrag, positionAfterDrag);
+    }
+
+    /**
+     * Drags app icon from AllApps into the Workspace.
+     * 1. Open all apps and wait for load complete.
+     * 2. Drag icon to homescreen.
+     * 3. Verify that the icon works on homescreen.
+     */
+    @PlatinumTest(focusArea = "launcher")
+    @Test
+    @PortraitLandscape
+    @ScreenRecord // b/256898879
+    public void testDragAppIcon() {
+
+        final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+        allApps.freeze();
+        try {
+            allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
+            mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName());
+        } finally {
+            allApps.unfreeze();
+        }
+        executeOnLauncher(launcher -> assertTrue(
+                "Launcher activity is the top activity; expecting another activity to be the top "
+                        + "one",
+                isInLaunchedApp(launcher)));
+    }
+
+    /**
+     * Similar start to testDragAppIcon but after dragging the icon to the workspace, it drags the
+     * icon inside of the workspace to different positions.
+     * @throws Exception
+     */
+    @Test
+    @PortraitLandscape
+    @PlatinumTest(focusArea = "launcher")
+    public void testDragAppIconToMultipleWorkspaceCells() throws Exception {
+        long startTime, endTime, elapsedTime;
+        Point[] targets = TestUtil.getCornersAndCenterPositions(mLauncher);
+
+        for (Point target : targets) {
+            startTime = SystemClock.uptimeMillis();
+            final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+            allApps.freeze();
+            try {
+                allApps.getAppIcon(APP_NAME).dragToWorkspace(target.x, target.y);
+            } finally {
+                allApps.unfreeze();
+            }
+            // Reset the workspace for the next shortcut creation.
+            initialize(this, true);
+            endTime = SystemClock.uptimeMillis();
+            elapsedTime = endTime - startTime;
+            Log.d("testDragAppIconToWorkspaceCellTime",
+                    "Milliseconds taken to drag app icon to workspace cell: " + elapsedTime);
+        }
+
+        // test to move a shortcut to other cell.
+        final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(APP_NAME);
+        for (Point target : targets) {
+            startTime = SystemClock.uptimeMillis();
+            launcherTestAppIcon.dragToWorkspace(target.x, target.y);
+            endTime = SystemClock.uptimeMillis();
+            elapsedTime = endTime - startTime;
+            Log.d("testDragAppIconToWorkspaceCellTime",
+                    "Milliseconds taken to move shortcut to other cell: " + elapsedTime);
+        }
+    }
+}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 707781e..f734fe5 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -122,6 +122,10 @@
                 }, DEFAULT_UI_TIMEOUT, launcher);
     }
 
+    public static String getAppPackageName() {
+        return getInstrumentation().getContext().getPackageName();
+    }
+
     private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher) {
         sActivityLeakReported = true;
         return "Activity leak detector has found leaked activities, "
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 0316f84..69572df 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -16,8 +16,6 @@
 
 package com.android.launcher3.ui;
 
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
 import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
 import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
 import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
@@ -32,7 +30,6 @@
 
 import android.content.Intent;
 import android.graphics.Point;
-import android.os.SystemClock;
 import android.platform.test.annotations.PlatinumTest;
 import android.util.Log;
 
@@ -49,11 +46,8 @@
 import com.android.launcher3.tapl.AppIcon;
 import com.android.launcher3.tapl.AppIconMenu;
 import com.android.launcher3.tapl.AppIconMenuItem;
-import com.android.launcher3.tapl.Folder;
-import com.android.launcher3.tapl.FolderIcon;
 import com.android.launcher3.tapl.HomeAllApps;
 import com.android.launcher3.tapl.HomeAppIcon;
-import com.android.launcher3.tapl.HomeAppIconMenuItem;
 import com.android.launcher3.tapl.Widgets;
 import com.android.launcher3.tapl.Workspace;
 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
@@ -68,7 +62,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -79,11 +72,11 @@
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
-    private static final String APP_NAME = "LauncherTestApp";
-    private static final String DUMMY_APP_NAME = "Aardwolf";
-    private static final String MAPS_APP_NAME = "Maps";
-    private static final String STORE_APP_NAME = "Play Store";
-    private static final String GMAIL_APP_NAME = "Gmail";
+    public static final String APP_NAME = "LauncherTestApp";
+    public static final String DUMMY_APP_NAME = "Aardwolf";
+    public static final String MAPS_APP_NAME = "Maps";
+    public static final String STORE_APP_NAME = "Play Store";
+    public static final String GMAIL_APP_NAME = "Gmail";
     private static final String READ_DEVICE_CONFIG_PERMISSION =
             "android.permission.READ_DEVICE_CONFIG";
 
@@ -312,89 +305,6 @@
             allApps.unfreeze();
         }
     }
-
-    @PlatinumTest(focusArea = "launcher")
-    @Test
-    @PortraitLandscape
-    @ScreenRecord // b/256898879
-    public void testDragAppIcon() throws Throwable {
-        // 1. Open all apps and wait for load complete.
-        // 2. Drag icon to homescreen.
-        // 3. Verify that the icon works on homescreen.
-        final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
-        allApps.freeze();
-        try {
-            allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
-            mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName());
-        } finally {
-            allApps.unfreeze();
-        }
-        executeOnLauncher(launcher -> assertTrue(
-                "Launcher activity is the top activity; expecting another activity to be the top "
-                        + "one",
-                isInLaunchedApp(launcher)));
-    }
-
-    @Test
-    @PortraitLandscape
-    @PlatinumTest(focusArea = "launcher")
-    public void testDragShortcut() throws Throwable {
-        // 1. Open all apps and wait for load complete.
-        // 2. Find the app and long press it to show shortcuts.
-        // 3. Press icon center until shortcuts appear
-        final HomeAllApps allApps = mLauncher
-                .getWorkspace()
-                .switchToAllApps();
-        allApps.freeze();
-        try {
-            final HomeAppIconMenuItem menuItem = allApps
-                    .getAppIcon(APP_NAME)
-                    .openDeepShortcutMenu()
-                    .getMenuItem(0);
-            final String actualShortcutName = menuItem.getText();
-            final String expectedShortcutName = "Shortcut 1";
-
-            assertEquals(expectedShortcutName, actualShortcutName);
-            menuItem.dragToWorkspace(false, false);
-            mLauncher.getWorkspace().getWorkspaceAppIcon(expectedShortcutName)
-                    .launch(getAppPackageName());
-        } finally {
-            allApps.unfreeze();
-        }
-    }
-
-    @Test
-    @PortraitLandscape
-    @ScreenRecord
-    @Ignore // b/233075289
-    @PlatinumTest(focusArea = "launcher")
-    public void testDragToFolder() {
-        // TODO: add the use case to drag an icon to an existing folder. Currently it either fails
-        // on tablets or phones due to difference in resolution.
-        final HomeAppIcon playStoreIcon = createShortcutIfNotExist(STORE_APP_NAME, 0, 1);
-        final HomeAppIcon gmailIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
-
-        FolderIcon folderIcon = gmailIcon.dragToIcon(playStoreIcon);
-        Folder folder = folderIcon.open();
-        folder.getAppIcon(STORE_APP_NAME);
-        folder.getAppIcon(GMAIL_APP_NAME);
-        Workspace workspace = folder.close();
-
-        workspace.verifyWorkspaceAppIconIsGone(STORE_APP_NAME + " should be moved to a folder.",
-                STORE_APP_NAME);
-        workspace.verifyWorkspaceAppIconIsGone(GMAIL_APP_NAME + " should be moved to a folder.",
-                GMAIL_APP_NAME);
-
-        final HomeAppIcon mapIcon = createShortcutInCenterIfNotExist(MAPS_APP_NAME);
-        folderIcon = mapIcon.dragToIcon(folderIcon);
-        folder = folderIcon.open();
-        folder.getAppIcon(MAPS_APP_NAME);
-        workspace = folder.close();
-
-        workspace.verifyWorkspaceAppIconIsGone(MAPS_APP_NAME + " should be moved to a folder.",
-                MAPS_APP_NAME);
-    }
-
     @FlakyTest(bugId = 256615483)
     @Test
     @PortraitLandscape
@@ -414,24 +324,6 @@
 
     @Test
     @PortraitLandscape
-    @PlatinumTest(focusArea = "launcher")
-    public void testDragAndCancelAppIcon() {
-        final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
-        Point positionBeforeDrag =
-                mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
-        assertNotNull("App not found in Workspace before dragging.", positionBeforeDrag);
-
-        mLauncher.getWorkspace().dragAndCancelAppIcon(homeAppIcon);
-
-        Point positionAfterDrag =
-                mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
-        assertNotNull("App not found in Workspace after dragging.", positionAfterDrag);
-        assertEquals("App not returned to same position in Workspace after drag & cancel",
-                positionBeforeDrag, positionAfterDrag);
-    }
-
-    @Test
-    @PortraitLandscape
     public void testDeleteFromWorkspace() throws Exception {
         // test delete both built-in apps and user-installed app from workspace
         for (String appName : new String[]{"Gmail", "Play Store", APP_NAME}) {
@@ -479,50 +371,14 @@
             TestUtil.uninstallDummyApp();
         }
     }
-
-    @Test
-    @PortraitLandscape
-    @PlatinumTest(focusArea = "launcher")
-    public void testDragAppIconToWorkspaceCell() throws Exception {
-        long startTime, endTime, elapsedTime;
-        Point[] targets = getCornersAndCenterPositions();
-
-        for (Point target : targets) {
-            startTime = SystemClock.uptimeMillis();
-            final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
-            allApps.freeze();
-            try {
-                allApps.getAppIcon(APP_NAME).dragToWorkspace(target.x, target.y);
-            } finally {
-                allApps.unfreeze();
-            }
-            // Reset the workspace for the next shortcut creation.
-            initialize(this, true);
-            endTime = SystemClock.uptimeMillis();
-            elapsedTime = endTime - startTime;
-            Log.d("testDragAppIconToWorkspaceCellTime",
-                    "Milliseconds taken to drag app icon to workspace cell: " + elapsedTime);
-        }
-
-        // test to move a shortcut to other cell.
-        final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(APP_NAME);
-        for (Point target : targets) {
-            startTime = SystemClock.uptimeMillis();
-            launcherTestAppIcon.dragToWorkspace(target.x, target.y);
-            endTime = SystemClock.uptimeMillis();
-            elapsedTime = endTime - startTime;
-            Log.d("testDragAppIconToWorkspaceCellTime",
-                    "Milliseconds taken to move shortcut to other cell: " + elapsedTime);
-        }
-    }
-
     /**
      * Adds three icons to the workspace and removes one of them by dragging to uninstall.
      */
     @Test
+    @ScreenRecord // b/241821721
     @PlatinumTest(focusArea = "launcher")
     public void uninstallWorkspaceIcon() throws IOException {
-        Point[] gridPositions = getCornersAndCenterPositions();
+        Point[] gridPositions = TestUtil.getCornersAndCenterPositions(mLauncher);
         StringBuilder sb = new StringBuilder();
         for (Point p : gridPositions) {
             sb.append(p).append(", ");
@@ -552,26 +408,6 @@
 
     @Test
     @PortraitLandscape
-    @PlatinumTest(focusArea = "launcher")
-    public void testDragShortcutToWorkspaceCell() throws Exception {
-        Point[] targets = getCornersAndCenterPositions();
-
-        for (Point target : targets) {
-            final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
-            allApps.freeze();
-            try {
-                allApps.getAppIcon(APP_NAME)
-                        .openDeepShortcutMenu()
-                        .getMenuItem(0)
-                        .dragToWorkspace(target.x, target.y);
-            } finally {
-                allApps.unfreeze();
-            }
-        }
-    }
-
-    @Test
-    @PortraitLandscape
     public void testAddDeleteShortcutOnHotseat() {
         mLauncher.getWorkspace()
                 .deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
@@ -597,25 +433,6 @@
         mLauncher.waitForLauncherInitialized();
     }
 
-    /**
-     * @return List of workspace grid coordinates. Those are not pixels. See {@link
-     * Workspace#getIconGridDimensions()}
-     */
-    private Point[] getCornersAndCenterPositions() {
-        final Point dimensions = mLauncher.getWorkspace().getIconGridDimensions();
-        return new Point[]{
-                new Point(0, 1),
-                new Point(0, dimensions.y - 2),
-                new Point(dimensions.x - 1, 1),
-                new Point(dimensions.x - 1, dimensions.y - 2),
-                new Point(dimensions.x / 2, dimensions.y / 2)
-        };
-    }
-
-    public static String getAppPackageName() {
-        return getInstrumentation().getContext().getPackageName();
-    }
-
     @Test
     public void testGetAppIconName() {
         HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
diff --git a/tests/src/com/android/launcher3/util/TestUtil.java b/tests/src/com/android/launcher3/util/TestUtil.java
index 21059e6..957bf95 100644
--- a/tests/src/com/android/launcher3/util/TestUtil.java
+++ b/tests/src/com/android/launcher3/util/TestUtil.java
@@ -30,6 +30,7 @@
 import android.content.Context;
 import android.content.pm.LauncherApps;
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.Looper;
@@ -46,6 +47,8 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.config.FeatureFlags.BooleanFlag;
 import com.android.launcher3.config.FeatureFlags.IntFlag;
+import com.android.launcher3.tapl.LauncherInstrumentation;
+import com.android.launcher3.tapl.Workspace;
 
 import org.junit.Assert;
 
@@ -125,6 +128,21 @@
     }
 
     /**
+     * @return Grid coordinates from the center and corners of the Workspace. Those are not pixels.
+     * See {@link Workspace#getIconGridDimensions()}
+     */
+    public static Point[] getCornersAndCenterPositions(LauncherInstrumentation launcher) {
+        final Point dimensions = launcher.getWorkspace().getIconGridDimensions();
+        return new Point[]{
+                new Point(0, 1),
+                new Point(0, dimensions.y - 2),
+                new Point(dimensions.x - 1, 1),
+                new Point(dimensions.x - 1, dimensions.y - 2),
+                new Point(dimensions.x / 2, dimensions.y / 2)
+        };
+    }
+
+    /**
      * Utility class to override a boolean flag during test. Note that the returned SafeCloseable
      * must be closed to restore the original state
      */
diff --git a/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
index 5cc4c5e..592cc9b 100644
--- a/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
+++ b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
@@ -18,6 +18,7 @@
 import androidx.annotation.NonNull;
 
 import com.android.launcher3.tapl.LauncherInstrumentation;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
 
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
@@ -42,6 +43,7 @@
                 base.evaluate();
                 // Make sure that Launcher workspace looks correct.
                 mLauncher.goHome();
+                AbstractLauncherUiTest.checkDetectedLeaks(mLauncher);
             }
         };
     }