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

Commit 70a920cd authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Update display orientation that was interrupted by recents animation

When launching an activity with different orientation, the recents
animation can still be started before the transition is completed.
During animating recents, the display will keep original orientation.
So once the recents animation is finished, it still needs to check
again if the top activity may have pending orientation change.

Fixes: 155863908
Test: atest RecentsAnimationControllerTest# \
      testClearFixedRotationLaunchingAppAfterCleanupAnimation

Change-Id: I0f85dae9f55073fefe366d1f82929f5d250fc866
parent aca49a44
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -5531,7 +5531,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        /**
         * The animating activity which shows the recents task list. It is set between
         * {@link RecentsAnimationController#initialize} and
         * {@link RecentsAnimationController#cancelAnimation}.
         * {@link RecentsAnimationController#cleanupAnimation}.
         */
        private ActivityRecord mAnimatingRecents;

@@ -5554,14 +5554,25 @@ 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() {
        void onFinishRecentsAnimation(boolean moveRecentsToBack) {
            final ActivityRecord animatingRecents = mAnimatingRecents;
            mAnimatingRecents = null;
            if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp
                    && !animatingRecents.hasFixedRotationTransform()) {
                // The recents activity won't be the top, such as giving up the swipe up gesture
                // and return to the original top.
            if (!moveRecentsToBack) {
                // 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;
            }

            if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) {
                // Because it won't affect display orientation, just finish the transform.
                animatingRecents.finishFixedRotationTransform();
                mFixedRotationLaunchingApp = null;
            } else {
                // If there is already a launching activity that is not the recents, before its
                // transition is completed, the recents animation may be started. So if the recents
                // activity won't be the top, the display orientation should be updated according
                // to the current top activity.
                continueUpdateOrientationForDiffOrienLaunchingApp();
            }
        }

+2 −5
Original line number Diff line number Diff line
@@ -734,13 +734,10 @@ public class RecentsAnimationController implements DeathRecipient {
            if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
                mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(
                        mTargetActivityRecord.token);
            } else {
                // The target activity will be moved to original position (non-top). Since it won't
                // affect display orientation, just finish the transform.
                mTargetActivityRecord.finishFixedRotationTransform();
            }
        }
        mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();
        mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(
                reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION /* moveRecentsToBack */);

        // Notify that the animation has ended
        if (mStatusBar != null) {
+5 −0
Original line number Diff line number Diff line
@@ -671,6 +671,11 @@ class WindowToken extends WindowContainer<WindowState> {
            pw.print(" waitingToShow=true");
        }
        pw.println();
        if (hasFixedRotationTransform()) {
            pw.print(prefix);
            pw.print("fixedRotationConfig=");
            pw.println(mFixedRotationTransformState.mRotatedOverrideConfiguration);
        }
    }

    @Override
+35 −7
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.wm;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -159,7 +158,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        hiddenActivity.setVisible(false);
        mDefaultDisplay.getConfiguration().windowConfiguration.setRotation(
                mDefaultDisplay.getRotation());
        mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
        initializeRecentsAnimationController(mController, homeActivity);

        // Ensure that we are animating the target activity as well
        assertTrue(mController.isAnimatingTask(homeActivity.getTask()));
@@ -182,7 +181,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {

        mDefaultDisplay.getConfiguration().windowConfiguration.setRotation(
                mDefaultDisplay.getRotation());
        mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
        initializeRecentsAnimationController(mController, homeActivity);
        mController.startAnimation();

        // Ensure that we are animating the app and wallpaper target
@@ -205,7 +204,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {

        mDefaultDisplay.getConfiguration().windowConfiguration.setRotation(
                mDefaultDisplay.getRotation());
        mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
        initializeRecentsAnimationController(mController, homeActivity);
        mController.startAnimation();

        // Cancel the animation and ensure the controller is still running
@@ -231,7 +230,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        doReturn(true).when(mDefaultDisplay.mWallpaperController).isWallpaperVisible();

        // Start and finish the animation
        mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
        initializeRecentsAnimationController(mController, homeActivity);
        mController.startAnimation();

        assertTrue(mController.isAnimatingTask(homeActivity.getTask()));
@@ -342,7 +341,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        assertEquals(Configuration.ORIENTATION_LANDSCAPE,
                mDefaultDisplay.getConfiguration().orientation);

        mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
        initializeRecentsAnimationController(mController, homeActivity);

        assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp);

@@ -357,6 +356,30 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        assertNull(mDefaultDisplay.mFixedRotationLaunchingApp);
    }

    @Test
    public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
        final ActivityRecord homeActivity = createHomeActivity();
        homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
        // Assume an activity is launching to different rotation.
        mDefaultDisplay.setFixedRotationLaunchingApp(activity,
                (mDefaultDisplay.getRotation() + 1) % 4);

        assertTrue(activity.hasFixedRotationTransform());
        assertEquals(activity, mDefaultDisplay.mFixedRotationLaunchingApp);

        // Before the transition is done, the recents animation is triggered.
        initializeRecentsAnimationController(mController, homeActivity);
        assertFalse(homeActivity.hasFixedRotationTransform());

        // Simulate giving up the swipe up gesture to keep the original activity as top.
        mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
        // The rotation transform should be cleared after updating orientation with display.
        assertFalse(activity.hasFixedRotationTransform());
        assertNull(mDefaultDisplay.mFixedRotationLaunchingApp);
    }

    @Test
    public void testWallpaperHasFixedRotationApplied() {
        mWm.mIsFixedRotationTransformEnabled = true;
@@ -394,7 +417,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        doReturn(true).when(mDefaultDisplay.mWallpaperController).isWallpaperVisible();

        // Start the recents animation
        mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
        initializeRecentsAnimationController(mController, homeActivity);

        mDefaultDisplay.mWallpaperController.adjustWallpaperWindows();

@@ -433,6 +456,11 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        return homeActivity;
    }

    private static void initializeRecentsAnimationController(RecentsAnimationController controller,
            ActivityRecord activity) {
        controller.initialize(activity.getActivityType(), new SparseBooleanArray(), activity);
    }

    private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
        verify(binder, atLeast(0)).asBinder();
        verifyNoMoreInteractions(binder);