Merge "Track window for 2 button nav as well as 0 button" into ub-launcher3-qt-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
index 0924f38..ced9afa 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -85,15 +85,24 @@
         }
     }
 
+    /** See {@link #finish(boolean, Runnable, boolean)} */
+    @UiThread
+    public void finish(boolean toRecents, Runnable onFinishComplete) {
+        finish(toRecents, onFinishComplete, false /* sendUserLeaveHint */);
+    }
+
     /**
      * @param onFinishComplete A callback that runs on the main thread after the animation
      *                         controller has finished on the background thread.
+     * @param sendUserLeaveHint Determines whether userLeaveHint flag will be set on the pausing
+     *                          activity. If userLeaveHint is true, the activity will enter into
+     *                          picture-in-picture mode upon being paused.
      */
     @UiThread
-    public void finish(boolean toRecents, Runnable onFinishComplete) {
+    public void finish(boolean toRecents, Runnable onFinishComplete, boolean sendUserLeaveHint) {
         Preconditions.assertUIThread();
         if (!toRecents) {
-            finishAndClear(false, onFinishComplete);
+            finishAndClear(false, onFinishComplete, sendUserLeaveHint);
         } else {
             if (mTouchInProgress) {
                 mFinishPending = true;
@@ -102,16 +111,17 @@
                     onFinishComplete.run();
                 }
             } else {
-                finishAndClear(true, onFinishComplete);
+                finishAndClear(true, onFinishComplete, sendUserLeaveHint);
             }
         }
     }
 
-    private void finishAndClear(boolean toRecents, Runnable onFinishComplete) {
+    private void finishAndClear(boolean toRecents, Runnable onFinishComplete,
+            boolean sendUserLeaveHint) {
         SwipeAnimationTargetSet controller = targetSet;
         targetSet = null;
         if (controller != null) {
-            controller.finishController(toRecents, onFinishComplete);
+            controller.finishController(toRecents, onFinishComplete, sendUserLeaveHint);
         }
     }
 
@@ -163,7 +173,7 @@
             mTouchInProgress = false;
             if (mFinishPending) {
                 mFinishPending = false;
-                finishAndClear(true /* toRecents */, null);
+                finishAndClear(true /* toRecents */, null, false /* sendUserLeaveHint */);
             }
         }
         if (mInputConsumer != null) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
index 42a28fb..6e98a5a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
@@ -290,6 +290,10 @@
             if (sysUiProxy == null) {
                 return null;
             }
+            if (SysUINavigationMode.getMode(activity) == SysUINavigationMode.Mode.NO_BUTTON) {
+                // TODO(b/130225926): Temporarily disable pinning while gesture nav is enabled
+                return null;
+            }
             if (!ActivityManagerWrapper.getInstance().isScreenPinningEnabled()) {
                 return null;
             }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index a974135..5a1d387 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -1130,7 +1130,8 @@
     private void finishCurrentTransitionToHome() {
         synchronized (mRecentsAnimationWrapper) {
             mRecentsAnimationWrapper.finish(true /* toRecents */,
-                    () -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
+                    () -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED),
+                    true /* sendUserLeaveHint */);
         }
         TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true);
         doLogGesture(HOME);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
index b682481..5a1a103 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
@@ -53,11 +53,11 @@
         this.mOnFinishListener = onFinishListener;
     }
 
-    public void finishController(boolean toRecents, Runnable callback) {
+    public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
         mOnFinishListener.accept(this);
         BACKGROUND_EXECUTOR.execute(() -> {
             controller.setInputConsumerEnabled(false);
-            controller.finish(toRecents);
+            controller.finish(toRecents, sendUserLeaveHint);
 
             if (callback != null) {
                 MAIN_THREAD_EXECUTOR.execute(callback);
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;