Snap for 9564311 from fd9f322bdb9dccdc1bee31e37778a3296674676c to tm-qpr3-release

Change-Id: I76c1d34629e6ab4534f8c420e016c119eb85447d
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index ba7a910..c95535b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -596,6 +596,10 @@
             }
         }
 
+        if (DisplayController.isTransientTaskbar(mActivity)) {
+            fullLengthAnimatorSet.play(mControllers.taskbarViewController
+                    .createRevealAnimToIsStashed(isStashed));
+        }
         fullLengthAnimatorSet.play(mControllers.stashedHandleViewController
                 .createRevealAnimToIsStashed(isStashed));
         // Return the stashed handle to its default scale in case it was changed as part of the
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 69f79ba..9824fe0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -27,6 +27,8 @@
 import static com.android.launcher3.touch.SingleAxisSwipeDetector.DIRECTION_NEGATIVE;
 import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
 
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.graphics.Rect;
 import android.util.FloatProperty;
@@ -49,6 +51,8 @@
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.anim.RevealOutlineAnimation;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.icons.ThemedIconDrawable;
@@ -95,6 +99,7 @@
     private float mTaskbarIconTranslationYForSwipe;
 
     private final int mTaskbarBottomMargin;
+    private final int mStashedHandleHeight;
 
     private final AnimatedFloat mThemeIconsBackground = new AnimatedFloat(
             this::updateIconsBackground);
@@ -127,6 +132,8 @@
         mTaskbarBottomMargin = DisplayController.isTransientTaskbar(activity)
                 ? activity.getResources().getDimensionPixelSize(R.dimen.transient_taskbar_margin)
                 : 0;
+        mStashedHandleHeight = activity.getResources()
+                .getDimensionPixelSize(R.dimen.taskbar_stashed_handle_height);
 
         if (DisplayController.isTransientTaskbar(mActivity)) {
             mSwipeDownDetector = new SingleAxisSwipeDetector(activity,
@@ -280,6 +287,40 @@
                 ));
     }
 
+    private ValueAnimator createRevealAnimForView(View view, boolean isStashed) {
+        Rect viewBounds = new Rect(0, 0, view.getWidth(), view.getHeight());
+        int centerY = viewBounds.centerY();
+        int halfHandleHeight = mStashedHandleHeight / 2;
+
+        Rect stashedRect = new Rect(viewBounds.left,
+                centerY - halfHandleHeight,
+                viewBounds.right,
+                centerY + halfHandleHeight);
+
+        float radius = 0;
+        float stashedRadius = viewBounds.width() / 2f;
+
+        return new RoundedRectRevealOutlineProvider(radius, stashedRadius, viewBounds, stashedRect)
+                .createRevealAnimator(view, !isStashed, 0);
+    }
+
+    /**
+     * Creates and returns a {@link RevealOutlineAnimation} Animator that updates the icon shape
+     * and size.
+     * @param isStashed When true, the icon crops vertically to the size of the stashed handle.
+     *                  When false, the reverse happens.
+     */
+    public AnimatorSet createRevealAnimToIsStashed(boolean isStashed) {
+        AnimatorSet as = new AnimatorSet();
+        for (int i = mTaskbarView.getChildCount() - 1; i >= 0; i--) {
+            View child = mTaskbarView.getChildAt(i);
+            if (child instanceof BubbleTextView) {
+                as.play(createRevealAnimForView(child, isStashed));
+            }
+        }
+        return as;
+    }
+
     /**
      * Sets the taskbar icon alignment relative to Launcher hotseat icons
      * @param alignmentRatio [0, 1]
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 1b29a83..2485ff8 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1600,7 +1600,7 @@
         final SwipePipToHomeAnimator.Builder builder = new SwipePipToHomeAnimator.Builder()
                 .setContext(mContext)
                 .setTaskId(runningTaskTarget.taskId)
-                .setComponentName(taskInfo.topActivity)
+                .setActivityInfo(taskInfo.topActivityInfo)
                 .setLeash(runningTaskTarget.leash)
                 .setSourceRectHint(
                         runningTaskTarget.taskInfo.pictureInPictureParams.getSourceRectHint())
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index ca4365f..e4c2dae 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -22,9 +22,11 @@
 import android.animation.RectEvaluator;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.os.SystemProperties;
 import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -50,7 +52,7 @@
     private static final float END_PROGRESS = 1.0f;
 
     private final int mTaskId;
-    private final ComponentName mComponentName;
+    private final ActivityInfo mActivityInfo;
     private final SurfaceControl mLeash;
     private final Rect mSourceRectHint = new Rect();
     private final Rect mAppBounds = new Rect();
@@ -80,15 +82,16 @@
     private boolean mHasAnimationEnded;
 
     /**
-     * An overlay used to mask changes in content when entering PiP for apps that aren't seamless.
+     * Wrapper of {@link SurfaceControl} that is used when entering PiP without valid
+     * source rect hint.
      */
     @Nullable
