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

Commit 9be8bf7c authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/25779963',...

Merge cherrypicks of ['googleplex-android-review.googlesource.com/25779963', 'googleplex-android-review.googlesource.com/25834515', 'googleplex-android-review.googlesource.com/25812532', 'googleplex-android-review.googlesource.com/25832083'] into 24Q1-release.

Change-Id: Idce83e9705cd4836e9fd9828eab98e135e3da4a8
parents a2be7aa2 467b57b2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3672,6 +3672,7 @@ package android.view.animation {

  public class AnimationUtils {
    method @FlaggedApi("android.view.flags.expected_presentation_time_read_only") public static void lockAnimationClock(long, long);
    method public static void lockAnimationClock(long);
    method public static void unlockAnimationClock();
  }

+34 −0
Original line number Diff line number Diff line
@@ -123,6 +123,40 @@ public class AnimationUtils {
        }
    }

    /**
     * Locks AnimationUtils{@link #currentAnimationTimeMillis()} to a fixed value for the current
     * thread. This is used by {@link android.view.Choreographer} to ensure that all accesses
     * during a vsync update are synchronized to the timestamp of the vsync.
     *
     * It is also exposed to tests to allow for rapid, flake-free headless testing.
     *
     * Must be followed by a call to {@link #unlockAnimationClock()} to allow time to
     * progress. Failing to do this will result in stuck animations, scrolls, and flings.
     *
     * Note that time is not allowed to "rewind" and must perpetually flow forward. So the
     * lock may fail if the time is in the past from a previously returned value, however
     * time will be frozen for the duration of the lock. The clock is a thread-local, so
     * ensure that {@link #lockAnimationClock(long)}, {@link #unlockAnimationClock()}, and
     * {@link #currentAnimationTimeMillis()} are all called on the same thread.
     *
     * This is also not reference counted in any way. Any call to {@link #unlockAnimationClock()}
     * will unlock the clock for everyone on the same thread. It is therefore recommended
     * for tests to use their own thread to ensure that there is no collision with any existing
     * {@link android.view.Choreographer} instance.
     *
     * Have to add the method back because of b/307888459.
     * Remove this method once the lockAnimationClock(long, long) change
     * is landed to aosp/android14-tests-dev branch.
     *
     * @hide
     */
    @TestApi
    public static void lockAnimationClock(long vsyncMillis) {
        AnimationState state = sAnimationState.get();
        state.animationClockLocked = true;
        state.currentVsyncTimeMillis = vsyncMillis;
    }

    /**
     * Frees the time lock set in place by {@link #lockAnimationClock(long)}. Must be called
     * to allow the animation clock to self-update.
+2 −1
Original line number Diff line number Diff line
@@ -52,9 +52,10 @@ interface IPip {
     * @param componentName ComponentName represents the Activity
     * @param destinationBounds the destination bounds the PiP window lands into
     * @param overlay an optional overlay to fade out after entering PiP
     * @param appBounds the bounds used to set the buffer size of the optional content overlay
     */
    oneway void stopSwipePipToHome(int taskId, in ComponentName componentName,
            in Rect destinationBounds, in SurfaceControl overlay) = 2;
            in Rect destinationBounds, in SurfaceControl overlay, in Rect appBounds) = 2;

    /**
     * Notifies the swiping Activity to PiP onto home transition is aborted
+28 −4
Original line number Diff line number Diff line
@@ -334,6 +334,16 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    @Nullable
    SurfaceControl mPipOverlay;

    /**
     * The app bounds used for the buffer size of the
     * {@link com.android.wm.shell.pip.PipContentOverlay.PipAppIconOverlay}.
     *
     * Note that this is empty if the overlay is removed or if it's some other type of overlay
     * defined in {@link PipContentOverlay}.
     */
    @NonNull
    final Rect mAppBounds = new Rect();

    public PipTaskOrganizer(Context context,
            @NonNull SyncTransactionQueue syncTransactionQueue,
            @NonNull PipTransitionState pipTransitionState,
@@ -464,15 +474,15 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
     * Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
     */
    public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
            SurfaceControl overlay) {
            SurfaceControl overlay, Rect appBounds) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "stopSwipePipToHome: %s, state=%s", componentName, mPipTransitionState);
                "stopSwipePipToHome: %s, stat=%s", componentName, mPipTransitionState);
        // do nothing if there is no startSwipePipToHome being called before
        if (!mPipTransitionState.getInSwipePipToHomeTransition()) {
            return;
        }
        mPipBoundsState.setBounds(destinationBounds);
        mPipOverlay = overlay;
        setContentOverlay(overlay, appBounds);
        if (ENABLE_SHELL_TRANSITIONS && overlay != null) {
            // With Shell transition, the overlay was attached to the remote transition leash, which
            // will be removed when the current transition is finished, so we need to reparent it
@@ -1888,7 +1898,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                        "%s: trying to remove overlay (%s) which is not local reference (%s)",
                        TAG, surface, mPipOverlay);
            }
            mPipOverlay = null;
            clearContentOverlay();
        }
        if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
            // Avoid double removal, which is fatal.
