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

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

Update non-top fixed rotation apps on display resize

Given:
  Top translucent landscape app (display is landscape)
  Opaque portrait app (fixed rotation for portrait)
This updates the new configuration and surface position for the portrait
app when display size is changed. Because the override configuration and
surface offset was calculated from previous display size.

Fix: 423060487
Flag: EXEMPT bugix
Test: DisplayContentTests#testNonTopVisibleFixedOrientationOnDisplayResize

Change-Id: I0a9369a894556cbc0c1f60bfde36dbb575516b71
parent 44da68ab
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -1658,6 +1658,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                }
                mAtmService.mChainTracker.endPartial();
            }
            if (!mSetIgnoreOrientationRequest
                    && (changes & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0) {
                // Update new size for the rotated activities, if any.
                applyFixedRotationForNonTopVisibleActivityIfNeeded();
            }
            sendNewConfiguration();
        }

@@ -1877,7 +1882,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }
        final int displayRotation = getRotation();
        final int rotation = mDisplayRotation.rotationForOrientation(orientation, displayRotation);
        if (rotation == displayRotation) {
        final DisplayFrames rotatedFrames = ar.getFixedRotationTransformDisplayFrames();
        if (rotation == displayRotation && (rotatedFrames == null || (rotatedFrames.mWidth
                == mDisplayFrames.mWidth && rotatedFrames.mHeight == mDisplayFrames.mHeight))) {
            return;
        }
        startFixedRotationTransform(ar, rotation);
+7 −3
Original line number Diff line number Diff line
@@ -3209,8 +3209,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        // set first, since we don't want rotation included in this (for now).
        mLastSurfacePosition.set(mTmpPos.x, mTmpPos.y);

        if (mTransitionController.isShellTransitionsEnabled()
                && !mTransitionController.useShellTransitionsRotation()) {
        if (!mTransitionController.useShellTransitionsRotation()) {
            if (deltaRotation != Surface.ROTATION_0) {
                updateSurfaceRotation(t, deltaRotation, null /* positionLeash */);
                mDisplayContent.setFixedTransformHint(getPendingTransaction(), mSurfaceControl,
@@ -3233,8 +3232,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        // parent must be non-null otherwise deltaRotation would be 0.
        RotationUtils.rotateSurface(t, mSurfaceControl, deltaRotation);
        mTmpPos.set(mLastSurfacePosition.x, mLastSurfacePosition.y);
        final Rect parentBounds = getParent().getBounds();
        final boolean flipped = (deltaRotation % 2) != 0;
        final Rect parentBounds = getParentBoundsForSurfaceRotation(flipped);
        RotationUtils.rotatePoint(mTmpPos, deltaRotation,
                flipped ? parentBounds.height() : parentBounds.width(),
                flipped ? parentBounds.width() : parentBounds.height());
@@ -3242,6 +3241,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
                mTmpPos.x, mTmpPos.y);
    }

    /** This is used to calculate the offset of rotated surface in the parent. */
    Rect getParentBoundsForSurfaceRotation(boolean flipped) {
        return getParent().getBounds();
    }

    @VisibleForTesting
    Point getLastSurfacePosition() {
        return mLastSurfacePosition;
+27 −0
Original line number Diff line number Diff line
@@ -448,6 +448,11 @@ class WindowToken extends WindowContainer<WindowState> {
    void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames,
            Configuration config) {
        if (mFixedRotationTransformState != null) {
            if (mFixedRotationTransformState.mDisplayFrames.mRotation == displayFrames.mRotation) {
                // Invalidate the position, so WindowContainer#updateSurfacePosition can update
                // the surface position with new size for the same rotation.
                mLastSurfacePosition.offset(-1, -1);
            }
            mFixedRotationTransformState.disassociate(this);
        }
        config = new Configuration(config);
@@ -467,6 +472,12 @@ class WindowToken extends WindowContainer<WindowState> {
            return;
        }
        if (mFixedRotationTransformState != null) {
            if (mFixedRotationTransformState.mDisplayFrames.mRotation
                    == fixedRotationState.mDisplayFrames.mRotation) {
                // Invalidate the position, so WindowContainer#updateSurfacePosition can update
                // the surface position with new size for the same rotation.
                mLastSurfacePosition.offset(-1, -1);
            }
            mFixedRotationTransformState.disassociate(this);
        }
        mFixedRotationTransformState = fixedRotationState;
@@ -675,6 +686,22 @@ class WindowToken extends WindowContainer<WindowState> {
        super.updateSurfaceRotation(t, deltaRotation, positionLeash);
    }

    @Override
    Rect getParentBoundsForSurfaceRotation(boolean flipped) {
        if (mFixedRotationTransformState == null) {
            return super.getParentBoundsForSurfaceRotation(flipped);
        }
        // Use the bounds from transform state because it is calculated by the latest display size.
        // In case the display is resizing that the parent hasn't applied new configuration.
        if (!flipped) {
            return mFixedRotationTransformState.mDisplayFrames.mUnrestricted;
        }
        final int w = mFixedRotationTransformState.mDisplayFrames.mHeight;
        final int h = mFixedRotationTransformState.mDisplayFrames.mWidth;
        mTmpPrevBounds.set(0, 0, w, h);
        return mTmpPrevBounds;
    }

    @Override
    void resetSurfacePositionForAnimationLeash(SurfaceControl.Transaction t) {
        // Keep the transformed position to animate because the surface will show in different
+34 −0
Original line number Diff line number Diff line
@@ -1767,6 +1767,40 @@ public class DisplayContentTests extends WindowTestsBase {
                mDisplayContent.hasTopFixedRotationLaunchingApp());
    }

    @Test
    public void testNonTopVisibleFixedOrientationOnDisplayResize() {
        useFakeSettingsProvider();
        spyOn(mWm.mAppCompatConfiguration);
        doReturn(false).when(mWm.mAppCompatConfiguration).isTranslucentLetterboxingEnabled();
        setReverseDefaultRotation(mDisplayContent, false);
        makeDisplayPortrait(mDisplayContent);
        final ActivityRecord nonTopVisible = new ActivityBuilder(mAtm).setCreateTask(true)
                .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE).setVisible(false).build();
        new ActivityBuilder(mAtm).setCreateTask(true)
                .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
                .setActivityTheme(android.R.style.Theme_Translucent).build();
        nonTopVisible.setVisibleRequested(true);
        clearInvocations(mTransaction);
        mDisplayContent.updateOrientation();
        mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded();

        assertTrue(nonTopVisible.hasFixedRotationTransform());
        verify(mTransaction).setPosition(eq(nonTopVisible.mSurfaceControl),
                eq((float) mDisplayContent.mBaseDisplayWidth), eq(0f));

        clearInvocations(mTransaction);
        final int newW = mDisplayContent.mBaseDisplayWidth / 2;
        final int newH = mDisplayContent.mBaseDisplayHeight / 2;
        mDisplayContent.setForcedSize(newW, newH);

        final DisplayFrames rotatedFrames = nonTopVisible.getFixedRotationTransformDisplayFrames();
        assertNotNull(rotatedFrames);
        assertEquals(newH, rotatedFrames.mWidth);
        assertEquals(newW, rotatedFrames.mHeight);
        verify(mTransaction).setPosition(eq(nonTopVisible.mSurfaceControl),
                eq((float) newW), eq(0f));
    }

    @Test
    public void testSecondaryInternalDisplayRotationFollowsDefaultDisplay() {
        final DisplayRotationCoordinator coordinator =