Merge "launcher: use same icon size for all apps drawer in foldables" into sc-v2-dev
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index c8abd14..2543e6c 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -565,12 +565,12 @@
 
     /** Start multiple tasks in split-screen simultaneously. */
     public void startTasks(int mainTaskId, Bundle mainOptions, int sideTaskId, Bundle sideOptions,
-            @SplitConfigurationOptions.StagePosition int sidePosition,
+            @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio,
             RemoteTransitionCompat remoteTransition) {
         if (mSystemUiProxy != null) {
             try {
                 mSplitScreen.startTasks(mainTaskId, mainOptions, sideTaskId, sideOptions,
-                        sidePosition, remoteTransition.getTransition());
+                        sidePosition, splitRatio, remoteTransition.getTransition());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call startTask");
             }
@@ -582,11 +582,11 @@
      */
     public void startTasksWithLegacyTransition(int mainTaskId, Bundle mainOptions, int sideTaskId,
             Bundle sideOptions, @SplitConfigurationOptions.StagePosition int sidePosition,
-            RemoteAnimationAdapter adapter) {
+            float splitRatio, RemoteAnimationAdapter adapter) {
         if (mSystemUiProxy != null) {
             try {
                 mSplitScreen.startTasksWithLegacyTransition(mainTaskId, mainOptions, sideTaskId,
-                        sideOptions, sidePosition, adapter);
+                        sideOptions, sidePosition, splitRatio, adapter);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call startTasksWithLegacyTransition");
             }
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 22f67d2..d2373c9 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -37,12 +37,12 @@
 import com.android.quickstep.FallbackActivityInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.RecentsActivity;
+import com.android.quickstep.util.GroupTask;
 import com.android.quickstep.util.SplitSelectStateController;
 import com.android.quickstep.util.TaskViewSimulator;
 import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
-import com.android.quickstep.util.GroupTask;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.Task.TaskKey;
 
@@ -206,10 +206,6 @@
 
     @Override
     public void onStateTransitionStart(RecentsState toState) {
-        if (toState == HOME) {
-            // Clean-up logic that occurs when recents is no longer in use/visible.
-            reset();
-        }
         setOverviewStateEnabled(true);
         setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
         setOverviewFullscreenEnabled(toState.isFullScreen());
@@ -218,6 +214,10 @@
 
     @Override
     public void onStateTransitionComplete(RecentsState finalState) {
+        if (finalState == HOME) {
+            // Clean-up logic that occurs when recents is no longer in use/visible.
+            reset();
+        }
         boolean isOverlayEnabled = finalState == DEFAULT || finalState == MODAL_TASK;
         setOverlayEnabled(isOverlayEnabled);
         setFreezeViewVisibility(false);
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index c784d82..d310893 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -18,6 +18,7 @@
 
 import static com.android.launcher3.Utilities.postAsyncCallback;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
 
@@ -30,7 +31,6 @@
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
 
-
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.statehandlers.DepthController;
@@ -95,7 +95,7 @@
     public void setSecondTaskId(Task task, Consumer<Boolean> callback) {
         mSecondTask = task;
         launchTasks(mInitialTask, mSecondTask, mStagePosition, callback,
-                false /* freezeTaskList */);
+                false /* freezeTaskList */, DEFAULT_SPLIT_RATIO);
     }
 
     /**
@@ -107,14 +107,15 @@
         TaskView.TaskIdAttributeContainer[] taskIdAttributeContainers =
                 groupedTaskView.getTaskIdAttributeContainers();
         launchTasks(taskIdAttributeContainers[0].getTask(), taskIdAttributeContainers[1].getTask(),
-                taskIdAttributeContainers[0].getStagePosition(), callback, freezeTaskList);
+                taskIdAttributeContainers[0].getStagePosition(), callback, freezeTaskList,
+                groupedTaskView.getSplitRatio());
     }
 
     /**
      * @param stagePosition representing location of task1
      */
     public void launchTasks(Task task1, Task task2, @StagePosition int stagePosition,
-            Consumer<Boolean> callback, boolean freezeTaskList) {
+            Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) {
         // Assume initial task is for top/left part of screen
         final int[] taskIds = stagePosition == STAGE_POSITION_TOP_OR_LEFT
                 ? new int[]{task1.key.id, task2.key.id}
@@ -123,7 +124,7 @@
             RemoteSplitLaunchTransitionRunner animationRunner =
                     new RemoteSplitLaunchTransitionRunner(task1, task2);
             mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
-                    null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
+                    null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, splitRatio,
                     new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR,
                             ActivityThread.currentActivityThread().getApplicationThread()));
         } else {
@@ -140,7 +141,7 @@
             }
             mSystemUiProxy.startTasksWithLegacyTransition(taskIds[0], mainOpts.toBundle(),
                     taskIds[1], null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
-                    adapter);
+                    splitRatio, adapter);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 4771d1e..00f541d 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -1,5 +1,6 @@
 package com.android.quickstep.views;
 
