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

Commit 559489ba authored by Chris Li's avatar Chris Li
Browse files

Ensure visibilities after TaskFragment WCT

Those WCT operations can change activity visibility. Without this
change, some activities visibility update may happen too late to be
included in transition animatoin.

Bug: 196173550
Test: Test with demo app that the activity visible is updated.
Test: atest WmTests:TaskFragmentOrganizerControllerTest
Change-Id: I78e6e1953f7ad2b733bc819002ac5d1d4929e727
parent dde5115d
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -122,7 +122,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
     * A Map which manages the relationship between
     * {@link TaskFragmentCreationParams#getFragmentToken()} and {@link TaskFragment}
     */
    private final ArrayMap<IBinder, TaskFragment> mLaunchTaskFragments = new ArrayMap<>();
    @VisibleForTesting
    final ArrayMap<IBinder, TaskFragment> mLaunchTaskFragments = new ArrayMap<>();

    WindowOrganizerController(ActivityTaskManagerService atm) {
        mService = atm;
@@ -672,7 +673,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    throw new IllegalArgumentException(
                            "Can only delete organized TaskFragment, but not Task.");
                }
                deleteTaskFragment(taskFragment, errorCallbackToken);
                effects |= deleteTaskFragment(taskFragment, errorCallbackToken);
                break;
            case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
                fragmentToken = hop.getContainer();
@@ -704,6 +705,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    break;
                }
                activity.reparent(mLaunchTaskFragments.get(fragmentToken), POSITION_TOP);
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
                break;
            case HIERARCHY_OP_TYPE_REPARENT_CHILDREN:
                final WindowContainer oldParent = WindowContainer.fromBinder(hop.getContainer());
@@ -716,6 +718,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    break;
                }
                reparentTaskFragment(oldParent, newParent, errorCallbackToken);
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
                break;
            case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS:
                fragmentToken = hop.getContainer();
@@ -731,6 +734,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    break;
                }
                tf1.setAdjacentTaskFragment(tf2);
                effects |= TRANSACT_EFFECTS_LIFECYCLE;

                final Bundle bundle = hop.getLaunchOptions();
                final WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams =
@@ -1175,7 +1179,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        }
    }

    void deleteTaskFragment(@NonNull TaskFragment taskFragment,
    private int deleteTaskFragment(@NonNull TaskFragment taskFragment,
            @Nullable IBinder errorCallbackToken) {
        final int index = mLaunchTaskFragments.indexOfValue(taskFragment);
        if (index < 0) {
@@ -1184,10 +1188,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                            + "taskFragment");
            sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
                    errorCallbackToken, exception);
            return;
            return 0;
        }
        mLaunchTaskFragments.removeAt(index);
        taskFragment.remove(true /* withTransition */, "deleteTaskFragment");
        return TRANSACT_EFFECTS_LIFECYCLE;
    }

    @Nullable
+41 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {

    @Before
    public void setup() {
        mController = mWm.mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController;
        mController = mAtm.mWindowOrganizerController.mTaskFragmentOrganizerController;
        mOrganizer = new TaskFragmentOrganizer(Runnable::run);
        mOrganizerToken = mOrganizer.getOrganizerToken();
        mIOrganizer = ITaskFragmentOrganizer.Stub.asInterface(mOrganizerToken.asBinder());
@@ -284,7 +284,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
    @Test
    public void testApplyTransaction_enforceHierarchyChange_deleteTaskFragment()
            throws RemoteException {
        mController.registerOrganizer(mIOrganizer);
        mOrganizer.applyTransaction(mTransaction);
        doReturn(true).when(mTaskFragment).isAttached();

        // Throw exception if the transaction is trying to change a window that is not organized by
        // the organizer.
@@ -300,8 +302,18 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {

        // Allow transaction to change a TaskFragment created by the organizer.
        mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
        clearInvocations(mAtm.mRootWindowContainer);

        mAtm.getWindowOrganizerController().applyTransaction(mTransaction);

        // No lifecycle update when the TaskFragment is not recorded.
        verify(mAtm.mRootWindowContainer, never()).resumeFocusedTasksTopActivities();

        mAtm.mWindowOrganizerController.mLaunchTaskFragments
                .put(mFragmentToken, mTaskFragment);
        mAtm.getWindowOrganizerController().applyTransaction(mTransaction);

        verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities();
    }

    @Test
@@ -327,8 +339,11 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
        // Allow transaction to change a TaskFragment created by the organizer.
        mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
        taskFragment2.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
        clearInvocations(mAtm.mRootWindowContainer);

        mAtm.getWindowOrganizerController().applyTransaction(mTransaction);

        verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities();
    }

    @Test
@@ -360,6 +375,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
    public void testApplyTransaction_enforceHierarchyChange_reparentChildren()
            throws RemoteException {
        mOrganizer.applyTransaction(mTransaction);
        mController.registerOrganizer(mIOrganizer);
        doReturn(true).when(mTaskFragment).isAttached();

        // Throw exception if the transaction is trying to change a window that is not organized by
        // the organizer.
@@ -375,7 +392,30 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {

        // Allow transaction to change a TaskFragment created by the organizer.
        mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
        clearInvocations(mAtm.mRootWindowContainer);

        mAtm.getWindowOrganizerController().applyTransaction(mTransaction);

        verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities();
    }

    @Test
    public void testApplyTransaction_reparentActivityToTaskFragment_triggerLifecycleUpdate()
            throws RemoteException {
        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
        mOrganizer.applyTransaction(mTransaction);
        mController.registerOrganizer(mIOrganizer);
        mTaskFragment = new TaskFragmentBuilder(mAtm)
                .setCreateParentTask()
                .setFragmentToken(mFragmentToken)
                .build();
        mAtm.mWindowOrganizerController.mLaunchTaskFragments
                .put(mFragmentToken, mTaskFragment);
        mTransaction.reparentActivityToTaskFragment(mFragmentToken, activity.appToken);
        clearInvocations(mAtm.mRootWindowContainer);

        mAtm.getWindowOrganizerController().applyTransaction(mTransaction);

        verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities();
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -1140,6 +1140,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
        private int mCreateActivityCount = 0;
        @Nullable
        private TaskFragmentOrganizer mOrganizer;
        private IBinder mFragmentToken;

        TaskFragmentBuilder(ActivityTaskManagerService service) {
            mAtm = service;
@@ -1171,10 +1172,15 @@ class WindowTestsBase extends SystemServiceTestsBase {
            return this;
        }

        TaskFragmentBuilder setFragmentToken(@Nullable IBinder fragmentToken) {
            mFragmentToken = fragmentToken;
            return this;
        }

        TaskFragment build() {
            SystemServicesTestRule.checkHoldsLock(mAtm.mGlobalLock);

            final TaskFragment taskFragment = new TaskFragment(mAtm, null /* fragmentToken */,
            final TaskFragment taskFragment = new TaskFragment(mAtm, mFragmentToken,
                    mOrganizer != null);
            if (mParentTask == null && mCreateParentTask) {
                mParentTask = new TaskBuilder(mAtm.mTaskSupervisor).build();