summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java45
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);