diff options
| author | 2021-09-19 19:03:58 +0800 | |
|---|---|---|
| committer | 2021-09-22 13:08:35 +0800 | |
| commit | 559489ba25f51bfa446fa5ad9afddf18915e4292 (patch) | |
| tree | 211136ddd7a1b7387adb673cb6716a32765250f8 | |
| parent | dde5115d05ed288d0d051d0611e5a82a14813b59 (diff) | |
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
3 files changed, 57 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 834b6e62305d..0b2b05054e60 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -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 diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index 98c1eabe4eca..d475c46eed0c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -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(); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 1f6065f014ae..6626aa46e7da 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -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(); |