Merge "Change preload icon size to always be 0.7 scale when downloading" into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index df867cb..474dc3d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -73,12 +73,12 @@
         boolean useStashedLauncherState = toState.hasOverviewActions();
         boolean stashedLauncherState =
                 useStashedLauncherState && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get();
-        TaskbarStashController controller = mControllers.taskbarStashController;
+        TaskbarStashController stashController = mControllers.taskbarStashController;
         // Set both FLAG_IN_STASHED_LAUNCHER_STATE and FLAG_IN_APP to ensure the state is respected.
         // For all other states, just use the current stashed-in-app setting (e.g. if long clicked).
-        controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, stashedLauncherState);
-        controller.updateStateForFlag(FLAG_IN_APP, !useStashedLauncherState);
-        return controller.applyStateWithoutStart(duration);
+        stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, stashedLauncherState);
+        stashController.updateStateForFlag(FLAG_IN_APP, !useStashedLauncherState);
+        return stashController.createApplyStateAnimator(duration);
     }
 
     private void animateToRecentsState(RecentsState toState) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index a18aabe..237661e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -26,7 +26,6 @@
 import android.annotation.ColorInt;
 import android.os.RemoteException;
 import android.util.Log;
-import android.util.SparseArray;
 import android.view.TaskTransitionSpec;
 import android.view.WindowManagerGlobal;
 
@@ -45,13 +44,13 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.MultiPropertyFactory;
 import com.android.launcher3.util.OnboardingPrefs;
 import com.android.quickstep.RecentsAnimationCallbacks;
 import com.android.quickstep.views.RecentsView;
 
 import java.io.PrintWriter;
 import java.util.Set;
-import java.util.stream.Stream;
 
 /**
  * A data source which integrates with a Launcher instance
@@ -65,7 +64,12 @@
     public static final int WIDGETS_PAGE_PROGRESS_INDEX = 2;
     public static final int SYSUI_SURFACE_PROGRESS_INDEX = 3;
 
-    private final SparseArray<Float> mTaskbarInAppDisplayProgress = new SparseArray<>(4);
+    private static final int DISPLAY_PROGRESS_COUNT = 4;
+
+    private final AnimatedFloat mTaskbarInAppDisplayProgress = new AnimatedFloat();
+    private final MultiPropertyFactory<AnimatedFloat> mTaskbarInAppDisplayProgressMultiProp =
+            new MultiPropertyFactory<>(mTaskbarInAppDisplayProgress,
+                    AnimatedFloat.VALUE, DISPLAY_PROGRESS_COUNT, Float::max);
 
     private final QuickstepLauncher mLauncher;
 
@@ -305,11 +309,11 @@
      *                 1 => use in-app layout
      */
     public void onTaskbarInAppDisplayProgressUpdate(float progress, int progressIndex) {
+        mTaskbarInAppDisplayProgressMultiProp.get(progressIndex).setValue(progress);
         if (mControllers == null) {
             // This method can be called before init() is called.
             return;
         }
-        mTaskbarInAppDisplayProgress.put(progressIndex, progress);
         if (mControllers.uiController.isIconAlignedWithHotseat()
                 && !mTaskbarLauncherStateController.isAnimatingToLauncher()) {
             // Only animate the nav buttons while home and not animating home, otherwise let
@@ -317,30 +321,13 @@
             mControllers.navbarButtonsViewController
                     .getTaskbarNavButtonTranslationYForInAppDisplay()
                     .updateValue(mLauncher.getDeviceProfile().getTaskbarOffsetY()
-                            * getInAppDisplayProgress());
+                            * mTaskbarInAppDisplayProgress.value);
         }
     }
 
     /** Returns true iff any in-app display progress > 0. */
     public boolean shouldUseInAppLayout() {
-        return getInAppDisplayProgress() > 0;
-    }
-
-    private float getInAppDisplayProgress(int index) {
-        if (!mTaskbarInAppDisplayProgress.contains(index)) {
-            mTaskbarInAppDisplayProgress.put(index, 0f);
-        }
-        return mTaskbarInAppDisplayProgress.get(index);
-    }
-
-    private float getInAppDisplayProgress() {
-        return Stream.of(
-                getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX),
-                getInAppDisplayProgress(ALL_APPS_PAGE_PROGRESS_INDEX),
-                getInAppDisplayProgress(WIDGETS_PAGE_PROGRESS_INDEX),
-                getInAppDisplayProgress(SYSUI_SURFACE_PROGRESS_INDEX))
-                .max(Float::compareTo)
-                .get();
+        return mTaskbarInAppDisplayProgress.value > 0;
     }
 
     @Override
