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

Commit 6eb20a08 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Ensure activity configuration when applying WCT with display change" into main

parents f76b4a0d b7693ffa
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5280,6 +5280,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    /** Applies latest configuration and/or visibility updates if needed. */
    boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
        if (starting == null && mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
            return true;
        }
        boolean kept = true;
        final Task mainRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
        // mainRootTask is null during startup.
+23 −2
Original line number Diff line number Diff line
@@ -2857,12 +2857,18 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        return false;
    }

    /** Applies the new configuration for the changed displays. */
    void applyDisplayChangeIfNeeded() {
    /**
     * Applies the new configuration for the changed displays. Returns the activities that should
     * check whether to deliver the new configuration to clients.
     */
    @Nullable
    ArrayList<ActivityRecord> applyDisplayChangeIfNeeded() {
        ArrayList<ActivityRecord> activitiesMayChange = null;
        for (int i = mParticipants.size() - 1; i >= 0; --i) {
            final WindowContainer<?> wc = mParticipants.valueAt(i);
            final DisplayContent dc = wc.asDisplayContent();
            if (dc == null || !mChanges.get(dc).hasChanged()) continue;
            final int originalSeq = dc.getConfiguration().seq;
            dc.sendNewConfiguration();
            // Set to ready if no other change controls the ready state. But if there is, such as
            // if an activity is pausing, it will call setReady(ar, false) and wait for the next
@@ -2871,7 +2877,22 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            if (!mReadyTrackerOld.mUsed) {
                setReady(dc, true);
            }
            if (originalSeq == dc.getConfiguration().seq) continue;
            // If the update is deferred, sendNewConfiguration won't deliver new configuration to
            // clients, then it is the caller's responsibility to deliver the changes.
            if (mController.mAtm.mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
                if (activitiesMayChange == null) {
                    activitiesMayChange = new ArrayList<>();
                }
                final ArrayList<ActivityRecord> visibleActivities = activitiesMayChange;
                dc.forAllActivities(r -> {
                    if (r.isVisibleRequested()) {
                        visibleActivities.add(r);
                    }
                });
            }
        }
        return activitiesMayChange;
    }

    boolean getLegacyIsReady() {
+19 −2
Original line number Diff line number Diff line
@@ -570,8 +570,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        mService.deferWindowLayout();
        mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */);
        try {
            if (transition != null) {
                transition.applyDisplayChangeIfNeeded();
            final ArrayList<ActivityRecord> activitiesMayChange =
                    transition != null ? transition.applyDisplayChangeIfNeeded() : null;
            if (activitiesMayChange != null) {
                effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
            }
            final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
            final int hopSize = hops.size();
@@ -695,8 +697,23 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                for (int i = haveConfigChanges.size() - 1; i >= 0; --i) {
                    haveConfigChanges.valueAt(i).forAllActivities(r -> {
                        r.ensureActivityConfiguration(0, PRESERVE_WINDOWS);
                        if (activitiesMayChange != null) {
                            activitiesMayChange.remove(r);
                        }
                    });
                }
                // TODO(b/258618073): Combine with haveConfigChanges after confirming that there
                //  is no problem to always preserve window. Currently this uses the parameters
                //  as ATMS#ensureConfigAndVisibilityAfterUpdate.
                if (activitiesMayChange != null) {
                    for (int i = activitiesMayChange.size() - 1; i >= 0; --i) {
                        final ActivityRecord ar = activitiesMayChange.get(i);
                        if (!ar.isVisibleRequested()) continue;
                        ar.ensureActivityConfiguration(0 /* globalChanges */,
                                !PRESERVE_WINDOWS, true /* ignoreVisibility */,
                                false /* isRequestedOrientationChanged */);
                    }
                }
            }

            if (effects != 0) {
+13 −10
Original line number Diff line number Diff line
@@ -2086,15 +2086,17 @@ public class DisplayContentTests extends WindowTestsBase {

    @Test
    public void testShellTransitRotation() {
        DisplayContent dc = createNewDisplay();
        dc.setLastHasContent();
        final DisplayContent dc = mDisplayContent;
        // Create 2 visible activities to verify that they can both receive the new configuration.
        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true).build();
        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build();
        doReturn(true).when(activity1).isSyncFinished(any());
        doReturn(true).when(activity2).isSyncFinished(any());

        final TestTransitionPlayer testPlayer = registerTestTransitionPlayer();
        final DisplayRotation dr = dc.getDisplayRotation();
        doCallRealMethod().when(dr).updateRotationUnchecked(anyBoolean());
        // Rotate 180 degree so the display doesn't have configuration change. This condition is
        // used for the later verification of stop-freezing (without setting mWaitingForConfig).
        doReturn((dr.getRotation() + 2) % 4).when(dr).rotationForOrientation(anyInt(), anyInt());
        spyOn(dr);
        doReturn((dr.getRotation() + 1) % 4).when(dr).rotationForOrientation(anyInt(), anyInt());
        mWm.mDisplayChangeController =
                new IDisplayChangeWindowController.Stub() {
                    @Override
@@ -2109,11 +2111,8 @@ public class DisplayContentTests extends WindowTestsBase {
                    }
                };

        // kill any existing rotation animation (vestigial from test setup).
        dc.setRotationAnimation(null);

        final int origRot = dc.getConfiguration().windowConfiguration.getRotation();

        dc.setLastHasContent();
        mWm.updateRotation(true /* alwaysSendConfiguration */, false /* forceRelayout */);
        // Should create a transition request without performing rotation
        assertNotNull(testPlayer.mLastRequest);
@@ -2122,6 +2121,10 @@ public class DisplayContentTests extends WindowTestsBase {
        // Once transition starts, rotation is applied and transition shows DC rotating.
        testPlayer.startTransition();
        waitUntilHandlersIdle();
        verify(activity1).ensureActivityConfiguration(anyInt(), anyBoolean(), anyBoolean(),
                anyBoolean());
        verify(activity2).ensureActivityConfiguration(anyInt(), anyBoolean(), anyBoolean(),
                anyBoolean());
        assertNotEquals(origRot, dc.getConfiguration().windowConfiguration.getRotation());
        assertNotNull(testPlayer.mLastReady);
        assertTrue(testPlayer.mController.isPlaying());