-    private SurfaceControl mContentOverlay;
+    private PipContentOverlay mPipContentOverlay;
 
     /**
      * @param context {@link Context} provides Launcher resources
      * @param taskId Task id associated with this animator, see also {@link #getTaskId()}
-     * @param componentName Component associated with this animator,
+     * @param activityInfo {@link ActivityInfo} associated with this animator,
      *                      see also {@link #getComponentName()}
      * @param leash {@link SurfaceControl} this animator operates on
      * @param sourceRectHint See the definition in {@link android.app.PictureInPictureParams}
@@ -106,7 +109,7 @@
      */
     private SwipePipToHomeAnimator(@NonNull Context context,
             int taskId,
-            @NonNull ComponentName componentName,
+            @NonNull ActivityInfo activityInfo,
             @NonNull SurfaceControl leash,
             @Nullable Rect sourceRectHint,
             @NonNull Rect appBounds,
@@ -120,7 +123,7 @@
             @NonNull View view) {
         super(startBounds, new RectF(destinationBoundsTransformed), context, null);
         mTaskId = taskId;
-        mComponentName = componentName;
+        mActivityInfo = activityInfo;
         mLeash = leash;
         mAppBounds.set(appBounds);
         mHomeToWindowPositionMap.set(homeToWindowPositionMap);
@@ -146,15 +149,15 @@
             // Create a new overlay layer. We do not call detach on this instance, it's propagated
             // to other classes like PipTaskOrganizer / RecentsAnimationController to complete
             // the cleanup.
-            final PipContentOverlay.PipColorOverlay overlay =
-                    new PipContentOverlay.PipColorOverlay(view.getContext());
+            if (SystemProperties.getBoolean(
+                    "persist.wm.debug.enable_pip_app_icon_overlay", false)) {
+                mPipContentOverlay = new PipContentOverlay.PipAppIconOverlay(view.getContext(),
+                        mAppBounds, mActivityInfo);
+            }  else {
+                mPipContentOverlay = new PipContentOverlay.PipColorOverlay(view.getContext());
+            }
             final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
-            mContentOverlay = overlay.getLeash();
-            overlay.attach(tx, mLeash);
-            addOnUpdateListener((currentRect, progress) -> {
-                overlay.onAnimationUpdate(tx, progress);
-                tx.apply();
-            });
+            mPipContentOverlay.attach(tx, mLeash);
         } else {
             mSourceRectHint.set(sourceRectHint);
             mSourceHintRectInsets = new Rect(sourceRectHint.left - appBounds.left,
@@ -203,6 +206,9 @@
     private PictureInPictureSurfaceTransaction onAnimationUpdate(SurfaceControl.Transaction tx,
             RectF currentRect, float progress) {
         currentRect.round(mCurrentBounds);
+        if (mPipContentOverlay != null) {
+            mPipContentOverlay.onAnimationUpdate(tx, mCurrentBounds, progress);
+        }
         final PictureInPictureSurfaceTransaction op;
         if (mSourceHintRectInsets == null) {
             // no source rect hint been set, directly scale the window down
@@ -247,7 +253,7 @@
     }
 
     public ComponentName getComponentName() {
-        return mComponentName;
+        return mActivityInfo.getComponentName();
     }
 
     public Rect getDestinationBounds() {
@@ -256,7 +262,7 @@
 
     @Nullable
     public SurfaceControl getContentOverlay() {
-        return mContentOverlay;
+        return mPipContentOverlay == null ? null : mPipContentOverlay.getLeash();
     }
 
     /** @return {@link PictureInPictureSurfaceTransaction} for the final leash transaction. */
@@ -309,7 +315,7 @@
     public static class Builder {
         private Context mContext;
         private int mTaskId;
-        private ComponentName mComponentName;
+        private ActivityInfo mActivityInfo;
         private SurfaceControl mLeash;
         private Rect mSourceRectHint;
         private Rect mDisplayCutoutInsets;
@@ -333,8 +339,8 @@
             return this;
         }
 
-        public Builder setComponentName(ComponentName componentName) {
-            mComponentName = componentName;
+        public Builder setActivityInfo(ActivityInfo activityInfo) {
+            mActivityInfo = activityInfo;
             return this;
         }
 
@@ -418,7 +424,7 @@
                     mAppBounds.inset(mDisplayCutoutInsets);
                 }
             }
-            return new SwipePipToHomeAnimator(mContext, mTaskId, mComponentName, mLeash,
+            return new SwipePipToHomeAnimator(mContext, mTaskId, mActivityInfo, mLeash,
                     mSourceRectHint, mAppBounds,
                     mHomeToWindowPositionMap, mStartBounds, mDestinationBounds,
                     mFromRotation, mDestinationBoundsTransformed,
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 4f4e65c..9587447 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -305,9 +305,6 @@
             "FOLDABLE_WORKSPACE_REORDER", true,
             "In foldables, when reordering the icons and widgets, is now going to use both sides");
 
-    public static final BooleanFlag ENABLE_QUICK_LAUNCH_V3 = new DeviceFlag(
-            "ENABLE_QUICK_LAUNCH_V3", false, "Quick Launch V3");
-
     public static final BooleanFlag ENABLE_WIDGET_PICKER_DEPTH = new DeviceFlag(
             "ENABLE_WIDGET_PICKER_DEPTH", true, "Enable changing depth in widget picker.");