Loading services/core/java/com/android/server/wm/TaskFragment.java +4 −0 Original line number Diff line number Diff line Loading @@ -401,6 +401,10 @@ class TaskFragment extends WindowContainer<WindowContainer> { mTaskFragmentOrganizerProcessName = processName; } void onTaskFragmentOrganizerRemoved() { mTaskFragmentOrganizer = null; } /** Whether this TaskFragment is organized by the given {@code organizer}. */ boolean hasTaskFragmentOrganizer(ITaskFragmentOrganizer organizer) { return organizer != null && mTaskFragmentOrganizer != null Loading services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +14 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr void dispose() { while (!mOrganizedTaskFragments.isEmpty()) { final TaskFragment taskFragment = mOrganizedTaskFragments.get(0); // Cleanup before remove to prevent it from sending any additional event, such as // #onTaskFragmentVanished, to the removed organizer. taskFragment.onTaskFragmentOrganizerRemoved(); taskFragment.removeImmediately(); mOrganizedTaskFragments.remove(taskFragment); } Loading Loading @@ -512,10 +515,21 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr mPendingTaskFragmentEvents.add(pendingEvent); } boolean isOrganizerRegistered(ITaskFragmentOrganizer organizer) { return mTaskFragmentOrganizerState.containsKey(organizer.asBinder()); } private void removeOrganizer(ITaskFragmentOrganizer organizer) { final TaskFragmentOrganizerState state = validateAndGetState(organizer); // remove all of the children of the organized TaskFragment state.dispose(); // Remove any pending event of this organizer. for (int i = mPendingTaskFragmentEvents.size() - 1; i >= 0; i--) { final PendingTaskFragmentEvent event = mPendingTaskFragmentEvents.get(i); if (event.mTaskFragmentOrg.asBinder().equals(organizer.asBinder())) { mPendingTaskFragmentEvents.remove(i); } } mTaskFragmentOrganizerState.remove(organizer.asBinder()); } Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +6 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId, @Nullable Transition transition, @NonNull CallerInfo caller, @Nullable Transition finishTransition) { if (t.getTaskFragmentOrganizer() != null && !mTaskFragmentOrganizerController .isOrganizerRegistered(t.getTaskFragmentOrganizer())) { Slog.e(TAG, "Caller organizer=" + t.getTaskFragmentOrganizer() + " is no longer registered"); return; } int effects = 0; ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); mService.deferWindowLayout(); Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -420,6 +420,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { @Test public void testApplyTransaction_enforceHierarchyChange_setAdjacentRoots() throws RemoteException { mAtm.mTaskFragmentOrganizerController.registerOrganizer(mIOrganizer); final TaskFragment taskFragment2 = new TaskFragment(mAtm, new Binder(), true /* createdByOrganizer */); final WindowContainerToken token2 = taskFragment2.mRemoteToken.toWindowContainerToken(); Loading Loading @@ -594,6 +595,25 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { assertEquals(activity0, mDisplayContent.mFocusedApp); } @Test public void testApplyTransaction_skipTransactionForUnregisterOrganizer() { final ActivityRecord ownerActivity = createActivityRecord(mDisplayContent); final IBinder fragmentToken = new Binder(); // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment. createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken); mAtm.mWindowOrganizerController.applyTransaction(mTransaction); // Nothing should happen as the organizer is not registered. assertNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken)); mController.registerOrganizer(mIOrganizer); mAtm.mWindowOrganizerController.applyTransaction(mTransaction); // Successfully created when the organizer is registered. assertNotNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken)); } @Test public void testTaskFragmentInPip_startActivityInTaskFragment() { setupTaskFragmentInPip(); Loading Loading
services/core/java/com/android/server/wm/TaskFragment.java +4 −0 Original line number Diff line number Diff line Loading @@ -401,6 +401,10 @@ class TaskFragment extends WindowContainer<WindowContainer> { mTaskFragmentOrganizerProcessName = processName; } void onTaskFragmentOrganizerRemoved() { mTaskFragmentOrganizer = null; } /** Whether this TaskFragment is organized by the given {@code organizer}. */ boolean hasTaskFragmentOrganizer(ITaskFragmentOrganizer organizer) { return organizer != null && mTaskFragmentOrganizer != null Loading
services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +14 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr void dispose() { while (!mOrganizedTaskFragments.isEmpty()) { final TaskFragment taskFragment = mOrganizedTaskFragments.get(0); // Cleanup before remove to prevent it from sending any additional event, such as // #onTaskFragmentVanished, to the removed organizer. taskFragment.onTaskFragmentOrganizerRemoved(); taskFragment.removeImmediately(); mOrganizedTaskFragments.remove(taskFragment); } Loading Loading @@ -512,10 +515,21 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr mPendingTaskFragmentEvents.add(pendingEvent); } boolean isOrganizerRegistered(ITaskFragmentOrganizer organizer) { return mTaskFragmentOrganizerState.containsKey(organizer.asBinder()); } private void removeOrganizer(ITaskFragmentOrganizer organizer) { final TaskFragmentOrganizerState state = validateAndGetState(organizer); // remove all of the children of the organized TaskFragment state.dispose(); // Remove any pending event of this organizer. for (int i = mPendingTaskFragmentEvents.size() - 1; i >= 0; i--) { final PendingTaskFragmentEvent event = mPendingTaskFragmentEvents.get(i); if (event.mTaskFragmentOrg.asBinder().equals(organizer.asBinder())) { mPendingTaskFragmentEvents.remove(i); } } mTaskFragmentOrganizerState.remove(organizer.asBinder()); } Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +6 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId, @Nullable Transition transition, @NonNull CallerInfo caller, @Nullable Transition finishTransition) { if (t.getTaskFragmentOrganizer() != null && !mTaskFragmentOrganizerController .isOrganizerRegistered(t.getTaskFragmentOrganizer())) { Slog.e(TAG, "Caller organizer=" + t.getTaskFragmentOrganizer() + " is no longer registered"); return; } int effects = 0; ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); mService.deferWindowLayout(); Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -420,6 +420,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { @Test public void testApplyTransaction_enforceHierarchyChange_setAdjacentRoots() throws RemoteException { mAtm.mTaskFragmentOrganizerController.registerOrganizer(mIOrganizer); final TaskFragment taskFragment2 = new TaskFragment(mAtm, new Binder(), true /* createdByOrganizer */); final WindowContainerToken token2 = taskFragment2.mRemoteToken.toWindowContainerToken(); Loading Loading @@ -594,6 +595,25 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { assertEquals(activity0, mDisplayContent.mFocusedApp); } @Test public void testApplyTransaction_skipTransactionForUnregisterOrganizer() { final ActivityRecord ownerActivity = createActivityRecord(mDisplayContent); final IBinder fragmentToken = new Binder(); // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment. createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken); mAtm.mWindowOrganizerController.applyTransaction(mTransaction); // Nothing should happen as the organizer is not registered. assertNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken)); mController.registerOrganizer(mIOrganizer); mAtm.mWindowOrganizerController.applyTransaction(mTransaction); // Successfully created when the organizer is registered. assertNotNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken)); } @Test public void testTaskFragmentInPip_startActivityInTaskFragment() { setupTaskFragmentInPip(); Loading