Merge "Disable slow recents animation handling" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 27a895c..5e325fb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -529,26 +529,52 @@
 
     /**
      * Creates {@link WindowManager.LayoutParams} for Taskbar, and also sets LP.paramsForRotation
-     * for taskbar
+     * for taskbar showing as navigation bar
      */
     private WindowManager.LayoutParams createAllWindowParams() {
         final int windowType =
                 ENABLE_TASKBAR_NAVBAR_UNIFICATION ? TYPE_NAVIGATION_BAR : TYPE_NAVIGATION_BAR_PANEL;
         WindowManager.LayoutParams windowLayoutParams =
                 createDefaultWindowLayoutParams(windowType, TaskbarActivityContext.WINDOW_TITLE);
+        if (!isPhoneButtonNavMode()) {
+            return windowLayoutParams;
+        }
 
+        // Provide WM layout params for all rotations to cache, see NavigationBar#getBarLayoutParams
+        int width = WindowManager.LayoutParams.MATCH_PARENT;
+        int height = WindowManager.LayoutParams.MATCH_PARENT;
+        int gravity = Gravity.BOTTOM;
         windowLayoutParams.paramsForRotation = new WindowManager.LayoutParams[4];
         for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
             WindowManager.LayoutParams lp =
                     createDefaultWindowLayoutParams(windowType,
                             TaskbarActivityContext.WINDOW_TITLE);
-            if (isPhoneButtonNavMode()) {
-                populatePhoneButtonNavModeWindowLayoutParams(rot, lp);
+            switch (rot) {
+                case Surface.ROTATION_0, Surface.ROTATION_180 -> {
+                    // Defaults are fine
+                    width = WindowManager.LayoutParams.MATCH_PARENT;
+                    height = mLastRequestedNonFullscreenSize;
+                    gravity = Gravity.BOTTOM;
+                }
+                case Surface.ROTATION_90 -> {
+                    width = mLastRequestedNonFullscreenSize;
+                    height = WindowManager.LayoutParams.MATCH_PARENT;
+                    gravity = Gravity.END;
+                }
+                case Surface.ROTATION_270 -> {
+                    width = mLastRequestedNonFullscreenSize;
+                    height = WindowManager.LayoutParams.MATCH_PARENT;
+                    gravity = Gravity.START;
+                }
+
             }
+            lp.width = width;
+            lp.height = height;
+            lp.gravity = gravity;
             windowLayoutParams.paramsForRotation[rot] = lp;
         }
 
-        // Override with current layout params
+        // Override current layout params
         WindowManager.LayoutParams currentParams =
                 windowLayoutParams.paramsForRotation[getDisplay().getRotation()];
         windowLayoutParams.width = currentParams.width;
@@ -558,32 +584,6 @@
         return windowLayoutParams;
     }
 
-    /**
-     * Update {@link WindowManager.LayoutParams} with values specific to phone and 3 button
-     * navigation users
-     */
-    private void populatePhoneButtonNavModeWindowLayoutParams(int rot,
-            WindowManager.LayoutParams lp) {
-        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
-        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
-        lp.gravity = Gravity.BOTTOM;
-
-        // Override with per-rotation specific values
-        switch (rot) {
-            case Surface.ROTATION_0, Surface.ROTATION_180 -> {
-                lp.height = mLastRequestedNonFullscreenSize;
-            }
-            case Surface.ROTATION_90 -> {
-                lp.width = mLastRequestedNonFullscreenSize;
-                lp.gravity = Gravity.END;
-            }
-            case Surface.ROTATION_270 -> {
-                lp.width = mLastRequestedNonFullscreenSize;
-                lp.gravity = Gravity.START;
-            }
-        }
-    }
-
     public void onConfigurationChanged(@Config int configChanges) {
         mControllers.onConfigurationChanged(configChanges);
         if (!mIsUserSetupComplete) {
@@ -944,10 +944,8 @@
         }
         if (landscapePhoneButtonNav) {
             mWindowLayoutParams.width = size;
-            mWindowLayoutParams.paramsForRotation[getDisplay().getRotation()].width = size;
         } else {
             mWindowLayoutParams.height = size;
-            mWindowLayoutParams.paramsForRotation[getDisplay().getRotation()].height = size;
         }
         mControllers.taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged();
         notifyUpdateLayoutParams();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 567fad0..aa457ca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -118,9 +118,11 @@
                 getProvidedInsets(insetsRoundedCornerFlag)
             }
 
