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

Commit 45f8014a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Ic134c432,I5c5c1233 into rvc-qpr-dev

* changes:
  Allow to replace fixed rotation state
  Finish fixed rotation after recents moved to top
parents 0827205f 1f27ebfa
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -1573,7 +1573,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            // the heavy operations. This also benefits that the states of multiple activities
            // are handled together.
            r.linkFixedRotationTransform(prevRotatedLaunchingApp);
            if (r != mFixedRotationTransitionListener.mAnimatingRecents) {
                // Only update the record for normal activity so the display orientation can be
                // updated when the transition is done if it becomes the top. And the case of
                // recents can be handled when the recents animation is finished.
                setFixedRotationLaunchingAppUnchecked(r, rotation);
            }
            return;
        }

@@ -5642,6 +5647,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
         */
        private ActivityRecord mAnimatingRecents;

        /** Whether {@link #mAnimatingRecents} is going to be the top activity. */
        private boolean mRecentsWillBeTop;

        /**
         * If the recents activity has a fixed orientation which is different from the current top
         * activity, it will be rotated before being shown so we avoid a screen rotation animation
@@ -5667,10 +5675,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
         * If {@link #mAnimatingRecents} still has fixed rotation, it should be moved to top so we
         * don't clear {@link #mFixedRotationLaunchingApp} that will be handled by transition.
         */
        void onFinishRecentsAnimation(boolean moveRecentsToBack) {
        void onFinishRecentsAnimation() {
            final ActivityRecord animatingRecents = mAnimatingRecents;
            final boolean recentsWillBeTop = mRecentsWillBeTop;
            mAnimatingRecents = null;
            if (!moveRecentsToBack) {
            mRecentsWillBeTop = false;
            if (recentsWillBeTop) {
                // The recents activity will be the top, such as staying at recents list or
                // returning to home (if home and recents are the same activity).
                return;
@@ -5693,6 +5703,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            }
        }

        void notifyRecentsWillBeTop() {
            mRecentsWillBeTop = true;
        }

        /**
         * Return {@code true} if there is an ongoing animation to the "Recents" activity and this
         * activity as a fixed orientation so shouldn't be rotated.
@@ -5713,6 +5727,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            if (r == null || r == mAnimatingRecents) {
                return;
            }
            if (mAnimatingRecents != null && mRecentsWillBeTop) {
                // The activity is not the recents and it should be moved to back later, so it is
                // better to keep its current appearance for the next transition. Otherwise the
                // display orientation may be updated too early and the layout procedures at the
                // end of finishing recents animation is skipped. That causes flickering because
                // the surface of closing app hasn't updated to invisible.
                return;
            }
            if (mFixedRotationLaunchingApp == null) {
                // In most cases this is a no-op if the activity doesn't have fixed rotation.
                // Otherwise it could be from finishing recents animation while the display has
+6 −2
Original line number Diff line number Diff line
@@ -702,6 +702,11 @@ public class RecentsAnimationController implements DeathRecipient {
                        "cleanupAnimation(): Notify animation finished mPendingAnimations=%d "
                                + "reorderMode=%d",
                        mPendingAnimations.size(), reorderMode);
        if (reorderMode != REORDER_MOVE_TO_ORIGINAL_POSITION) {
            // Notify the state at the beginning because the removeAnimation may notify the
            // transition is finished. This is a signal that there will be a next transition.
            mDisplayContent.mFixedRotationTransitionListener.notifyRecentsWillBeTop();
        }
        for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
            final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
            if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
@@ -742,8 +747,7 @@ public class RecentsAnimationController implements DeathRecipient {
                        mTargetActivityRecord.token);
            }
        }
        mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(
                reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION /* moveRecentsToBack */);
        mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();

        // Notify that the animation has ended
        if (mStatusBar != null) {
+13 −7
Original line number Diff line number Diff line
@@ -531,7 +531,7 @@ class WindowToken extends WindowContainer<WindowState> {
    void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames,
            Configuration config) {
        if (mFixedRotationTransformState != null) {
            return;
            cleanUpFixedRotationTransformState(true /* replacing */);
        }
        mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
                new Configuration(config), mDisplayContent.getRotation());
@@ -548,13 +548,13 @@ class WindowToken extends WindowContainer<WindowState> {
     * one. This takes the same effect as {@link #applyFixedRotationTransform}.
     */
    void linkFixedRotationTransform(WindowToken other) {
        if (mFixedRotationTransformState != null) {
            return;
        }
        final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
        if (fixedRotationState == null) {
        if (fixedRotationState == null || mFixedRotationTransformState == fixedRotationState) {
            return;
        }
        if (mFixedRotationTransformState != null) {
            cleanUpFixedRotationTransformState(true /* replacing */);
        }
        mFixedRotationTransformState = fixedRotationState;
        fixedRotationState.mAssociatedTokens.add(this);
        onConfigurationChanged(getParent().getConfiguration());
@@ -609,11 +609,17 @@ class WindowToken extends WindowContainer<WindowState> {
        // The state is cleared at the end, because it is used to indicate that other windows can
        // use seamless rotation when applying rotation to display.
        for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
            state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState();
            state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState(
                    false /* replacing */);
        }
    }

    private void cleanUpFixedRotationTransformState() {
    private void cleanUpFixedRotationTransformState(boolean replacing) {
        if (replacing && mFixedRotationTransformState.mAssociatedTokens.size() > 1) {
            // The state is not only used by self. Make sure to leave the influence by others.
            mFixedRotationTransformState.mAssociatedTokens.remove(this);
            mFixedRotationTransformState.mRotatedContainers.remove(this);
        }
        mFixedRotationTransformState = null;
        notifyFixedRotationTransform(false /* enabled */);
    }
+1 −1
Original line number Diff line number Diff line
@@ -1282,7 +1282,7 @@ public class DisplayContentTests extends WindowTestsBase {
        assertFalse(displayRotation.updateRotationUnchecked(false));

        // Rotation can be updated if the recents animation is finished.
        mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(false);
        mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();
        assertTrue(displayRotation.updateRotationUnchecked(false));

        // Rotation can be updated if the recents animation is animating but it is not on top, e.g.
+27 −2
Original line number Diff line number Diff line
@@ -363,12 +363,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        assertFalse(homeActivity.hasFixedRotationTransform());
    }

    @Test
    public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
    private ActivityRecord prepareFixedRotationLaunchingAppWithRecentsAnim() {
        final ActivityRecord homeActivity = createHomeActivity();
        homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
        // Add a window so it can be animated by the recents.
        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
        activity.addWindow(win);
        // Assume an activity is launching to different rotation.
        mDefaultDisplay.setFixedRotationLaunchingApp(activity,
                (mDefaultDisplay.getRotation() + 1) % 4);
@@ -379,6 +381,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        // Before the transition is done, the recents animation is triggered.
        initializeRecentsAnimationController(mController, homeActivity);
        assertFalse(homeActivity.hasFixedRotationTransform());
        assertTrue(mController.isAnimatingTask(activity.getTask()));

        return activity;
    }

    @Test
    public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
        final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim();

        // Simulate giving up the swipe up gesture to keep the original activity as top.
        mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
@@ -387,6 +397,21 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        assertFalse(mDefaultDisplay.hasTopFixedRotationLaunchingApp());
    }

    @Test
    public void testKeepFixedRotationWhenMovingRecentsToTop() {
        final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim();
        // Assume a transition animation has started running before recents animation. Then the
        // activity will receive onAnimationFinished that notifies app transition finished when
        // removing the recents animation of task.
        activity.getTask().getAnimationSources().add(activity);

        // Simulate swiping to home/recents before the transition is done.
        mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
        // The rotation transform should be preserved. In real case, it will be cleared by the next
        // move-to-top transition.
        assertTrue(activity.hasFixedRotationTransform());
    }

    @Test
    public void testWallpaperHasFixedRotationApplied() {
        mWm.setRecentsAnimationController(mController);
Loading