@@ -358,7 +345,8 @@
     @Override
     public boolean isHotseatIconOnTopWhenAligned() {
         return mTaskbarLauncherStateController.isInHotseatOnTopStates()
-                && getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX) == 0;
+                && mTaskbarInAppDisplayProgressMultiProp.get(MINUS_ONE_PAGE_PROGRESS_INDEX)
+                    .getValue() == 0;
     }
 
     @Override
@@ -369,28 +357,15 @@
                 "%s\tmTaskbarOverrideBackgroundAlpha=%.2f",
                 prefix,
                 mTaskbarOverrideBackgroundAlpha.value));
-
         pw.println(String.format("%s\tTaskbar in-app display progress:", prefix));
-        if (mControllers == null) {
-            pw.println(String.format("%s\t\tMissing mControllers", prefix));
-        } else {
-            pw.println(String.format(
-                    "%s\t\tprogress at MINUS_ONE_PAGE_PROGRESS_INDEX=%.2f",
-                    prefix,
-                    getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX)));
-            pw.println(String.format(
-                    "%s\t\tprogress at ALL_APPS_PAGE_PROGRESS_INDEX=%.2f",
-                    prefix,
-                    getInAppDisplayProgress(ALL_APPS_PAGE_PROGRESS_INDEX)));
-            pw.println(String.format(
-                    "%s\t\tprogress at WIDGETS_PAGE_PROGRESS_INDEX=%.2f",
-                    prefix,
-                    getInAppDisplayProgress(WIDGETS_PAGE_PROGRESS_INDEX)));
-            pw.println(String.format(
-                    "%s\t\tprogress at SYSUI_SURFACE_PROGRESS_INDEX=%.2f",
-                    prefix,
-                    getInAppDisplayProgress(SYSUI_SURFACE_PROGRESS_INDEX)));
-        }
+        mTaskbarInAppDisplayProgressMultiProp.dump(
+                prefix + "\t",
+                pw,
+                "mTaskbarInAppDisplayProgressMultiProp",
+                "MINUS_ONE_PAGE_PROGRESS_INDEX",
+                "ALL_APPS_PAGE_PROGRESS_INDEX",
+                "WIDGETS_PAGE_PROGRESS_INDEX",
+                "SYSUI_SURFACE_PROGRESS_INDEX");
 
         mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw);
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 4ad3858..e3e84cf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -183,7 +183,7 @@
         stashController.updateStateForFlag(FLAG_IN_APP, false);
 
         updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true);
-        animatorSet.play(stashController.applyStateWithoutStart(duration));
+        animatorSet.play(stashController.createApplyStateAnimator(duration));
         animatorSet.play(applyState(duration, false));
 
         if (mTaskBarRecentsAnimationListener != null) {
@@ -397,7 +397,7 @@
         boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher);
         TaskbarStashController stashController = mControllers.taskbarStashController;
         stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, isInStashedState);
