Move overview actions to task menu when no focused task.

Bug: 265641913
Test: manual
Change-Id: I03a88275b399940468246a69365f76f7deda724e
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index d40f2ae..0dcd723 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -36,6 +36,7 @@
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.SystemShortcut;
@@ -77,9 +78,11 @@
         RecentsOrientedState orientedState = taskView.getRecentsView().getPagedViewOrientedState();
         boolean canLauncherRotate = orientedState.isRecentsActivityRotationAllowed();
         boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0;
+        boolean isTablet = activity.getDeviceProfile().isTablet;
 
         // Add overview actions to the menu when in in-place rotate landscape mode.
-        if (!canLauncherRotate && isInLandscape) {
+        if ((!canLauncherRotate && isInLandscape)
+                || (isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get())) {
             // Add screenshot action to task menu.
             List<SystemShortcut> screenshotShortcuts = TaskShortcutFactory.SCREENSHOT
                     .getShortcuts(activity, taskContainer);
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index eeabdc8..0d21e60 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -55,7 +55,8 @@
             HIDDEN_NO_TASKS,
             HIDDEN_NO_RECENTS,
             HIDDEN_SPLIT_SCREEN,
-            HIDDEN_SPLIT_SELECT_ACTIVE
+            HIDDEN_SPLIT_SELECT_ACTIVE,
+            HIDDEN_ACTIONS_IN_MENU
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ActionsHiddenFlags { }
@@ -65,6 +66,7 @@
     public static final int HIDDEN_NO_RECENTS = 1 << 2;
     public static final int HIDDEN_SPLIT_SCREEN = 1 << 3;
     public static final int HIDDEN_SPLIT_SELECT_ACTIVE = 1 << 4;
+    public static final int HIDDEN_ACTIONS_IN_MENU = 1 << 5;
 
     @IntDef(flag = true, value = {
             DISABLED_SCROLLING,
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 8facb0a..61d6179 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -42,6 +42,7 @@
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_75;
 import static com.android.launcher3.anim.Interpolators.clampToProgress;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCH_FROM_STAGED_APP;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT;
@@ -60,6 +61,7 @@
 import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED;
 import static com.android.quickstep.views.OverviewActionsView.FLAG_IS_NOT_TABLET;
 import static com.android.quickstep.views.OverviewActionsView.FLAG_SINGLE_TASK;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_ACTIONS_IN_MENU;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
@@ -1864,6 +1866,9 @@
         DeviceProfile dp = mActivity.getDeviceProfile();
         setOverviewGridEnabled(
                 mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
+        if (ENABLE_GRID_ONLY_OVERVIEW.get()) {
+            mActionsView.updateHiddenFlags(HIDDEN_ACTIONS_IN_MENU, dp.isTablet);
+        }
         setPageSpacing(dp.overviewPageSpacing);
 
         // Propagate DeviceProfile change event.
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
index 54b58b9..0da70a9 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
@@ -46,7 +46,7 @@
 
         fun showForTask(
             taskContainer: TaskIdAttributeContainer,
-            alignSecondRow: Boolean = false
+            alignedOptionIndex: Int = 0
         ): Boolean {
             val activity =
                 BaseDraggingActivity.fromContext<BaseDraggingActivity>(
@@ -59,7 +59,7 @@
                     false
                 ) as TaskMenuViewWithArrow<*>
 
-            return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow)
+            return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignedOptionIndex)
         }
     }
 
@@ -82,9 +82,9 @@
         CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION
     }
 
-    private var alignSecondRow: Boolean = false
-    private val extraSpaceForSecondRowAlignment: Int
-        get() = if (alignSecondRow) optionMeasuredHeight else 0
+    private var alignedOptionIndex: Int = 0
+    private val extraSpaceForRowAlignment: Int
+        get() = optionMeasuredHeight * alignedOptionIndex
     private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid)
 
     private lateinit var taskView: TaskView
