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

Commit b40f9662 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Clear fixed rotation if display config does not change

There is a timing that when remote rotation is completed, the
orientation from sensor has been updated again. If the transition
of rotated app hasn't complete, the display is still in previous
orientation, then if it is the same as the last value from sensor,
the display configuration does not change. So in this case the
rotated app needs to be restored to avoid showing different
orientation than the display.

Fixes: 153327533
Test: ActivityRecordTests#testActivityOnCancelFixedRotationTransform
Test: Add delay to execute DisplayRotation#continueRotation.
      Put device in landscape with a portrait home on top, launch an
      activity without fixed orientation, and then rotate the device
      to portrait immediately. The activity should launch in landscape
      and rotate to portrait with animation.

Change-Id: Ic966923a751d94cc6ea86a83c2f600424999799c
parent cbc5d272
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -1271,6 +1271,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (configUpdated) {
            return;
        }

        // The display configuration doesn't change. If there is a launching transformed app, that
        // means its request to change display configuration has been discarded, then it should
        // respect to the current configuration of display.
        clearFixedRotationLaunchingApp();

        // Something changed (E.g. device rotation), but no configuration update is needed.
        // E.g. changing device rotation by 180 degrees. Go ahead and perform surface placement to
        // unfreeze the display since we froze it when the rotation was updated in
@@ -1496,8 +1502,20 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            sendNewConfiguration();
            return;
        }
        // The display won't rotate (e.g. the orientation from sensor has updated again before
        // applying rotation to display), so clear it to stop using seamless rotation.
        // The orientation of display is not changed.
        clearFixedRotationLaunchingApp();
    }

    /**
     * Clears the {@link mFixedRotationLaunchingApp} without applying rotation to display. It is
     * used when the display won't rotate (e.g. the orientation from sensor has updated again before
     * applying rotation to display) but the launching app has been transformed. So the record need
     * to be cleared and restored to stop using seamless rotation and rotated configuration.
     */
    private void clearFixedRotationLaunchingApp() {
        if (mFixedRotationLaunchingApp == null) {
            return;
        }
        mFixedRotationLaunchingApp.finishFixedRotationTransform();
        mFixedRotationLaunchingApp = null;
    }
@@ -2869,6 +2887,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            pw.print("  mLastStatusBarVisibility=0x");
            pw.println(Integer.toHexString(mLastStatusBarVisibility));
        }
        if (mFixedRotationLaunchingApp != null) {
            pw.println("  mFixedRotationLaunchingApp=" + mFixedRotationLaunchingApp);
        }

        pw.println();
        mWallpaperController.dump(pw, "  ");
+13 −1
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;

import android.app.ActivityOptions;
@@ -1362,6 +1363,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
        final DisplayInfo rotatedInfo = mActivity.getFixedRotationTransformDisplayInfo();
        mActivity.finishFixedRotationTransform();
        final ScreenRotationAnimation rotationAnim = display.getRotationAnimation();
        assertNotNull(rotationAnim);
        rotationAnim.setRotation(display.getPendingTransaction(), originalRotation);

        // Because the display doesn't rotate, the rotated activity needs to cancel the fixed
@@ -1369,8 +1371,18 @@ public class ActivityRecordTests extends ActivityTestsBase {
        verify(mActivity).onCancelFixedRotationTransform(rotatedInfo.rotation);
        assertTrue(mActivity.isFreezingScreen());
        assertFalse(displayRotation.isRotatingSeamlessly());
        assertNotNull(rotationAnim);
        assertTrue(rotationAnim.isRotating());

        // Simulate the remote rotation has completed and the configuration doesn't change, then
        // the rotated activity should also be restored by clearing the transform.
        displayRotation.updateRotationUnchecked(true /* forceUpdate */);
        doReturn(false).when(displayRotation).isWaitingForRemoteRotation();
        clearInvocations(mActivity);
        display.mFixedRotationLaunchingApp = mActivity;
        display.sendNewConfiguration();

        assertNull(display.mFixedRotationLaunchingApp);
        assertFalse(mActivity.hasFixedRotationTransform());
    }

    @Test