Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6d46793 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Fix janky animation when enter pip from secondary split" into main

parents 0bc6b1e8 112b7a06
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -427,10 +427,10 @@ public class PipAnimationController {
                    new PipContentOverlay.PipSnapshotOverlay(snapshot, sourceRectHint));
        }

        void setAppIconContentOverlay(Context context, Rect bounds, ActivityInfo activityInfo,
                int appIconSizePx) {
        void setAppIconContentOverlay(Context context, Rect appBounds, Rect destinationBounds,
                ActivityInfo activityInfo, int appIconSizePx) {
            reattachContentOverlay(
                    new PipContentOverlay.PipAppIconOverlay(context, bounds,
                    new PipContentOverlay.PipAppIconOverlay(context, appBounds, destinationBounds,
                            new IconProvider(context).getIcon(activityInfo), appIconSizePx));
        }

+31 −10
Original line number Diff line number Diff line
@@ -180,20 +180,34 @@ public abstract class PipContentOverlay {
        private final Context mContext;
        private final int mAppIconSizePx;
        private final Rect mAppBounds;
        private final int mOverlayHalfSize;
        private final Matrix mTmpTransform = new Matrix();
        private final float[] mTmpFloat9 = new float[9];

        private Bitmap mBitmap;

        public PipAppIconOverlay(Context context, Rect appBounds,
        public PipAppIconOverlay(Context context, Rect appBounds, Rect destinationBounds,
                Drawable appIcon, int appIconSizePx) {
            mContext = context;
            final int maxAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
                    MAX_APP_ICON_SIZE_DP, context.getResources().getDisplayMetrics());
            mAppIconSizePx = Math.min(maxAppIconSizePx, appIconSizePx);
            mAppBounds = new Rect(appBounds);
            mBitmap = Bitmap.createBitmap(appBounds.width(), appBounds.height(),
                    Bitmap.Config.ARGB_8888);

            final int appWidth = appBounds.width();
            final int appHeight = appBounds.height();

            // In order to have the overlay always cover the pip window during the transition, the
            // overlay will be drawn with the max size of the start and end bounds in different
            // rotation.
            final int overlaySize = Math.max(Math.max(appWidth, appHeight),
                    Math.max(destinationBounds.width(), destinationBounds.height())) + 1;
            mOverlayHalfSize = overlaySize >> 1;

            // When the activity is in the secondary split, make sure the scaling center is not
            // offset.
            mAppBounds = new Rect(0, 0, appWidth, appHeight);

            mBitmap = Bitmap.createBitmap(overlaySize, overlaySize, Bitmap.Config.ARGB_8888);
            prepareAppIconOverlay(appIcon);
            mLeash = new SurfaceControl.Builder(new SurfaceSession())
                    .setCallsite(TAG)
@@ -215,12 +229,19 @@ public abstract class PipContentOverlay {
        public void onAnimationUpdate(SurfaceControl.Transaction atomicTx,
                Rect currentBounds, float fraction) {
            mTmpTransform.reset();
            // In order for the overlay to always cover the pip window, the overlay may have a
            // size larger than the pip window. Make sure that app icon is at the center.
            final int appBoundsCenterX = mAppBounds.centerX();
            final int appBoundsCenterY = mAppBounds.centerY();
            mTmpTransform.setTranslate(
                    appBoundsCenterX - mOverlayHalfSize,
                    appBoundsCenterY - mOverlayHalfSize);
            // Scale back the bitmap with the pivot point at center.
            mTmpTransform.postScale(
                    (float) mAppBounds.width() / currentBounds.width(),
                    (float) mAppBounds.height() / currentBounds.height(),
                    mAppBounds.centerX(),
                    mAppBounds.centerY());
                    appBoundsCenterX,
                    appBoundsCenterY);
            atomicTx.setMatrix(mLeash, mTmpTransform, mTmpFloat9)
                    .setAlpha(mLeash, fraction < 0.5f ? 0 : (fraction - 0.5f) * 2);
        }
@@ -253,10 +274,10 @@ public abstract class PipContentOverlay {
                ta.recycle();
            }
            final Rect appIconBounds = new Rect(
                    mAppBounds.centerX() - mAppIconSizePx / 2,
                    mAppBounds.centerY() - mAppIconSizePx / 2,
                    mAppBounds.centerX() + mAppIconSizePx / 2,
                    mAppBounds.centerY() + mAppIconSizePx / 2);
                    mOverlayHalfSize - mAppIconSizePx / 2,
                    mOverlayHalfSize - mAppIconSizePx / 2,
                    mOverlayHalfSize + mAppIconSizePx / 2,
                    mOverlayHalfSize + mAppIconSizePx / 2);
            appIcon.setBounds(appIconBounds);
            appIcon.draw(canvas);
            mBitmap = mBitmap.copy(Bitmap.Config.HARDWARE, false /* mutable */);
+2 −2
Original line number Diff line number Diff line
@@ -1718,7 +1718,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            sourceHintRect = computeRotatedBounds(rotationDelta, direction, destinationBounds,
                    sourceHintRect);
        }
        Rect baseBounds = direction == TRANSITION_DIRECTION_SNAP_AFTER_RESIZE
        final Rect baseBounds = direction == TRANSITION_DIRECTION_SNAP_AFTER_RESIZE
                ? mPipBoundsState.getBounds() : currentBounds;
        final boolean existingAnimatorRunning = mPipAnimationController.getCurrentAnimator() != null
                && mPipAnimationController.getCurrentAnimator().isRunning();
@@ -1741,7 +1741,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                final boolean hasTopActivityInfo = mTaskInfo.topActivityInfo != null;
                if (hasTopActivityInfo) {
                    animator.setAppIconContentOverlay(
                            mContext, currentBounds, mTaskInfo.topActivityInfo,
                            mContext, currentBounds, destinationBounds, mTaskInfo.topActivityInfo,
                            mPipBoundsState.getLauncherState().getAppIconSizePx());
                } else {
                    ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+1 −1
Original line number Diff line number Diff line
@@ -916,7 +916,7 @@ public class PipTransition extends PipTransitionController {
                final boolean hasTopActivityInfo = taskInfo.topActivityInfo != null;
                if (hasTopActivityInfo) {
                    animator.setAppIconContentOverlay(
                            mContext, currentBounds, taskInfo.topActivityInfo,
                            mContext, currentBounds, destinationBounds, taskInfo.topActivityInfo,
                            mPipBoundsState.getLauncherState().getAppIconSizePx());
                } else {
                    ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+7 −2
Original line number Diff line number Diff line
@@ -2095,6 +2095,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            }

            final TaskFragment organizedTf = r.getOrganizedTaskFragment();
            final TaskFragment taskFragment = r.getTaskFragment();
            final boolean singleActivity = task.getNonFinishingActivityCount() == 1;
            if (singleActivity) {
                rootTask = task;
@@ -2137,7 +2138,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                        .setIntent(r.intent)
                        .setDeferTaskAppear(true)
                        .setHasBeenVisible(true)
                        .setWindowingMode(task.getRequestedOverrideWindowingMode())
                        // In case the activity is in system split screen, or Activity Embedding
                        // split, we need to animate the PIP Task from the original TaskFragment
                        // bounds, so also setting the windowing mode, otherwise the bounds may
                        // be reset to fullscreen.
                        .setWindowingMode(taskFragment.getWindowingMode())
                        .build();
                // Establish bi-directional link between the original and pinned task.
                r.setLastParentBeforePip(launchIntoPipHostActivity);
@@ -2150,7 +2155,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                // current bounds.
                // Use Task#setBoundsUnchecked to skip checking windowing mode as the windowing mode
                // will be updated later after this is collected in transition.
                rootTask.setBoundsUnchecked(r.getTaskFragment().getBounds());
                rootTask.setBoundsUnchecked(taskFragment.getBounds());

                // Move the last recents animation transaction from original task to the new one.
                if (task.mLastRecentsAnimationTransaction != null) {
Loading