diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/TaskOrganizerController.java | 35 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java | 45 |
2 files changed, 72 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index ff5bfbee61f4..7d738241e4a3 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -67,7 +67,8 @@ import java.util.function.Consumer; class TaskOrganizerController extends ITaskOrganizerController.Stub { private static final String TAG = "TaskOrganizerController"; - private class DeathRecipient implements IBinder.DeathRecipient { + @VisibleForTesting + class DeathRecipient implements IBinder.DeathRecipient { ITaskOrganizer mTaskOrganizer; DeathRecipient(ITaskOrganizer organizer) { @@ -77,7 +78,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public void binderDied() { synchronized (mGlobalLock) { - final TaskOrganizerState state = mTaskOrganizerStates.remove( + final TaskOrganizerState state = mTaskOrganizerStates.get( mTaskOrganizer.asBinder()); if (state != null) { state.dispose(); @@ -170,7 +171,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } - private class TaskOrganizerState { + @VisibleForTesting + class TaskOrganizerState { private final TaskOrganizerCallbacks mOrganizer; private final DeathRecipient mDeathRecipient; private final ArrayList<Task> mOrganizedTasks = new ArrayList<>(); @@ -191,6 +193,11 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mUid = uid; } + @VisibleForTesting + DeathRecipient getDeathRecipient() { + return mDeathRecipient; + } + /** * Register this task with this state, but doesn't trigger the task appeared callback to * the organizer. @@ -265,7 +272,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { // Remove organizer state after removing tasks so we get a chance to send // onTaskVanished. - mTaskOrganizerStates.remove(asBinder()); + mTaskOrganizerStates.remove(mOrganizer.getBinder()); } void unlinkDeath() { @@ -596,7 +603,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { private void onTaskVanishedInternal(ITaskOrganizer organizer, Task task) { for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { PendingTaskEvent entry = mPendingTaskEvents.get(i); - if (task.mTaskId == entry.mTask.mTaskId) { + if (task.mTaskId == entry.mTask.mTaskId && entry.mTaskOrg == organizer) { // This task is vanished so remove all pending event of it. mPendingTaskEvents.remove(i); if (entry.mEventType == PendingTaskEvent.EVENT_APPEARED) { @@ -693,9 +700,16 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } break; case PendingTaskEvent.EVENT_VANISHED: - state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder()); - if (state != null) { - state.mOrganizer.onTaskVanished(task); + // TaskOrganizerState cannot be used here because it might have already been + // removed. + // The state is removed when an organizer dies or is unregistered. In order to + // send the pending vanished task events, the mTaskOrg from event is used. + // These events should not ideally be sent and will be removed as part of + // b/224812558. + try { + event.mTaskOrg.onTaskVanished(task.getTaskInfo()); + } catch (RemoteException ex) { + Slog.e(TAG, "Exception sending onTaskVanished callback", ex); } mLastSentTaskInfos.remove(task); break; @@ -1045,4 +1059,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } pw.println(); } + + @VisibleForTesting + TaskOrganizerState getTaskOrganizerState(IBinder taskOrganizer) { + return mTaskOrganizerStates.get(taskOrganizer); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index b4d305bbe4d0..9faf499f391a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -309,6 +309,51 @@ public class WindowOrganizerTests extends WindowTestsBase { } @Test + public void testOrganizerDeathReturnsRegistrationToPrevious() throws RemoteException { + final Task rootTask = createRootTask(); + final Task task = createTask(rootTask); + final Task rootTask2 = createRootTask(); + final Task task2 = createTask(rootTask2); + final Task rootTask3 = createRootTask(); + final Task task3 = createTask(rootTask3); + final ArrayList<TaskAppearedInfo> existingTasks = new ArrayList<>(); + final ITaskOrganizer organizer = registerMockOrganizer(existingTasks); + // Ensure events dispatch to organizer. + mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); + + // verify that tasks are returned and taskAppeared is not called + assertContainsTasks(existingTasks, rootTask, rootTask2, rootTask3); + verify(organizer, times(0)).onTaskAppeared(any(RunningTaskInfo.class), + any(SurfaceControl.class)); + verify(organizer, times(0)).onTaskVanished(any()); + assertTrue(rootTask.isOrganized()); + + // Now we replace the registration and verify the new organizer receives existing tasks + final ArrayList<TaskAppearedInfo> existingTasks2 = new ArrayList<>(); + final ITaskOrganizer organizer2 = registerMockOrganizer(existingTasks2); + // Ensure events dispatch to organizer. + mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); + assertContainsTasks(existingTasks2, rootTask, rootTask2, rootTask3); + verify(organizer2, times(0)).onTaskAppeared(any(RunningTaskInfo.class), + any(SurfaceControl.class)); + verify(organizer2, times(0)).onTaskVanished(any()); + // Removed tasks from the original organizer + assertTaskVanished(organizer, true /* expectVanished */, rootTask, rootTask2, rootTask3); + assertTrue(rootTask2.isOrganized()); + + // Trigger binderDied for second one, the first one should automatically be reregistered + // so we verify that it's now seeing changes. + mWm.mAtmService.mTaskOrganizerController.getTaskOrganizerState(organizer2.asBinder()) + .getDeathRecipient().binderDied(); + + // Ensure events dispatch to organizer. + mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); + verify(organizer, times(3)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); + assertTaskVanished(organizer2, true /* expectVanished */, rootTask, rootTask2, rootTask3); + } + + @Test public void testRegisterTaskOrganizerWithExistingTasks() throws RemoteException { final Task rootTask = createRootTask(); final Task task = createTask(rootTask); |