-        Animator stashAnimator = stashController.applyStateWithoutStart(duration);
+        Animator stashAnimator = stashController.createApplyStateAnimator(duration);
         if (stashAnimator != null) {
             stashAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 6031b49..61d169f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -35,6 +35,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
 import android.annotation.Nullable;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
@@ -69,8 +70,6 @@
  */
 public class TaskbarStashController implements TaskbarControllers.LoggableTaskbarController {
 
-    private static final String TAG = "TaskbarStashController";
-
     public static final int FLAG_IN_APP = 1 << 0;
     public static final int FLAG_STASHED_IN_APP_MANUAL = 1 << 1; // long press, persisted
     public static final int FLAG_STASHED_IN_SYSUI_STATE = 1 << 2; // app pinning, keyguard, etc.
@@ -374,8 +373,8 @@
 
     /**
      * Returns the height that taskbar will inset when inside apps.
-     * @see WindowInsets.Type#navigationBars()
-     * @see WindowInsets.Type#systemBars()
+     * @see android.view.WindowInsets.Type#navigationBars()
+     * @see android.view.WindowInsets.Type#systemBars()
      */
     public int getContentHeightToReportToApps() {
         if ((isPhoneMode() && !mActivity.isThreeButtonNav())
@@ -408,7 +407,7 @@
 
     /**
      * Returns the height that taskbar will inset when inside apps.
-     * @see WindowInsets.Type#tappableElement()
+     * @see android.view.WindowInsets.Type#tappableElement()
      */
     public int getTappableHeightToReportToApps() {
         int contentHeight = getContentHeightToReportToApps();
@@ -494,7 +493,6 @@
         createAnimToIsStashed(
                 /* isStashed= */ false,
                 placeholderDuration,
-                /* startDelay= */ 0,
                 /* animateBg= */ false,
                 /* changedFlags=*/ 0);
         animation.play(mAnimator);
@@ -504,11 +502,10 @@
      * Create a stash animation and save to {@link #mAnimator}.
      * @param isStashed whether it's a stash animation or an unstash animation
      * @param duration duration of the animation
-     * @param startDelay how many milliseconds to delay the animation after starting it.
      * @param animateBg whether the taskbar's background should be animated
      */
-    private void createAnimToIsStashed(boolean isStashed, long duration, long startDelay,
-            boolean animateBg, int changedFlags) {
+    private void createAnimToIsStashed(boolean isStashed, long duration, boolean animateBg,
+            int changedFlags) {
         if (mAnimator != null) {
             mAnimator.cancel();
         }
@@ -528,13 +525,7 @@
                     .setDuration(duration));
             mAnimator.play(mTaskbarImeBgAlpha.animateToValue(
                     hasAnyFlag(FLAG_STASHED_IN_APP_IME) ? 0 : 1).setDuration(duration));
-            mAnimator.setStartDelay(startDelay);
-            mAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mAnimator = null;
-                }
-            });
+            mAnimator.addListener(AnimatorListeners.forEndCallback(() -> mAnimator = null));
             return;
         }
 
@@ -615,7 +606,6 @@
 
         mAnimator.playTogether(fullLengthAnimatorSet, firstHalfAnimatorSet,
                 secondHalfAnimatorSet);
-        mAnimator.setStartDelay(startDelay);
         mAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
@@ -701,19 +691,17 @@
     }
 
     public void applyState(long duration) {
-        mStatePropertyHolder.setState(mState, duration, true);
+        createApplyStateAnimator(duration).start();
     }
 
     public void applyState(long duration, long startDelay) {
-        mStatePropertyHolder.setState(mState, duration, startDelay, true);
+        Animator animator = createApplyStateAnimator(duration);
+        animator.setStartDelay(startDelay);
+        animator.start();
     }
 
-    public Animator applyStateWithoutStart() {
-        return applyStateWithoutStart(TASKBAR_STASH_DURATION);
-    }
-
-    public Animator applyStateWithoutStart(long duration) {
-        return mStatePropertyHolder.setState(mState, duration, false);
+    public Animator createApplyStateAnimator(long duration) {
+        return mStatePropertyHolder.createSetStateAnimator(mState, duration);
     }
 
     /**
@@ -948,22 +936,14 @@
         }
 
         /**
-         * @see #setState(int, long, long, boolean) with a default startDelay = 0.
-         */
-        public Animator setState(int flags, long duration, boolean start) {
-            return setState(flags, duration, 0 /* startDelay */, start);
-        }
-
-        /**
-         * Applies the latest state, potentially calling onStateChangeApplied() and creating a new
-         * animation (stored in mAnimator) which is started if {@param start} is true.
+         * Creates an animator (stored in mAnimator) which applies the latest state, potentially
+         * creating a new animation (stored in mAnimator).
          * @param flags The latest flags to apply (see the top of this file).
          * @param duration The length of the animation.
-         * @param startDelay How long to delay the animation after calling start().
-         * @param start Whether to start mAnimator immediately.
-         * @return mAnimator if mIsStashed changed, else null.
+         * @return mAnimator if mIsStashed changed or an empty animator.
          */
-        public Animator setState(int flags, long duration, long startDelay, boolean start) {
+        @NonNull
+        public Animator createSetStateAnimator(int flags, long duration) {
             int changedFlags = mPrevFlags ^ flags;
             if (mPrevFlags != flags) {
                 onStateChangeApplied(changedFlags);
@@ -979,24 +959,19 @@
                     && mAnimator != null && mAnimator.isStarted())) {
                 if (TestProtocol.sDebugTracing) {
                     Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format(
-                            "setState: mIsStashed=%b, isStashed=%b, duration=%d, start=:%b",
+                            "setState: mIsStashed=%b, isStashed=%b, duration=%d",
                             mIsStashed,
                             isStashed,
-                            duration,
-                            start));
+                            duration));
                 }
                 mIsStashed = isStashed;
                 mIsHotseatIconOnTopWhenAligned = isHotseatIconOnTopWhenAligned;
 
                 // This sets mAnimator.
-                createAnimToIsStashed(
-                        mIsStashed, duration, startDelay, /* animateBg= */ true, changedFlags);
-                if (start) {
-                    mAnimator.start();
-                }
+                createAnimToIsStashed(mIsStashed, duration, /* animateBg= */ true, changedFlags);
                 return mAnimator;
             }
-            return null;
+            return ValueAnimator.ofFloat(0, 1).setDuration(duration);
         }
     }
 }
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index f124940..7b540d0 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -260,6 +260,7 @@
     // Whether Taskbar will inset the bottom of apps by taskbarSize.
     public boolean isTaskbarPresentInApps;
     public int taskbarSize;