-        if (windowLayoutParams.paramsForRotation != null) {
-            for (layoutParams in windowLayoutParams.paramsForRotation) {
-                layoutParams.providedInsets = getProvidedInsets(insetsRoundedCornerFlag)
+        if (!context.isGestureNav) {
+            if (windowLayoutParams.paramsForRotation != null) {
+                for (layoutParams in windowLayoutParams.paramsForRotation) {
+                    layoutParams.providedInsets = getProvidedInsets(insetsRoundedCornerFlag)
+                }
             }
         }
 
@@ -154,12 +156,19 @@
             )
         }
 
+        val gravity = windowLayoutParams.gravity
+
         // Pre-calculate insets for different providers across different rotations for this gravity
         for (rotation in Surface.ROTATION_0..Surface.ROTATION_270) {
             // Add insets for navbar rotated params
-            val layoutParams = windowLayoutParams.paramsForRotation[rotation]
-            for (provider in layoutParams.providedInsets) {
-                setProviderInsets(provider, layoutParams.gravity, rotation)
+            if (windowLayoutParams.paramsForRotation != null) {
+                val layoutParams = windowLayoutParams.paramsForRotation[rotation]
+                for (provider in layoutParams.providedInsets) {
+                    setProviderInsets(provider, layoutParams.gravity, rotation)
+                }
+            }
+            for (provider in windowLayoutParams.providedInsets) {
+                setProviderInsets(provider, gravity, rotation)
             }
         }
         context.notifyUpdateLayoutParams()
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 36bdad4..62ce341 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -328,11 +328,15 @@
 
             // No "save app pair" menu item if:
             // - app pairs feature is not enabled
+            // - we are in 3p launcher
             // - the task in question is a single task
             // - at least one app in app pair is unpinnable
             // - the Overview Actions Button should be visible
-            if (!FeatureFlags.enableAppPairs() || !taskView.containsMultipleTasks()
-                    || hasUnpinnableApp || shouldShowActionsButtonInstead) {
+            if (!FeatureFlags.enableAppPairs()
+                    || !recentsView.supportsAppPairs()
+                    || !taskView.containsMultipleTasks()
+                    || hasUnpinnableApp
+                    || shouldShowActionsButtonInstead) {
                 return null;
             }
 
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 0ee50a4..32d8be9 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -302,4 +302,10 @@
     protected boolean canLaunchFullscreenTask() {
         return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
     }
+
+    /** Returns if app pairs are supported in this launcher. */
+    @Override
+    public boolean supportsAppPairs() {
+        return false;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 7a1c49a..e0091a5 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -106,6 +106,7 @@
     public @interface AppPairButtonHiddenFlags { }
     public static final int FLAG_SINGLE_TASK_HIDE_APP_PAIR = 1 << 0;
     public static final int FLAG_SMALL_SCREEN_HIDE_APP_PAIR = 1 << 1;
+    public static final int FLAG_3P_LAUNCHER_HIDE_APP_PAIR = 1 << 2;
 
     private MultiValueAlpha mMultiValueAlpha;
 
@@ -255,6 +256,13 @@
     }
 
     /**
+     * Updates flags to hide and show actions buttons for 1p/3p launchers.
+     */
+    public void updateFor3pLauncher(boolean is3pLauncher) {
+        updateAppPairButtonHiddenFlags(FLAG_3P_LAUNCHER_HIDE_APP_PAIR, is3pLauncher);
+    }
+
+    /**
      * Updates the proper flags to indicate whether the "Screenshot" button should be hidden.
      *
      * @param flag   The flag to update.
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 2cbeb31..760d84b 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -4022,6 +4022,8 @@
         mActionsView.updateForGroupedTask(isCurrentSplit);
         // Update flags to see if actions bar should show buttons for tablets or phones.
         mActionsView.updateForSmallScreen(!mActivity.getDeviceProfile().isTablet);
+        // Update flags for 1p/3p launchers
+        mActionsView.updateFor3pLauncher(!supportsAppPairs());
 
         if (isDesktopModeSupported()) {
             boolean isCurrentDesktop = getCurrentPageTaskView() instanceof DesktopTaskView;
@@ -4029,6 +4031,11 @@
         }
     }
 
+    /** Returns if app pairs are supported in this launcher. Overridden in subclasses. */
+    public boolean supportsAppPairs() {
+        return true;
+    }
+
     /**
      * Returns all the tasks in the top row, without the focused task
      */
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 213f58f..077ca60 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -76,17 +76,21 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.model.Statement;
 
+import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class FallbackRecentsTest {
 
     private static final String FALLBACK_LAUNCHER_TITLE = "Test launcher";
+    private static final Pattern COMPONENT_INFO_REGEX = Pattern.compile("ComponentInfo\\{(.*)\\}");
 
     private final UiDevice mDevice;
     private final LauncherInstrumentation mLauncher;
@@ -253,7 +257,7 @@
     //@NavigationModeSwitch
     @Test
     @ScreenRecordRule.ScreenRecord // b/321775748
-    public void testOverview() {
+    public void testOverview() throws IOException {
         startAppFast(getAppPackageName());
         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
         startTestActivity(2);
@@ -261,7 +265,10 @@
         Wait.atMost("Expected three apps in the task list",
                 () -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
 
+        checkTestLauncher();
         BaseOverview overview = mLauncher.getLaunchedAppState().switchToOverview();
+        checkTestLauncher();
+
         executeOnRecents(recents -> {
             assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3);
         });
@@ -303,6 +310,17 @@
                 mOtherLauncherActivity.packageName).text(FALLBACK_LAUNCHER_TITLE)), WAIT_TIME_MS));
     }
 
