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

Commit 109ceb83 authored by Riddle Hsu's avatar Riddle Hsu Committed by Automerger Merge Worker
Browse files

Merge "Handle orientation behind for fixed rotation" into tm-qpr-dev am: e7f01c35

parents 073616d8 e7f01c35
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -1575,8 +1575,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                mAtmService.getTaskChangeNotificationController()
                        .notifyTaskRequestedOrientationChanged(task.mTaskId, orientation);
            }
            // Currently there is no use case from non-activity.
            if (handleTopActivityLaunchingInDifferentOrientation(r, true /* checkOpening */)) {
            // The orientation source may not be the top if it uses SCREEN_ORIENTATION_BEHIND.
            final ActivityRecord topCandidate = !r.mVisibleRequested ? topRunningActivity() : r;
            if (handleTopActivityLaunchingInDifferentOrientation(
                    topCandidate, r, true /* checkOpening */)) {
                // Display orientation should be deferred until the top fixed rotation is finished.
                return false;
            }
@@ -1593,7 +1595,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    /**
     * Returns a valid rotation if the activity can use different orientation than the display.
     * Otherwise {@link #ROTATION_UNDEFINED}.
     * Otherwise {@link android.app.WindowConfiguration#ROTATION_UNDEFINED}.
     */
    @Rotation
    int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
@@ -1603,6 +1605,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
            return ROTATION_UNDEFINED;
        }
        if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
            final ActivityRecord nextCandidate = getActivity(
                    a -> a.mOrientation != SCREEN_ORIENTATION_UNSET
                            && a.mOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND,
                    r, false /* includeBoundary */, true /* traverseTopToBottom */);
            if (nextCandidate != null) {
                r = nextCandidate;
            }
        }
        if (r.inMultiWindowMode() || r.getRequestedConfigurationOrientation(true /* forDisplay */)
                == getConfiguration().orientation) {
            return ROTATION_UNDEFINED;
@@ -1616,18 +1627,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return rotation;
    }

    boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
            boolean checkOpening) {
        return handleTopActivityLaunchingInDifferentOrientation(r, r, checkOpening);
    }

    /**
     * We need to keep display rotation fixed for a while when the activity in different orientation
     * is launching until the launch animation is done to avoid showing the previous activity
     * inadvertently in a wrong orientation.
     *
     * @param r The launching activity which may change display orientation.
     * @param orientationSrc It may be different from {@param r} if the launching activity uses
     *                       "behind" orientation.
     * @param checkOpening Whether to check if the activity is animating by transition. Set to
     *                     {@code true} if the caller is not sure whether the activity is launching.
     * @return {@code true} if the fixed rotation is started.
     */
    boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
            boolean checkOpening) {
    private boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
            @NonNull ActivityRecord orientationSrc, boolean checkOpening) {
        if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
            return false;
        }
@@ -1676,7 +1694,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            // animation is not running (it may be swiping to home).
            return false;
        }
        final int rotation = rotationForActivityInDifferentOrientation(r);
        final int rotation = rotationForActivityInDifferentOrientation(orientationSrc);
        if (rotation == ROTATION_UNDEFINED) {
            // The display rotation won't be changed by current top activity. The client side
            // adjustments of previous rotated activity should be cleared earlier. Otherwise if
+21 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -1092,6 +1093,25 @@ public class DisplayContentTests extends WindowTestsBase {
        assertEquals(ROTATION_180, dc.getRotation());
    }

    @Test
    public void testOrientationBehind() {
        final ActivityRecord prev = new ActivityBuilder(mAtm).setCreateTask(true)
                .setScreenOrientation(getRotatedOrientation(mDisplayContent)).build();
        prev.mVisibleRequested = false;
        final ActivityRecord top = new ActivityBuilder(mAtm).setCreateTask(true)
                .setScreenOrientation(SCREEN_ORIENTATION_BEHIND).build();
        assertNotEquals(WindowConfiguration.ROTATION_UNDEFINED,
                mDisplayContent.rotationForActivityInDifferentOrientation(top));

        mDisplayContent.requestTransitionAndLegacyPrepare(WindowManager.TRANSIT_OPEN, 0);
        top.setVisibility(true);
        mDisplayContent.updateOrientation();
        // The top uses "behind", so the orientation is decided by the previous.
        assertEquals(prev, mDisplayContent.getLastOrientationSource());
        // The top will use the rotation from "prev" with fixed rotation.
        assertTrue(top.hasFixedRotationTransform());
    }

    @Test
    public void testFixedToUserRotationChanged() {
        final DisplayContent dc = createNewDisplay();
@@ -1650,8 +1670,7 @@ public class DisplayContentTests extends WindowTestsBase {
        // The condition should reject using fixed rotation because the resumed client in real case
        // might get display info immediately. And the fixed rotation adjustments haven't arrived
        // client side so the info may be inconsistent with the requested orientation.
        verify(mDisplayContent).handleTopActivityLaunchingInDifferentOrientation(eq(app),
                eq(true) /* checkOpening */);
        verify(mDisplayContent).updateOrientation(eq(app), anyBoolean());
        assertFalse(app.isFixedRotationTransforming());
        assertFalse(mDisplayContent.hasTopFixedRotationLaunchingApp());
    }