+import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
 
@@ -122,6 +123,14 @@
         invalidate();
     }
 
+    public float getSplitRatio() {
+        if (mSplitBoundsConfig != null) {
+            return mSplitBoundsConfig.appsStackedVertically
+                    ? mSplitBoundsConfig.topTaskPercent : mSplitBoundsConfig.leftTaskPercent;
+        }
+        return DEFAULT_SPLIT_RATIO;
+    }
+
     @Override
     public boolean offerTouchToChildren(MotionEvent event) {
         computeAndSetIconTouchDelegate(mIconView2, mIcon2CenterCoords, mIcon2TouchDelegate);
@@ -157,7 +166,8 @@
     @Override
     public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) {
         getRecentsView().getSplitPlaceholder().launchTasks(mTask, mSecondaryTask,
-                STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList);
+                STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList,
+                getSplitRatio());
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index a2e9e57..d001690 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -92,10 +92,6 @@
 
     @Override
     public void onStateTransitionStart(LauncherState toState) {
-        if (toState == NORMAL || toState == SPRING_LOADED) {
-            // Clean-up logic that occurs when recents is no longer in use/visible.
-            reset();
-        }
         setOverviewStateEnabled(toState.overviewUi);
         setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
         setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
@@ -104,6 +100,10 @@
 
     @Override
     public void onStateTransitionComplete(LauncherState finalState) {
+        if (finalState == NORMAL || finalState == SPRING_LOADED) {
+            // Clean-up logic that occurs when recents is no longer in use/visible.
+            reset();
+        }
         boolean isOverlayEnabled = finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK;
         setOverlayEnabled(isOverlayEnabled);
         setFreezeViewVisibility(false);
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 3aa8d46..e9010d2 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3185,6 +3185,7 @@
                                 }
                             }
                         }
+                        pageBeginTransition();
                         setCurrentPage(pageToSnapTo);
                         // Update various scroll-dependent UI.
                         dispatchScrollChanged();