+    private void checkTestLauncher() throws IOException {
+        final Matcher matcher = COMPONENT_INFO_REGEX.matcher(
+                mDevice.executeShellCommand("cmd shortcut get-default-launcher"));
+        assertTrue("Incorrect output from get-default-launcher", matcher.find());
+        assertEquals("Current Launcher activity is incorrect",
+                "com.google.android.apps.nexuslauncher.tests/com.android"
+                        + ".launcher3.testcomponent.TestLauncherActivity",
+                matcher.group(1)
+        );
+    }
+
     private int getCurrentOverviewPage(RecentsActivity recents) {
         return recents.<RecentsView>getOverviewPanel().getCurrentPage();
     }
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 4f071fe..a9cf2ff 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -916,7 +916,8 @@
     /** Applies the given progress level to the this icon's progress bar. */
     @Nullable
     public PreloadIconDrawable applyProgressLevel() {
-        if (!(getTag() instanceof ItemInfoWithIcon)) {
+        if (!(getTag() instanceof ItemInfoWithIcon)
+                || !((ItemInfoWithIcon) getTag()).isActiveArchive()) {
             return null;
         }
 
@@ -973,6 +974,7 @@
         return info.isDisabled() || info.isPendingDownload();
     }
 
+
     public void applyDotState(ItemInfo itemInfo, boolean animate) {
         if (mIcon instanceof FastBitmapDrawable) {
             boolean wasDotted = mDotInfo != null;
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index 352c363..70cad96 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -160,10 +160,6 @@
      * and its install session is active
      */
     public boolean isPendingDownload() {
-        if (isArchived()) {
-            return this.getProgressLevel() == 0
-                    && (this.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0;
-        }
         return getProgressLevel() == 0;
     }
 
@@ -177,6 +173,11 @@
         return (runtimeStatusFlags & FLAG_ARCHIVED) != 0;
     }
 
+    /** Returns true if the app is archived and has an active install session. */
+    public boolean isActiveArchive() {
+        return isArchived() && (runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0;
+    }
+
     /**
      * Indicates whether we're using a low res icon
      */
diff --git a/tests/Android.bp b/tests/Android.bp
index e9111ea..24ae158 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -177,7 +177,7 @@
     name: "launcher-testing-shared",
     srcs: [
         "multivalentTests/shared/com/android/launcher3/testing/shared/**/*.java",
-        "multivalentTests/shared/com/android/launcher3/testing/shared/**/*.kt"
+        "multivalentTests/shared/com/android/launcher3/testing/shared/**/*.kt",
     ],
     resource_dirs: [],
     manifest: "multivalentTests/shared/AndroidManifest.xml",
@@ -225,8 +225,8 @@
     // multivalentTests directory is a shared folder for not only robolectric converted test
     // classes but also shared helper classes.
     srcs: [
-        "multivalentTests/src/com/android/launcher3/util/*.java",
-        "multivalentTests/src/com/android/launcher3/util/*.kt",
+        "multivalentTests/src/**/*.java",
+        "multivalentTests/src/**/*.kt",
 
         // Test util classes
         ":launcher-testing-helpers",
@@ -246,7 +246,8 @@
         "androidx.test.uiautomator_uiautomator",
         "androidx.core_core-animation-testing",
         "androidx.test.ext.junit",
-        "inline-mockito-robolectric-prebuilt",
+        "mockito-robolectric-prebuilt",
+        "mockito-kotlin2",
         "platform-parametric-runner-lib",
         "testables",
         "Launcher3TestResources",