+    public int transientTaskbarSize;
     public int stashedTaskbarSize;
     public int transientTaskbarMargin;
 
@@ -324,12 +325,12 @@
         }
 
         if (isTaskbarPresent) {
+            transientTaskbarSize = res.getDimensionPixelSize(R.dimen.transient_taskbar_size);
+            transientTaskbarMargin = res.getDimensionPixelSize(R.dimen.transient_taskbar_margin);
             if (DisplayController.isTransientTaskbar(context)) {
-                taskbarSize = res.getDimensionPixelSize(R.dimen.transient_taskbar_size);
+                taskbarSize = transientTaskbarSize;
                 stashedTaskbarSize =
                         res.getDimensionPixelSize(R.dimen.transient_taskbar_stashed_size);
-                transientTaskbarMargin =
-                        res.getDimensionPixelSize(R.dimen.transient_taskbar_margin);
             } else {
                 taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
                 stashedTaskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_stashed_size);
@@ -1383,7 +1384,7 @@
     public int getOverviewActionsClaimedSpaceBelow() {
         if (isTaskbarPresent) {
             if (FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) {
-                return taskbarSize + transientTaskbarMargin * 2;
+                return transientTaskbarSize + transientTaskbarMargin * 2;
             }
 
             return isGestureMode
diff --git a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
index 16448af..7e3588b 100644
--- a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
+++ b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
@@ -120,7 +120,7 @@
      * be clean otherwise this doesn't overrides the existing icons.
      */
     public FavoriteItemsTransaction fillHotseatIcons(FavoriteItemsTransaction transaction) {
-        int hotseatCount = InvariantDeviceProfile.INSTANCE.get(mContext).numShownHotseatIcons;
+        int hotseatCount = InvariantDeviceProfile.INSTANCE.get(mContext).numDatabaseHotseatIcons;
         for (int i = 0; i < hotseatCount; i++) {
             transaction.addItem(getHotseatValues(i));
         }
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 70d122b..cf21dd7 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -299,7 +299,7 @@
     /**
      * Removes all icons from homescreen and hotseat.
      */
-    public void clearHomescreen() throws Throwable {
+    public void clearHomescreen() {
         LauncherSettings.Settings.call(mTargetContext.getContentResolver(),
                 LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
         LauncherSettings.Settings.call(mTargetContext.getContentResolver(),