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

Commit 10b700e7 authored by Riddle Hsu's avatar Riddle Hsu Committed by Automerger Merge Worker
Browse files

Notify client to clear intermediate rotated adjustments am: 8fea9c8e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13660605

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I6842db2e211bce2997293b66b2888aa49f1d7f75
parents ea13c7bc 8fea9c8e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1513,6 +1513,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        }
        final int rotation = rotationForActivityInDifferentOrientation(r);
        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
            // the current top is in the same process, it may get the rotated state. The transform
            // will be cleared later with transition callback to ensure smooth animation.
            if (hasTopFixedRotationLaunchingApp()) {
                mFixedRotationLaunchingApp.notifyFixedRotationTransform(false /* enabled */);
            }
            return false;
        }
        if (!r.getParent().matchParentBounds()) {
+5 −7
Original line number Diff line number Diff line
@@ -622,11 +622,6 @@ class WindowToken extends WindowContainer<WindowState> {
        state.mIsTransforming = false;
        if (applyDisplayRotation != null) {
            applyDisplayRotation.run();
        } else {
            // The display will not rotate to the rotation of this container, let's cancel them.
            for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
                state.mAssociatedTokens.get(i).cancelFixedRotationTransform();
            }
        }
        // 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.
@@ -634,11 +629,15 @@ class WindowToken extends WindowContainer<WindowState> {
            final WindowToken token = state.mAssociatedTokens.get(i);
            token.mFixedRotationTransformState = null;
            token.notifyFixedRotationTransform(false /* enabled */);
            if (applyDisplayRotation == null) {
                // Notify cancellation because the display does not change rotation.
                token.cancelFixedRotationTransform();
            }
        }
    }

    /** Notifies application side to enable or disable the rotation adjustment of display info. */
    private void notifyFixedRotationTransform(boolean enabled) {
    void notifyFixedRotationTransform(boolean enabled) {
        FixedRotationAdjustments adjustments = null;
        // A token may contain windows of the same processes or different processes. The list is
        // used to avoid sending the same adjustments to a process multiple times.
@@ -682,7 +681,6 @@ class WindowToken extends WindowContainer<WindowState> {
            // The window may be detached or detaching.
            return;
        }
        notifyFixedRotationTransform(false /* enabled */);
        final int originalRotation = getWindowConfiguration().getRotation();
        onConfigurationChanged(parent.getConfiguration());
        onCancelFixedRotationTransform(originalRotation);
+31 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import static org.mockito.Mockito.doCallRealMethod;
import android.annotation.SuppressLint;
import android.app.ActivityTaskManager;
import android.app.WindowConfiguration;
import android.app.servertransaction.FixedRotationAdjustmentsItem;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.Region;
@@ -1345,6 +1346,36 @@ public class DisplayContentTests extends WindowTestsBase {
        assertFalse(recentsActivity.hasFixedRotationTransform());
    }

    @Test
    public void testClearIntermediateFixedRotationAdjustments() throws RemoteException {
        final ActivityRecord activity = new ActivityTestsBase.StackBuilder(mWm.mRoot)
                .setDisplay(mDisplayContent).build().getTopMostActivity();
        mDisplayContent.setFixedRotationLaunchingApp(activity,
                (mDisplayContent.getRotation() + 1) % 4);
        // Create a window so FixedRotationAdjustmentsItem can be sent.
        createWindow(null, TYPE_APPLICATION_STARTING, activity, "AppWin");
        final ActivityRecord activity2 = new ActivityTestsBase.StackBuilder(mWm.mRoot)
                .setDisplay(mDisplayContent).build().getTopMostActivity();
        activity2.setVisible(false);
        clearInvocations(mWm.mAtmService.getLifecycleManager());
        // The first activity has applied fixed rotation but the second activity becomes the top
        // before the transition is done and it has the same rotation as display, so the dispatched
        // rotation adjustment of first activity must be cleared.
        mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(activity2,
                false /* checkOpening */);

        final ArgumentCaptor<FixedRotationAdjustmentsItem> adjustmentsCaptor =
                ArgumentCaptor.forClass(FixedRotationAdjustmentsItem.class);
        verify(mWm.mAtmService.getLifecycleManager(), atLeastOnce()).scheduleTransaction(
                eq(activity.app.getThread()), adjustmentsCaptor.capture());
        // The transformation is kept for animation in real case.
        assertTrue(activity.hasFixedRotationTransform());
        final FixedRotationAdjustmentsItem clearAdjustments = FixedRotationAdjustmentsItem.obtain(
                activity.token, null /* fixedRotationAdjustments */);
        // The captor may match other items. The first one must be the item to clear adjustments.
        assertEquals(clearAdjustments, adjustmentsCaptor.getAllValues().get(0));
    }

    @Test
    public void testRemoteRotation() {
        DisplayContent dc = createNewDisplay();