Fix bug where app icons stay invisible after app open animation.

For the app open animation, we load the adaptive icon on the bg thread.
When the icon is done loading, we swap the og view with the FloatingIconView.
If the icon loads after the animation is done, we still set the og view
to INVISIBLE and it never gets restored since the animation is already done.
To fix this, we do not swap the views if the animation has already ended.

Bug: 130245920
Change-Id: I5cf85de4e2c533da8c395a23899980d27a941e1b
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 5889468..fab21fa 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -34,6 +34,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.Looper;
 import android.view.View;
@@ -73,6 +74,7 @@
     private static final Rect sTmpRect = new Rect();
 
     private Runnable mEndRunnable;
+    private CancellationSignal mLoadIconSignal;
 
     private final int mBlurSizeOutline;
 
@@ -153,6 +155,9 @@
 
     @Override
     public void onAnimationEnd(Animator animator) {
+        if (mLoadIconSignal != null) {
+            mLoadIconSignal.cancel();
+        }
         if (mEndRunnable != null) {
             mEndRunnable.run();
         } else {
@@ -186,7 +191,7 @@
 
     @WorkerThread
     private void getIcon(Launcher launcher, View v, ItemInfo info, boolean isOpening,
-            Runnable onIconLoadedRunnable) {
+            Runnable onIconLoadedRunnable, CancellationSignal loadIconSignal) {
         final LayoutParams lp = (LayoutParams) getLayoutParams();
         Drawable drawable = null;
         boolean supportsAdaptiveIcons = ADAPTIVE_ICON_WINDOW_ANIM.get()
@@ -290,7 +295,9 @@
                 setBackground(finalDrawable);
             }
 
-            onIconLoadedRunnable.run();
+            if (!loadIconSignal.isCanceled()) {
+                onIconLoadedRunnable.run();
+            }
             invalidate();
             invalidateOutline();
         });
@@ -386,6 +393,7 @@
         // Get the drawable on the background thread
         // Must be called after matchPositionOf so that we know what size to load.
         if (originalView.getTag() instanceof ItemInfo) {
+            view.mLoadIconSignal = new CancellationSignal();
             Runnable onIconLoaded = () -> {
                 // Delay swapping views until the icon is loaded to prevent a flash.
                 view.setVisibility(VISIBLE);
@@ -393,9 +401,10 @@
                     originalView.setVisibility(INVISIBLE);
                 }
             };
+            CancellationSignal loadIconSignal = view.mLoadIconSignal;
             new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(() -> {
                 view.getIcon(launcher, originalView, (ItemInfo) originalView.getTag(), isOpening,
-                        onIconLoaded);
+                        onIconLoaded, loadIconSignal);
             });
         }
 
@@ -461,6 +470,10 @@
         setScaleY(1);
         setAlpha(1);
         setBackground(null);
+        if (mLoadIconSignal != null) {
+            mLoadIconSignal.cancel();
+        }
+        mLoadIconSignal = null;
         mEndRunnable = null;
         mIsAdaptiveIcon = false;
         mForeground = null;