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

Commit ad0f56eb authored by Evan Rosky's avatar Evan Rosky
Browse files

Propagate config_at_end flag to reparent parent

Normally we consider reparented containers as "independent"
of both their parents. This means that even if the parent is
collected, we don't promote non-organized containers.

However, that is for animation specifically. Config-at-end
only cares about the post-end-state, so in this situation
we want to propagate config-at-end up to the end-parent
even when reparented.

This also adorns the activity itself with the flag so it
will properly sync if included as a direct target.

Bug: 202201326
Test: atest TransitionTests#testConfigAtEndReparent
Change-Id: I1be92157eecb4afecf5b519b56a2007b7782c66a
parent acbdee14
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -503,6 +503,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            }
            mConfigAtEndActivities.add(ar);
            ar.pauseConfigurationDispatch();
            snapshotStartState(ar);
            mChanges.get(ar).mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END;
        });
        snapshotStartState(wc);
        mChanges.get(wc).mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END;
@@ -2381,9 +2383,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            } else {
                parentChange.mFlags |= ChangeInfo.FLAG_CHANGE_YES_ANIMATION;
            }
            final ActivityRecord ar = targetChange.mContainer.asActivityRecord();
            if ((ar != null && ar.isConfigurationDispatchPaused())
                    || ((targetChange.mFlags & ChangeInfo.FLAG_CHANGE_CONFIG_AT_END) != 0)) {
            if ((targetChange.mFlags & ChangeInfo.FLAG_CHANGE_CONFIG_AT_END) != 0) {
                parentChange.mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END;
            }
        }
@@ -2470,6 +2470,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
                    } else {
                        intermediates.add(parentChange);
                    }
                    // for config-at-end, we want to promote the flag based on the end-state even
                    // if the activity was reparented because it operates after the animation. So,
                    // check that here since the promote code skips reparents.
                    if ((targetChange.mFlags & ChangeInfo.FLAG_CHANGE_CONFIG_AT_END) != 0
                            && targetChange.mContainer.asActivityRecord() != null
                            && targetChange.mContainer.getParent() == p) {
                        parentChange.mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END;
                    }
                    foundParentInTargets = true;
                    break;
                } else if (reportIfNotTop(p) && !skipIntermediateReports) {
+33 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import static java.lang.Integer.MAX_VALUE;

import android.app.ActivityManager;
import android.content.res.Configuration;
import android.graphics.Color;
@@ -2570,6 +2572,37 @@ public class TransitionTests extends WindowTestsBase {
        assertFalse(activity.isConfigurationDispatchPaused());
    }

    @Test
    public void testConfigAtEndReparent() {
        final TransitionController controller = mDisplayContent.mTransitionController;
        Transition transit = createTestTransition(TRANSIT_CHANGE, controller);
        final TestTransitionPlayer player = registerTestTransitionPlayer();

        final Task taskOrig = createTask(mDisplayContent);
        taskOrig.getConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 200, 300));
        final Task task = createTask(mDisplayContent);
        task.getConfiguration().windowConfiguration.setBounds(new Rect(10, 10, 200, 300));
        final ActivityRecord activity = createActivityRecord(taskOrig);
        activity.setVisibleRequested(true);
        activity.setVisible(true);

        controller.moveToCollecting(transit);
        transit.collect(taskOrig);
        transit.collect(task);
        transit.collect(activity);
        transit.setConfigAtEnd(taskOrig);
        activity.reparent(task, MAX_VALUE);
        task.moveToFront("test");

        controller.requestStartTransition(transit, task, null, null);
        player.start();
        // config-at-end flag must propagate up to task even when reparented (since config-at-end
        // only cares about after-end state).
        assertTrue(player.mLastReady.getChange(
                task.mRemoteToken.toWindowContainerToken()).hasFlags(FLAG_CONFIG_AT_END));
        player.finish();
    }

    @Test
    public void testReadyTrackerBasics() {
        final TransitionController controller = new TestTransitionController(