Add a content overlay for auto-enter w/o a source hint rect

Bug: 184703546
Test: Swipe up from app with auto-enter but no source hint rect

Signed-off-by: Winson Chung <winsonc@google.com>
Change-Id: Ib6f03dc6b11d37c44d732c75adabf45d1795fefc
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index d04bfe9..8356eab 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1507,10 +1507,12 @@
         if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
             SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
                     mSwipePipToHomeAnimator.getComponentName(),
-                    mSwipePipToHomeAnimator.getDestinationBounds());
+                    mSwipePipToHomeAnimator.getDestinationBounds(),
+                    mSwipePipToHomeAnimator.getContentOverlay());
             mRecentsAnimationController.setFinishTaskTransaction(
                     mSwipePipToHomeAnimator.getTaskId(),
-                    mSwipePipToHomeAnimator.getFinishTransaction());
+                    mSwipePipToHomeAnimator.getFinishTransaction(),
+                    mSwipePipToHomeAnimator.getContentOverlay());
             mIsSwipingPipToHome = false;
         }
     }
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 78da311..f2bd916 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -19,6 +19,7 @@
 import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
+import android.view.SurfaceControl;
 import android.window.PictureInPictureSurfaceTransaction;
 
 import androidx.annotation.NonNull;
@@ -159,12 +160,15 @@
      * that animating Activity to PiP has completed and the associated task surface should be
      * updated accordingly. This should be called before `finish`
      * @param taskId for which the leash should be updated
-     * @param finishTransaction leash operations for the final transform.
+     * @param finishTransaction the transaction to transfer to the task surface control after the
+     *                          leash is removed
+     * @param overlay the surface control for an overlay being shown above the pip (can be null)
      */
     public void setFinishTaskTransaction(int taskId,
-            PictureInPictureSurfaceTransaction finishTransaction) {
+            PictureInPictureSurfaceTransaction finishTransaction,
+            SurfaceControl overlay) {
         UI_HELPER_EXECUTOR.execute(
-                () -> mController.setFinishTaskTransaction(taskId, finishTransaction));
+                () -> mController.setFinishTaskTransaction(taskId, finishTransaction, overlay));
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 39d8888..6fb938a 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -33,6 +33,7 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.MotionEvent;
+import android.view.SurfaceControl;
 
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.SplitConfigurationOptions;
@@ -427,10 +428,11 @@
         return null;
     }
 
-    public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) {
+    public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
+            SurfaceControl overlay) {
         if (mPip != null) {
             try {
-                mPip.stopSwipePipToHome(componentName, destinationBounds);
+                mPip.stopSwipePipToHome(componentName, destinationBounds, overlay);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call stopSwipePipToHome");
             }
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index b5570a7..3631130 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -22,19 +22,24 @@
 import android.animation.RectEvaluator;
 import android.animation.ValueAnimator;
 import android.content.ComponentName;
+import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceControl;
+import android.view.SurfaceSession;
 import android.view.View;
 import android.window.PictureInPictureSurfaceTransaction;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.util.Themes;
 import com.android.systemui.shared.pip.PipSurfaceTransactionHelper;
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 
@@ -79,6 +84,12 @@
     private boolean mHasAnimationEnded;
 
     /**
+     * An overlay used to mask changes in content when entering PiP for apps that aren't seamless.
+     */
+    @Nullable
+    private SurfaceControl mContentOverlay;
+
+    /**
      * @param taskId Task id associated with this animator, see also {@link #getTaskId()}
      * @param componentName Component associated with this animator,
      *                      see also {@link #getComponentName()}
@@ -112,6 +123,33 @@
 
         if (sourceRectHint == null) {
             mSourceHintRectInsets = null;
+
+            // Create a new overlay layer
+            SurfaceSession session = new SurfaceSession();
+            mContentOverlay = new SurfaceControl.Builder(session)
+                    .setCallsite("SwipePipToHomeAnimator")
+                    .setName("PipContentOverlay")
+                    .setColorLayer()
+                    .build();
+            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+            t.show(mContentOverlay);
+            t.setLayer(mContentOverlay, Integer.MAX_VALUE);
+            int color = Themes.getColorBackground(view.getContext());
+            float[] bgColor = new float[] {Color.red(color) / 255f, Color.green(color) / 255f,
+                    Color.blue(color) / 255f};
+            t.setColor(mContentOverlay, bgColor);
+            t.setAlpha(mContentOverlay, 0f);
+            t.reparent(mContentOverlay, mLeash);
+            t.apply();
+
+            addUpdateListener(valueAnimator -> {
+                float alpha = valueAnimator.getAnimatedFraction() < 0.5f
+                        ? 0
+                        : Utilities.mapToRange(valueAnimator.getAnimatedFraction(), 0.5f, 1f,
+                                0f, 1f, Interpolators.FAST_OUT_SLOW_IN);
+                t.setAlpha(mContentOverlay, alpha);
+                t.apply();
+            });
         } else {
             mSourceHintRectInsets = new Rect(sourceRectHint.left - appBounds.left,
                     sourceRectHint.top - appBounds.top,
@@ -234,6 +272,11 @@
         return mDestinationBounds;
     }
 
+    @Nullable
+    public SurfaceControl getContentOverlay() {
+        return mContentOverlay;
+    }
+
     /** @return {@link PictureInPictureSurfaceTransaction} for the final leash transaction. */
     public PictureInPictureSurfaceTransaction getFinishTransaction() {
         // get the final leash operations but do not apply to the leash.
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index 06cac08..8243dd4 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -92,7 +92,7 @@
         return getAttrColor(context, android.R.attr.colorAccent);
     }
 
-    /** Returns the floating background color attribute. */
+    /** Returns the background color attribute. */
     public static int getColorBackground(Context context) {
         return getAttrColor(context, android.R.attr.colorBackground);
     }