@@ -1905,6 +1915,20 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        if (callback != null) callback.run();
    }

    void clearContentOverlay() {
        mPipOverlay = null;
        mAppBounds.setEmpty();
    }

    void setContentOverlay(@Nullable SurfaceControl leash, @NonNull Rect appBounds) {
        mPipOverlay = leash;
        if (mPipOverlay != null) {
            mAppBounds.set(appBounds);
        } else {
            mAppBounds.setEmpty();
        }
    }

    private void resetShadowRadius() {
        if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
            // mLeash is undefined when in PipTransitionState.UNDEFINED
+6 −19
Original line number Diff line number Diff line
@@ -141,8 +141,6 @@ public class PipTransition extends PipTransitionController {
    /** Whether the PIP window has fade out for fixed rotation. */
    private boolean mHasFadeOut;

    private Rect mInitBounds = new Rect();

    /** Used for setting transform to a transaction from animator. */
    private final PipAnimationController.PipTransactionHandler mTransactionConsumer =
            new PipAnimationController.PipTransactionHandler() {
@@ -465,12 +463,13 @@ public class PipTransition extends PipTransitionController {
                    mSurfaceTransactionHelper.crop(tx, leash, destinationBounds)
                            .resetScale(tx, leash, destinationBounds)
                            .round(tx, leash, true /* applyCornerRadius */);
                    if (mPipOrganizer.mPipOverlay != null && !mInitBounds.isEmpty()) {
                    final Rect appBounds = mPipOrganizer.mAppBounds;
                    if (mPipOrganizer.mPipOverlay != null && !appBounds.isEmpty()) {
                        // Resetting the scale for pinned task while re-adjusting its crop,
                        // also scales the overlay. So we need to update the overlay leash too.
                        Rect overlayBounds = new Rect(destinationBounds);
                        final int overlaySize = PipContentOverlay.PipAppIconOverlay
                                .getOverlaySize(mInitBounds, destinationBounds);
                                .getOverlaySize(appBounds, destinationBounds);

                        overlayBounds.offsetTo(
                                (destinationBounds.width() - overlaySize) / 2,
@@ -479,7 +478,6 @@ public class PipTransition extends PipTransitionController {
                                mPipOrganizer.mPipOverlay, overlayBounds);
                    }
                }
                mInitBounds.setEmpty();
                wct.setBoundsChangeTransaction(taskInfo.token, tx);
            }
            final int displayRotation = taskInfo.getConfiguration().windowConfiguration
@@ -617,7 +615,7 @@ public class PipTransition extends PipTransitionController {
        // if overlay is present remove it immediately, as exit transition came before it faded out
        if (mPipOrganizer.mPipOverlay != null) {
            startTransaction.remove(mPipOrganizer.mPipOverlay);
            clearPipOverlay();
            mPipOrganizer.clearContentOverlay();
        }
        if (pipChange == null) {
            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
@@ -951,9 +949,6 @@ public class PipTransition extends PipTransitionController {
        final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
        final Rect currentBounds = pipChange.getStartAbsBounds();

        // Cache the start bounds for overlay manipulations as a part of finishCallback.
        mInitBounds.set(currentBounds);

        int rotationDelta = deltaRotation(startRotation, endRotation);
        Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
                taskInfo.pictureInPictureParams, currentBounds, destinationBounds);
@@ -1022,7 +1017,7 @@ public class PipTransition extends PipTransitionController {
        } else {
            throw new RuntimeException("Unrecognized animation type: " + enterAnimationType);
        }
        mPipOrganizer.mPipOverlay = animator.getContentOverlayLeash();
        mPipOrganizer.setContentOverlay(animator.getContentOverlayLeash(), currentBounds);
        animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
                .setPipAnimationCallback(mPipAnimationCallback)
                .setDuration(mEnterExitAnimationDuration);
@@ -1073,10 +1068,6 @@ public class PipTransition extends PipTransitionController {
            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                    "%s: SwipePipToHome should not use fixed rotation %d", TAG, mEndFixedRotation);
        }
        Rect appBounds = pipTaskInfo.configuration.windowConfiguration.getAppBounds();
        if (mFixedRotationState == FIXED_ROTATION_CALLBACK && appBounds != null) {
            mInitBounds.set(appBounds);
        }
        final SurfaceControl swipePipToHomeOverlay = mPipOrganizer.mPipOverlay;
        if (swipePipToHomeOverlay != null) {
            // Launcher fade in the overlay on top of the fullscreen Task. It is possible we
@@ -1106,7 +1097,7 @@ public class PipTransition extends PipTransitionController {
        sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
        if (swipePipToHomeOverlay != null) {
            mPipOrganizer.fadeOutAndRemoveOverlay(swipePipToHomeOverlay,
                    this::clearPipOverlay /* callback */, false /* withStartDelay */);
                    null /* callback */, false /* withStartDelay */);
        }
        mPipTransitionState.setInSwipePipToHomeTransition(false);
    }
@@ -1250,10 +1241,6 @@ public class PipTransition extends PipTransitionController {
        mPipMenuController.updateMenuBounds(destinationBounds);
    }

    private void clearPipOverlay() {
        mPipOrganizer.mPipOverlay = null;
    }

    @Override
    public void dump(PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
Loading