@@ -4024,7 +4025,7 @@
 
     /** TODO(b/181707736) More gracefully handle exiting split selection state */
     private void resetFromSplitSelectionState() {
-        if (!showAsGrid()) {
+        if (!mActivity.getDeviceProfile().overviewShowAsGrid) {
             int pageToSnapTo = mCurrentPage;
             if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
                 pageToSnapTo += 1;
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 53b1c3e..cb714b2 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -68,6 +68,11 @@
     public @interface StageType {}
     ///////////////////////////////////
 
+    /**
+     * Default split ratio for launching app pair from overview.
+     */
+    public static final float DEFAULT_SPLIT_RATIO = 0.5f;
+
     public static class SplitPositionOption {
         public final int iconResId;
         public final int textResId;
diff --git a/tests/Android.bp b/tests/Android.bp
index c329ece..3670c37 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -23,7 +23,7 @@
 // Source code used for test
 filegroup {
     name: "launcher-tests-src",
-    srcs: ["src/**/*.java", "src/**/*.kt"],
+    srcs: ["src/**/*.java"],
 }
 
 // Source code used for oop test helpers
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
new file mode 100644
index 0000000..8a4590a
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -0,0 +1,201 @@
+package com.android.launcher3.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.util.Pair;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.model.BgDataModel.Callbacks;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.util.ContentWriter;
+import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSparseArrayMap;
+import com.android.launcher3.util.LauncherModelHelper;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link AddWorkspaceItemsTask}
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AddWorkspaceItemsTaskTest {
+
+    private final ComponentName mComponent1 = new ComponentName("a", "b");
+    private final ComponentName mComponent2 = new ComponentName("b", "b");
+
+    private Context mTargetContext;
+    private InvariantDeviceProfile mIdp;
+    private LauncherAppState mAppState;
+    private LauncherModelHelper mModelHelper;
+
+    private IntArray mExistingScreens;
+    private IntArray mNewScreens;
+    private IntSparseArrayMap<GridOccupancy> mScreenOccupancy;
+
+    @Before
+    public void setup() {
+        mModelHelper = new LauncherModelHelper();
+        mTargetContext = mModelHelper.sandboxContext;
+        mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
+        mIdp.numColumns = mIdp.numRows = 5;
+        mAppState = LauncherAppState.getInstance(mTargetContext);
+
+        mExistingScreens = new IntArray();
+        mScreenOccupancy = new IntSparseArrayMap<>();
+        mNewScreens = new IntArray();
+    }
+
+    @After
+    public void tearDown() {
+        mModelHelper.destroy();
+    }
+
+    private AddWorkspaceItemsTask newTask(ItemInfo... items) {
+        List<Pair<ItemInfo, Object>> list = new ArrayList<>();
+        for (ItemInfo item : items) {
+            list.add(Pair.create(item, null));
+        }
+        return new AddWorkspaceItemsTask(list);
+    }
+
+    @Test
+    public void testFindSpaceForItem_prefers_second() throws Exception {
+        // First screen has only one hole of size 1
+        int nextId = setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
+
+        // Second screen has 2 holes of sizes 3x2 and 2x3
+        setupWorkspaceWithHoles(nextId, 2, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));
+
+        int[] spaceFound = newTask().findSpaceForItem(
+                mAppState, mModelHelper.getBgDataModel(), mExistingScreens, mNewScreens, 1, 1);
+        assertEquals(1, spaceFound[0]);
+        assertTrue(mScreenOccupancy.get(spaceFound[0])
+                .isRegionVacant(spaceFound[1], spaceFound[2], 1, 1));
+
+        // Find a larger space
+        spaceFound = newTask().findSpaceForItem(
+                mAppState, mModelHelper.getBgDataModel(), mExistingScreens, mNewScreens, 2, 3);
+        assertEquals(2, spaceFound[0]);
+        assertTrue(mScreenOccupancy.get(spaceFound[0])
+                .isRegionVacant(spaceFound[1], spaceFound[2], 2, 3));
+    }
+
+    @Test
+    public void testFindSpaceForItem_adds_new_screen() throws Exception {
+        // First screen has 2 holes of sizes 3x2 and 2x3
+        setupWorkspaceWithHoles(1, 1, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));
+
+        IntArray oldScreens = mExistingScreens.clone();
+        int[] spaceFound = newTask().findSpaceForItem(
+                mAppState, mModelHelper.getBgDataModel(), mExistingScreens, mNewScreens, 3, 3);
+        assertFalse(oldScreens.contains(spaceFound[0]));
+        assertTrue(mNewScreens.contains(spaceFound[0]));
+    }
+
+    @Test
+    public void testAddItem_existing_item_ignored() throws Exception {
+        WorkspaceItemInfo info = new WorkspaceItemInfo();
+        info.intent = new Intent().setComponent(mComponent1);
+
+        // Setup a screen with a hole
+        setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
+
+        // Nothing was added
+        assertTrue(mModelHelper.executeTaskForTest(newTask(info)).isEmpty());
+    }
+
+    @Test
+    public void testAddItem_some_items_added() throws Exception {
+        Callbacks callbacks = mock(Callbacks.class);
+        Executors.MAIN_EXECUTOR.submit(() -> mModelHelper.getModel().addCallbacks(callbacks)).get();
+
+        WorkspaceItemInfo info = new WorkspaceItemInfo();
+        info.intent = new Intent().setComponent(mComponent1);
+
+        WorkspaceItemInfo info2 = new WorkspaceItemInfo();
+        info2.intent = new Intent().setComponent(mComponent2);
+
+        // Setup a screen with a hole
+        setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
+
+        mModelHelper.executeTaskForTest(newTask(info, info2)).get(0).run();
+        ArgumentCaptor<ArrayList> notAnimated = ArgumentCaptor.forClass(ArrayList.class);
+        ArgumentCaptor<ArrayList> animated = ArgumentCaptor.forClass(ArrayList.class);
+
+        // only info2 should be added because info was already added to the workspace
+        // in setupWorkspaceWithHoles()
+        verify(callbacks).bindAppsAdded(any(IntArray.class), notAnimated.capture(),
+                animated.capture());
+        assertTrue(notAnimated.getValue().isEmpty());
+
+        assertEquals(1, animated.getValue().size());
+        assertTrue(animated.getValue().contains(info2));
+    }
+
+    private int setupWorkspaceWithHoles(int startId, int screenId, Rect... holes) throws Exception {
+        return mModelHelper.executeSimpleTask(
+                model -> writeWorkspaceWithHoles(model, startId, screenId, holes));
+    }
+
+    private int writeWorkspaceWithHoles(
+            BgDataModel bgDataModel, int startId, int screenId, Rect... holes) {
+        GridOccupancy occupancy = new GridOccupancy(mIdp.numColumns, mIdp.numRows);
+        occupancy.markCells(0, 0, mIdp.numColumns, mIdp.numRows, true);
+        for (Rect r : holes) {
+            occupancy.markCells(r, false);
+        }
+
+        mExistingScreens.add(screenId);
+        mScreenOccupancy.append(screenId, occupancy);
+
+        for (int x = 0; x < mIdp.numColumns; x++) {
+            for (int y = 0; y < mIdp.numRows; y++) {
+                if (!occupancy.cells[x][y]) {
+                    continue;
+                }
+
+                WorkspaceItemInfo info = new WorkspaceItemInfo();
+                info.intent = new Intent().setComponent(mComponent1);
+                info.id = startId++;
+                info.screenId = screenId;
+                info.cellX = x;
+                info.cellY = y;
+                info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+                bgDataModel.addItem(mTargetContext, info, false);
+
+                ContentWriter writer = new ContentWriter(mTargetContext);
+                info.writeToValues(writer);
+                writer.put(Favorites._ID, info.id);
+                mTargetContext.getContentResolver().insert(Favorites.CONTENT_URI,
+                        writer.getValues(mTargetContext));
+            }
+        }
+        return startId;
+    }
+}
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt
deleted file mode 100644
index e315658..0000000
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (C) 2021 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.model
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Rect
-import android.util.Pair
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.InvariantDeviceProfile
-import com.android.launcher3.LauncherAppState
-import com.android.launcher3.LauncherSettings
-import com.android.launcher3.model.data.ItemInfo
-import com.android.launcher3.model.data.WorkspaceItemInfo
-import com.android.launcher3.util.*
-import com.android.launcher3.util.IntArray
-import org.junit.After
-import org.junit.Assert.*
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.*
-import org.mockito.ArgumentMatchers.any
-import org.mockito.Mockito.verify
-import kotlin.collections.ArrayList
-
-/**
- * Tests for [AddWorkspaceItemsTask]
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class AddWorkspaceItemsTaskTest {
-
-    @Captor
-    private lateinit var animatedItemArgumentCaptor: ArgumentCaptor<ArrayList<ItemInfo>>
-
-    @Captor
-    private lateinit var notAnimatedItemArgumentCaptor: ArgumentCaptor<ArrayList<ItemInfo>>
-
-    @Mock
-    private lateinit var dataModelCallbacks: BgDataModel.Callbacks
-
-    private lateinit var mTargetContext: Context
-    private lateinit var mIdp: InvariantDeviceProfile
-    private lateinit var mAppState: LauncherAppState
-    private lateinit var mModelHelper: LauncherModelHelper
-    private lateinit var mExistingScreens: IntArray
-    private lateinit var mNewScreens: IntArray
-    private lateinit var mScreenOccupancy: IntSparseArrayMap<GridOccupancy>
-
-    private val emptyScreenHoles = listOf(Rect(0, 0, 5, 5))
-    private val fullScreenHoles = emptyList<Rect>()
-
-
-    @Before
-    fun setup() {
-        MockitoAnnotations.initMocks(this)
-        mModelHelper = LauncherModelHelper()
-        mTargetContext = mModelHelper.sandboxContext
-        mIdp = InvariantDeviceProfile.INSTANCE[mTargetContext]
-        mIdp.numRows = 5
-        mIdp.numColumns = mIdp.numRows
-        mAppState = LauncherAppState.getInstance(mTargetContext)
-        mExistingScreens = IntArray()
-        mScreenOccupancy = IntSparseArrayMap()
-        mNewScreens = IntArray()
-        Executors.MAIN_EXECUTOR.submit { mModelHelper.model.addCallbacks(dataModelCallbacks) }.get()
-    }
-
-    @After
-    fun tearDown() {
-        mModelHelper.destroy()
-    }
-
-    @Test
-    fun justEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnFirstScreenId() {
-        setupWorkspacesWithHoles(
-                screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 hole
-                //  2 holes of sizes 3x2 and 2x3
-                screen2 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)),
-        )
-
-        val spaceFound = newTask().findSpaceForItem(
-                mAppState, mModelHelper.bgDataModel, mExistingScreens, mNewScreens, 1, 1)
-        assertEquals(1, spaceFound[0])
-        assertTrue(mScreenOccupancy[spaceFound[0]]
-                .isRegionVacant(spaceFound[1], spaceFound[2], 1, 1))
-    }
-
-    @Test
-    fun notEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnSecondScreenId() {
-        setupWorkspacesWithHoles(
-                screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 hole
-                //  2 holes of sizes 3x2 and 2x3
-                screen2 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)),
-        )
-
-        // Find a larger space
-        val spaceFound = newTask().findSpaceForItem(
-                mAppState, mModelHelper.bgDataModel, mExistingScreens, mNewScreens, 2, 3)
-        assertEquals(2, spaceFound[0])
-        assertTrue(mScreenOccupancy[spaceFound[0]]
-                .isRegionVacant(spaceFound[1], spaceFound[2], 2, 3))
-    }
-
-    @Test
-    fun notEnoughSpaceOnExistingScreens_whenFindSpaceForItem_thenReturnNewScreenId() {
-        setupWorkspacesWithHoles(
-                //  2 holes of sizes 3x2 and 2x3
-                screen1 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)),
-                //  2 holes of sizes 1x2 and 2x2
-                screen2 = listOf(Rect(1, 0, 2, 2), Rect(3, 2, 5, 4)),
-        )
-
-        val oldScreens = mExistingScreens.clone()
-        val spaceFound = newTask().findSpaceForItem(
-                mAppState, mModelHelper.bgDataModel, mExistingScreens, mNewScreens, 3, 3)
-        assertFalse(oldScreens.contains(spaceFound[0]))
-        assertTrue(mNewScreens.contains(spaceFound[0]))
-    }
-
-    @Test
-    fun enoughSpaceOnFirstScreen_whenTaskRuns_thenAddItemToFirstScreen() {
-        val workspaceHoles = createWorkspaceHoles(
-                screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 space
-                screen2 = listOf(Rect(2, 0, 5, 2)), // 3x2 space
-        )
-        val addedItems = testAddItems(workspaceHoles, getNewItem())
-        assertEquals(1, addedItems.size)
-        assertEquals(1, addedItems.first().itemInfo.screenId)
-    }
-
-    @Test
-    fun firstPageIsFull_whenTaskRuns_thenAddItemToSecondScreen() {
-        val workspaceHoles = createWorkspaceHoles(
-                screen1 = fullScreenHoles,
-        )
-        val addedItems = testAddItems(workspaceHoles, getNewItem())
-        assertEquals(1, addedItems.size)
-        assertEquals(2, addedItems.first().itemInfo.screenId)
-    }
-
-    @Test
-    fun firstScreenIsEmptyButSecondIsNotEmpty_whenTaskRuns_thenAddItemToSecondScreen() {
-        val workspaceHoles = createWorkspaceHoles(
-                screen1 = emptyScreenHoles,
-                screen2 = listOf(Rect(2, 0, 5, 2)), // 3x2 space
-        )
-        val addedItems = testAddItems(workspaceHoles, getNewItem())
-        assertEquals(1, addedItems.size)
-        assertEquals(2, addedItems.first().itemInfo.screenId)
-    }
-
-    @Test
-    fun twoEmptyMiddleScreens_whenTaskRuns_thenAddItemToThirdScreen() {
-        val workspaceHoles = createWorkspaceHoles(
-                screen1 = emptyScreenHoles,
-                screen2 = emptyScreenHoles,
-                screen3 = listOf(Rect(1, 1, 4, 4)), // 3x3 space
-        )
-        val addedItems = testAddItems(workspaceHoles, getNewItem())
-        assertEquals(1, addedItems.size)
-        assertEquals(3, addedItems.first().itemInfo.screenId)
-    }
-
-    @Test
-    fun allPagesAreFull_whenTaskRuns_thenAddItemToNewScreen() {
-        val workspaceHoles = createWorkspaceHoles(
-                screen1 = fullScreenHoles,
-                screen2 = fullScreenHoles,
-        )
-        val addedItems = testAddItems(workspaceHoles, getNewItem())
-        assertEquals(1, addedItems.size)
-        assertEquals(3, addedItems.first().itemInfo.screenId)
-    }
-
-    @Test
-    fun firstTwoPagesAreFull_and_ThirdPageIsEmpty_whenTaskRuns_thenAddItemToThirdPage() {
-        val workspaceHoles = createWorkspaceHoles(
-                screen1 = fullScreenHoles,
-                screen2 = fullScreenHoles,
-                screen3 = emptyScreenHoles
-        )
-        val addedItems = testAddItems(workspaceHoles, getNewItem())
-        assertEquals(1, addedItems.size)
-        assertEquals(3, addedItems.first().itemInfo.screenId)
-    }
-
-    @Test
-    fun itemIsAlreadyAdded_whenTaskRun_thenIgnoreItem() {
-        val task = newTask(getExistingItem())
-        setupWorkspacesWithHoles(
-                screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 hole
-        )
-
-        // Nothing was added
-        assertTrue(mModelHelper.executeTaskForTest(task).isEmpty())
-    }
-
-    @Test
-    fun newAndExistingItems_whenTaskRun_thenAddOnlyTheNewOne() {
-        val newItem = getNewItem()
-        val workspaceHoles = createWorkspaceHoles(
-                screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 hole
-        )
-        val addedItems = testAddItems(workspaceHoles, getExistingItem(), newItem)
-        assertEquals(1, addedItems.size)
-        val addedItem = addedItems.first()
-        assert(addedItem.isAnimated)
-        val addedItemInfo = addedItem.itemInfo
-        assertEquals(1, addedItemInfo.screenId)
-        assertEquals(newItem, addedItemInfo)
-    }
-
-    private fun testAddItems(
-            workspaceHoles: List<List<Rect>>,
-            vararg itemsToAdd: WorkspaceItemInfo
-    ): List<AddedItem> {
-        setupWorkspaces(workspaceHoles)
-        mModelHelper.executeTaskForTest(newTask(*itemsToAdd))[0].run()
-
-        verify(dataModelCallbacks).bindAppsAdded(any(),
-                notAnimatedItemArgumentCaptor.capture(), animatedItemArgumentCaptor.capture())
-
-        val addedItems = mutableListOf<AddedItem>()
-        addedItems.addAll(animatedItemArgumentCaptor.value.map { AddedItem(it, true) })
-        addedItems.addAll(notAnimatedItemArgumentCaptor.value.map { AddedItem(it, false) })
-        return addedItems
-    }
-
-    private fun setupWorkspaces(workspaceHoles: List<List<Rect>>) {
-        var nextItemId = 1
-        var screenId = 1
-        workspaceHoles.forEach { holes ->
-            nextItemId = setupWorkspace(nextItemId, screenId++, *holes.toTypedArray())
-        }
-    }
-
-    private fun setupWorkspace(startId: Int, screenId: Int, vararg holes: Rect): Int {
-        return mModelHelper.executeSimpleTask { dataModel ->
-            writeWorkspaceWithHoles(dataModel, startId, screenId, *holes)
-        }
-    }
-
-    private fun writeWorkspaceWithHoles(
-            bgDataModel: BgDataModel,
-            itemStartId: Int,
-            screenId: Int,
-            vararg holes: Rect,
-    ): Int {
-        var itemId = itemStartId
-        val occupancy = GridOccupancy(mIdp.numColumns, mIdp.numRows)
-        occupancy.markCells(0, 0, mIdp.numColumns, mIdp.numRows, true)
-        holes.forEach { holeRect ->
-            occupancy.markCells(holeRect, false)
-        }
-        mExistingScreens.add(screenId)
-        mScreenOccupancy.append(screenId, occupancy)
-        for (x in 0 until mIdp.numColumns) {
-            for (y in 0 until mIdp.numRows) {
-                if (!occupancy.cells[x][y]) {
-                    continue
-                }
-                val info = getExistingItem()
-                info.id = itemId++
-                info.screenId = screenId
-                info.cellX = x
-                info.cellY = y
-                info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP
-                bgDataModel.addItem(mTargetContext, info, false)
-                val writer = ContentWriter(mTargetContext)
-                info.writeToValues(writer)
-                writer.put(LauncherSettings.Favorites._ID, info.id)
-                mTargetContext.contentResolver.insert(LauncherSettings.Favorites.CONTENT_URI,
-                        writer.getValues(mTargetContext))
-            }
-        }
-        return itemId
-    }
-
-    private fun setupWorkspacesWithHoles(
-            screen1: List<Rect>? = null,
-            screen2: List<Rect>? = null,
-            screen3: List<Rect>? = null,
-    ) = createWorkspaceHoles(screen1, screen2, screen3)
-            .let(this::setupWorkspaces)
-
-    private fun createWorkspaceHoles(
-            screen1: List<Rect>? = null,
-            screen2: List<Rect>? = null,
-            screen3: List<Rect>? = null,
-    ): List<List<Rect>> = listOfNotNull(screen1, screen2, screen3)
-
-    private fun newTask(vararg items: ItemInfo): AddWorkspaceItemsTask =
-            items.map { Pair.create(it, Any()) }
-                    .toMutableList()
-                    .let(::AddWorkspaceItemsTask)
-
-    private fun getExistingItem() = WorkspaceItemInfo()
-            .apply { intent = Intent().setComponent(ComponentName("a", "b")) }
-
-    private fun getNewItem() = WorkspaceItemInfo()
-            .apply { intent = Intent().setComponent(ComponentName("b", "b")) }
-}
-
-private data class AddedItem(
-        val itemInfo: ItemInfo,
-        val isAnimated: Boolean
-)
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index d5479fb..3eb8cf1 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -212,7 +212,7 @@
         try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
                 "want to get overview actions")) {
             verifyActiveContainer();
-            UiObject2 overviewActions = mLauncher.waitForLauncherObject("action_buttons");
+            UiObject2 overviewActions = mLauncher.waitForOverviewObject("action_buttons");
             return new OverviewActions(overviewActions, mLauncher);
         }
     }
@@ -224,19 +224,16 @@
         return mLauncher.hasLauncherObject(mLauncher.getOverviewObjectSelector("clear_all"));
     }
 
-    /* TODO(b/197630182): Once b/188790554 is fixed, remove instanceof check. Currently, when
-        swiping from app to overview in Fallback Recents, taskbar remains and no action buttons
-        are visible, so we are only testing Overview for now, not BaseOverview. */
     private void verifyActionsViewVisibility() {
-        if (!(this instanceof Overview) || !hasTasks()) {
+        if (!hasTasks()) {
             return;
         }
         try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
                 "want to assert overview actions view visibility")) {
             if (mLauncher.isTablet() && !isOverviewSnappedToFocusedTaskForTablet()) {
-                mLauncher.waitUntilLauncherObjectGone("action_buttons");
+                mLauncher.waitUntilOverviewObjectGone("action_buttons");
             } else {
-                mLauncher.waitForLauncherObject("action_buttons");
+                mLauncher.waitForOverviewObject("action_buttons");
             }
         }
     }
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 3485dd1..91b1bc7 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1029,6 +1029,10 @@
         waitUntilGoneBySelector(getLauncherObjectSelector(resId));
     }
 
+    void waitUntilOverviewObjectGone(String resId) {
+        waitUntilGoneBySelector(getOverviewObjectSelector(resId));
+    }
+
     void waitUntilLauncherObjectGone(BySelector selector) {
         waitUntilGoneBySelector(makeLauncherSelector(selector));
     }