@@ -125,7 +125,7 @@
 
     private fun populateAndShowForTask(
         taskContainer: TaskIdAttributeContainer,
-        alignSecondRow: Boolean
+        alignedOptionIndex: Int
     ): Boolean {
         if (isAttachedToWindow) {
             return false
@@ -133,7 +133,7 @@
 
         taskView = taskContainer.taskView
         this.taskContainer = taskContainer
-        this.alignSecondRow = alignSecondRow
+        this.alignedOptionIndex = alignedOptionIndex
         if (!populateMenu()) return false
         addScrim()
         show()
@@ -257,8 +257,7 @@
     }
 
     /**
-     * Orients this container to the left or right of the given icon, aligning with the first option
-     * or second.
+     * Orients this container to the left or right of the given icon, aligning with the desired row.
      *
      * These are the preferred orientations, in order (RTL prefers right-aligned over left):
      * - Right and first option aligned
@@ -298,7 +297,7 @@
         // Offset y so that the arrow and row are center-aligned with the original icon.
         val iconHeight = mTempRect.height()
         val yOffset = (optionMeasuredHeight - iconHeight) / 2
-        var menuStartY = mTempRect.top - yOffset - extraSpaceForSecondRowAlignment
+        var menuStartY = mTempRect.top - yOffset - extraSpaceForRowAlignment
 
         // Insets are added later, so subtract them now.
         menuStartX -= insets.left
@@ -316,8 +315,7 @@
     override fun addArrow() {
         popupContainer.addView(mArrow)
         mArrow.x = getArrowX()
-        mArrow.y =
-            y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + extraSpaceForSecondRowAlignment
+        mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + extraSpaceForRowAlignment
 
         updateArrowColor()
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index aa37fdd..e53c4c8 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -71,6 +71,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.statemanager.StatefulActivity;
@@ -940,10 +941,20 @@
     protected boolean showTaskMenuWithContainer(IconView iconView) {
         TaskIdAttributeContainer menuContainer =
                 mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1];
-        if (mActivity.getDeviceProfile().isTablet) {
-            boolean alignSecondRow = getRecentsView().isOnGridBottomRow(menuContainer.getTaskView())
-                    && mActivity.getDeviceProfile().isLandscape;
-            return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignSecondRow);
+        DeviceProfile dp = mActivity.getDeviceProfile();
+        if (dp.isTablet) {
+            int alignedOptionIndex = 0;
+            if (getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) && dp.isLandscape) {
+                if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+                    // With no focused task, there is less available space below the tasks, so align
+                    // the arrow to the third option in the menu.
+                    alignedOptionIndex = 2;
+                } else  {
+                    // Bottom row of landscape grid aligns arrow to second option to avoid clipping
+                    alignedOptionIndex = 1;
+                }
+            }
+            return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignedOptionIndex);
         } else {
             return TaskMenuView.showForTask(menuContainer);
         }
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 9f9c6f9..262ccef 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -1406,8 +1406,10 @@
 
     /** Gets the space that the overview actions will take, including bottom margin. */
     public int getOverviewActionsClaimedSpace() {
-        return overviewActionsTopMarginPx + overviewActionsHeight
-                + getOverviewActionsClaimedSpaceBelow();
+        int overviewActionsSpace = isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()
+                ? 0
+                : (overviewActionsTopMarginPx + overviewActionsHeight);
+        return overviewActionsSpace + getOverviewActionsClaimedSpaceBelow();
     }
 
     /**
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 16be597..4f4e65c 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -394,6 +394,10 @@
             "Enables taskbar pinning to allow user to switch between transient and persistent "
                     + "taskbar flavors");
 
+    public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(
+            "ENABLE_GRID_ONLY_OVERVIEW", false,
+            "Enable a grid-only overview without a focused task.");
+
     public static void initialize(Context context) {
         synchronized (sDebugFlags) {
             for (DebugFlag flag : sDebugFlags) {