Update FloatingIconView to display PreloadIconDrawables during swipe home animations.

Swiping up to go home on an app that is downloading incrementally would cause a jittery animation. Updated FloatingIconView to animate directly to a PreloadIconDrawable.

Demo: https://drive.google.com/file/d/1ddr8OGR4c1ZneyQ0VkkAAxGpwNcP8Wyn/view?usp=sharing

Fixes: 177685929

Test: manual
Change-Id: I4cd2daa18f6d3fed42a9b666063e0b1c1c46e5d9
(cherry picked from commit b8cab8d8786a7de6adfcd5b77af9408e832ed0c2)
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 22eb15a..575d6cd 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -301,7 +301,7 @@
         verifyHighRes();
 
         if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK) != 0) {
-            applyProgressLevel(info.getProgressLevel());
+            applyProgressLevel();
         }
         applyDotState(info, false /* animate */);
     }
@@ -603,21 +603,20 @@
      * with the total download progress.
      */
     public void applyLoadingState(boolean promiseStateChanged) {
-        if (getTag() instanceof WorkspaceItemInfo) {
+        if (getTag() instanceof ItemInfoWithIcon) {
             WorkspaceItemInfo info = (WorkspaceItemInfo) getTag();
-            int progressLevel = info.getProgressLevel();
             if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_INCREMENTAL_DOWNLOAD_ACTIVE)
                     != 0) {
-                updateProgressBarUi(progressLevel, progressLevel == 100);
+                updateProgressBarUi(info.getProgressLevel() == 100);
             } else if (info.hasPromiseIconUi() || (info.runtimeStatusFlags
-                    & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
-                updateProgressBarUi(progressLevel, promiseStateChanged);
+                        & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
+                updateProgressBarUi(promiseStateChanged);
             }
         }
     }
 
-    private void updateProgressBarUi(int progressLevel, boolean maybePerformFinishedAnimation) {
-        PreloadIconDrawable preloadDrawable = applyProgressLevel(progressLevel);
+    private void updateProgressBarUi(boolean maybePerformFinishedAnimation) {
+        PreloadIconDrawable preloadDrawable = applyProgressLevel();
         if (preloadDrawable != null && maybePerformFinishedAnimation) {
             preloadDrawable.maybePerformFinishedAnimation();
         }
@@ -625,38 +624,59 @@
 
     /** Applies the given progress level to the this icon's progress bar. */
     @Nullable
-    public PreloadIconDrawable applyProgressLevel(int progressLevel) {
-        if (getTag() instanceof ItemInfoWithIcon) {
-            ItemInfoWithIcon info = (ItemInfoWithIcon) getTag();
-            if (progressLevel >= 100) {
-                setContentDescription(info.contentDescription != null
-                        ? info.contentDescription : "");
-            } else if (progressLevel > 0) {
-                setContentDescription(getContext()
-                        .getString(R.string.app_downloading_title, info.title,
-                                NumberFormat.getPercentInstance().format(progressLevel * 0.01)));
+    public PreloadIconDrawable applyProgressLevel() {
+        if (!(getTag() instanceof ItemInfoWithIcon)) {
+            return null;
+        }
+
+        ItemInfoWithIcon info = (ItemInfoWithIcon) getTag();
+        int progressLevel = info.getProgressLevel();
+        if (progressLevel >= 100) {
+            setContentDescription(info.contentDescription != null
+                    ? info.contentDescription : "");
+        } else if (progressLevel > 0) {
+            setContentDescription(getContext()
+                    .getString(R.string.app_downloading_title, info.title,
+                            NumberFormat.getPercentInstance().format(progressLevel * 0.01)));
+        } else {
+            setContentDescription(getContext()
+                    .getString(R.string.app_waiting_download_title, info.title));
+        }
+        if (mIcon != null) {
+            PreloadIconDrawable preloadIconDrawable;
+            if (mIcon instanceof PreloadIconDrawable) {
+                preloadIconDrawable = (PreloadIconDrawable) mIcon;
+                preloadIconDrawable.setLevel(progressLevel);
+                preloadIconDrawable.setIsDisabled(!info.isAppStartable());
             } else {
-                setContentDescription(getContext()
-                        .getString(R.string.app_waiting_download_title, info.title));
+                preloadIconDrawable = makePreloadIcon();
+                setIcon(preloadIconDrawable);
             }
-            if (mIcon != null) {
-                final PreloadIconDrawable preloadDrawable;
-                if (mIcon instanceof PreloadIconDrawable) {
-                    preloadDrawable = (PreloadIconDrawable) mIcon;
-                    preloadDrawable.setLevel(progressLevel);
-                    preloadDrawable.setIsDisabled(!info.isAppStartable());
-                } else {
-                    preloadDrawable = newPendingIcon(getContext(), info);
-                    preloadDrawable.setLevel(progressLevel);
-                    preloadDrawable.setIsDisabled(!info.isAppStartable());
-                    setIcon(preloadDrawable);
-                }
-                return preloadDrawable;
-            }
+            return preloadIconDrawable;
         }
         return null;
     }
 
+    /**
+     * Creates a PreloadIconDrawable with the appropriate progress level without mutating this
+     * object.
+     */
+    @Nullable
+    public PreloadIconDrawable makePreloadIcon() {
+        if (!(getTag() instanceof ItemInfoWithIcon)) {
+            return null;
+        }
+
+        ItemInfoWithIcon info = (ItemInfoWithIcon) getTag();
+        int progressLevel = info.getProgressLevel();
+        final PreloadIconDrawable preloadDrawable = newPendingIcon(getContext(), info);
+
+        preloadDrawable.setLevel(progressLevel);
+        preloadDrawable.setIsDisabled(!info.isAppStartable());
+
+        return preloadDrawable;
+    }
+
     public void applyDotState(ItemInfo itemInfo, boolean animate) {
         if (mIcon instanceof FastBitmapDrawable) {
             boolean wasDotted = mDotInfo != null;