From 4d20184433792d29daf6091bcd803c5352304b24 Mon Sep 17 00:00:00 2001 From: Gaurav Bhola Date: Thu, 3 Mar 2022 20:04:23 +0000 Subject: [PATCH] Encapsulate the pending task events logic. - Add a new class TaskOrganizerPendingEventsQueue to hold all the pendingEvents for a given TaskOrganizer. - Also made sure that pending events list is cleared when an Organizer gets unregsitered or dies. Fix: 224812558 Test: atest WindowOrganizerTests Change-Id: Idfac9fc5cd02b5f91324a5cd27639e1c258ce587 Merged-In: Idfac9fc5cd02b5f91324a5cd27639e1c258ce587 --- .../server/wm/TaskOrganizerController.java | 362 +++++++++++------- .../server/wm/WindowOrganizerTests.java | 29 +- 2 files changed, 236 insertions(+), 155 deletions(-) diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 6e84681f0ab54..c5993e1ef4bca 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -36,6 +36,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; +import android.util.ArrayMap; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.Display; @@ -55,7 +56,6 @@ import com.android.internal.util.ArrayUtils; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -94,7 +94,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { * lifecycle order since we may be updating the visibility of task surface controls in a pending * transaction before they are presented to the task org. */ - private class TaskOrganizerCallbacks { + private static class TaskOrganizerCallbacks { final ITaskOrganizer mTaskOrganizer; final Consumer mDeferTaskOrgCallbacksConsumer; @@ -123,7 +123,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } - void onTaskVanished(Task task) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task vanished taskId=%d", task.mTaskId); final RunningTaskInfo taskInfo = task.getTaskInfo(); @@ -173,11 +172,160 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } + /** + * Maintains a list of all the pending events for a given {@link android.window.TaskOrganizer} + */ + static final class TaskOrganizerPendingEventsQueue { + private final WeakHashMap mLastSentTaskInfos = new WeakHashMap<>(); + private final TaskOrganizerState mOrganizerState; + private RunningTaskInfo mTmpTaskInfo; + // Pending task events due to layout deferred. + private final ArrayList mPendingTaskEvents = new ArrayList<>(); + + TaskOrganizerPendingEventsQueue(TaskOrganizerState taskOrganizerState) { + mOrganizerState = taskOrganizerState; + } + + @VisibleForTesting + public ArrayList getPendingEventList() { + return mPendingTaskEvents; + } + + int numPendingTaskEvents() { + return mPendingTaskEvents.size(); + } + + void clearPendingTaskEvents() { + mPendingTaskEvents.clear(); + } + + void addPendingTaskEvent(PendingTaskEvent event) { + mPendingTaskEvents.add(event); + } + + void removePendingTaskEvent(PendingTaskEvent event) { + mPendingTaskEvents.remove(event); + } + + /** + * Removes all the pending task events for the given {@code task}. + * + * @param task + * @return true if a {@link PendingTaskEvent#EVENT_APPEARED} is still pending for the given + * {code task}. + */ + boolean removePendingTaskEvents(Task task) { + boolean foundPendingAppearedEvents = false; + for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { + PendingTaskEvent entry = mPendingTaskEvents.get(i); + if (task.mTaskId == entry.mTask.mTaskId) { + // This task is vanished so remove all pending event of it. + mPendingTaskEvents.remove(i); + + if (entry.mEventType == PendingTaskEvent.EVENT_APPEARED) { + foundPendingAppearedEvents = true; + } + } + } + return foundPendingAppearedEvents; + } + + @Nullable + private PendingTaskEvent getPendingTaskEvent(Task task, int type) { + for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { + PendingTaskEvent entry = mPendingTaskEvents.get(i); + if (task.mTaskId == entry.mTask.mTaskId && type == entry.mEventType) { + return entry; + } + } + return null; + } + + @VisibleForTesting + @Nullable + PendingTaskEvent getPendingLifecycleTaskEvent(Task task) { + for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { + PendingTaskEvent entry = mPendingTaskEvents.get(i); + if (task.mTaskId == entry.mTask.mTaskId && entry.isLifecycleEvent()) { + return entry; + } + } + return null; + } + + void dispatchPendingEvents() { + if (mPendingTaskEvents.isEmpty()) { + return; + } + for (int i = 0, n = mPendingTaskEvents.size(); i < n; i++) { + dispatchPendingEvent(mPendingTaskEvents.get(i)); + } + mPendingTaskEvents.clear(); + } + + private void dispatchPendingEvent(PendingTaskEvent event) { + final Task task = event.mTask; + switch (event.mEventType) { + case PendingTaskEvent.EVENT_APPEARED: + if (task.taskAppearedReady()) { + mOrganizerState.mOrganizer.onTaskAppeared(task); + } + break; + case PendingTaskEvent.EVENT_VANISHED: + mOrganizerState.mOrganizer.onTaskVanished(task); + mLastSentTaskInfos.remove(task); + break; + case PendingTaskEvent.EVENT_INFO_CHANGED: + dispatchTaskInfoChanged(event.mTask, event.mForce); + break; + case PendingTaskEvent.EVENT_ROOT_BACK_PRESSED: + mOrganizerState.mOrganizer.onBackPressedOnTaskRoot(task); + break; + } + } + + private void dispatchTaskInfoChanged(Task task, boolean force) { + RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task); + if (mTmpTaskInfo == null) { + mTmpTaskInfo = new RunningTaskInfo(); + } + mTmpTaskInfo.configuration.unset(); + task.fillTaskInfo(mTmpTaskInfo); + + boolean changed = !mTmpTaskInfo + .equalsForTaskOrganizer(lastInfo) + || !configurationsAreEqualForOrganizer( + mTmpTaskInfo.configuration, + lastInfo.configuration); + if (!(changed || force)) { + // mTmpTaskInfo will be reused next time. + return; + } + final RunningTaskInfo newInfo = mTmpTaskInfo; + mLastSentTaskInfos.put(task, + mTmpTaskInfo); + // Since we've stored this, clean up the reference so a new one will be created next + // time. + // Transferring it this way means we only have to construct new RunningTaskInfos when + // they change. + mTmpTaskInfo = null; + + if (task.isOrganized()) { + // Because we defer sending taskAppeared() until the app has drawn, we may receive a + // configuration change before the state actually has the task registered. As such + // we should ignore these change events to the organizer until taskAppeared(). If + // the task was created by the organizer, then we always send the info change. + mOrganizerState.mOrganizer.onTaskInfoChanged(task, newInfo); + } + } + } + @VisibleForTesting class TaskOrganizerState { private final TaskOrganizerCallbacks mOrganizer; private final DeathRecipient mDeathRecipient; private final ArrayList mOrganizedTasks = new ArrayList<>(); + private final TaskOrganizerPendingEventsQueue mPendingEventsQueue; private final int mUid; TaskOrganizerState(ITaskOrganizer organizer, int uid) { @@ -187,6 +335,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { : mService.mWindowManager.mAnimator::addAfterPrepareSurfacesRunnable; mOrganizer = new TaskOrganizerCallbacks(organizer, deferTaskOrgCallbacksConsumer); mDeathRecipient = new DeathRecipient(organizer); + mPendingEventsQueue = new TaskOrganizerPendingEventsQueue(this); try { organizer.asBinder().linkToDeath(mDeathRecipient, 0); } catch (RemoteException e) { @@ -200,6 +349,11 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { return mDeathRecipient; } + @VisibleForTesting + TaskOrganizerPendingEventsQueue getPendingEventsQueue() { + return mPendingEventsQueue; + } + /** * Register this task with this state, but doesn't trigger the task appeared callback to * the organizer. @@ -263,8 +417,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { // updateTaskOrganizerState should remove the task from the list, but still // check it again to avoid while-loop isn't terminate. if (removeTask(t, t.mRemoveWithTaskOrganizer)) { - TaskOrganizerController.this.onTaskVanishedInternal( - mOrganizer.mTaskOrganizer, t); + TaskOrganizerController.this.onTaskVanishedInternal(this, t); } } if (mService.getTransitionController().isShellTransitionsEnabled()) { @@ -278,8 +431,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } - // Remove organizer state after removing tasks so we get a chance to send - // onTaskVanished. + // Pending events queue for this organizer need to be cleared because this organizer + // has either died or unregistered itself. + mPendingEventsQueue.clearPendingTaskEvents(); mTaskOrganizerStates.remove(mOrganizer.getBinder()); } @@ -320,14 +474,10 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { // List of task organizers by priority private final LinkedList mTaskOrganizers = new LinkedList<>(); - private final HashMap mTaskOrganizerStates = new HashMap<>(); - private final WeakHashMap mLastSentTaskInfos = new WeakHashMap<>(); - // Pending task events due to layout deferred. - private final ArrayList mPendingTaskEvents = new ArrayList<>(); + private final ArrayMap mTaskOrganizerStates = new ArrayMap<>(); // Set of organized tasks (by taskId) that dispatch back pressed to their organizers private final HashSet mInterceptBackPressedOnRootTasks = new HashSet(); - private RunningTaskInfo mTmpTaskInfo; private Consumer mDeferTaskOrgCallbacksConsumer; TaskOrganizerController(ActivityTaskManagerService atm) { @@ -354,11 +504,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mDeferTaskOrgCallbacksConsumer = consumer; } - @VisibleForTesting - ArrayList getPendingEventList() { - return mPendingTaskEvents; - } - /** * Register a TaskOrganizer to manage tasks as they enter the a supported windowing mode. */ @@ -592,10 +737,13 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void onTaskAppeared(ITaskOrganizer organizer, Task task) { final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); if (state != null && state.addTask(task)) { - PendingTaskEvent pending = getPendingTaskEvent(task, PendingTaskEvent.EVENT_APPEARED); + final TaskOrganizerPendingEventsQueue pendingEvents = + state.mPendingEventsQueue; + PendingTaskEvent pending = pendingEvents.getPendingTaskEvent(task, + PendingTaskEvent.EVENT_APPEARED); if (pending == null) { - pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_APPEARED); - mPendingTaskEvents.add(pending); + pendingEvents.addPendingTaskEvent(new PendingTaskEvent(task, + PendingTaskEvent.EVENT_APPEARED)); } } } @@ -603,26 +751,25 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void onTaskVanished(ITaskOrganizer organizer, Task task) { final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); if (state != null && state.removeTask(task, task.mRemoveWithTaskOrganizer)) { - onTaskVanishedInternal(organizer, task); + onTaskVanishedInternal(state, task); } } - 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 && entry.mTaskOrg == organizer) { - // This task is vanished so remove all pending event of it. - mPendingTaskEvents.remove(i); - if (entry.mEventType == PendingTaskEvent.EVENT_APPEARED) { - // If task appeared callback still pend, ignore this callback too. - return; - } - } + private void onTaskVanishedInternal(TaskOrganizerState organizerState, Task task) { + if (organizerState == null) { + Slog.i(TAG, "cannot send onTaskVanished because organizer state is not " + + "present for this organizer"); + return; } - - PendingTaskEvent pending = - new PendingTaskEvent(task, organizer, PendingTaskEvent.EVENT_VANISHED); - mPendingTaskEvents.add(pending); + TaskOrganizerPendingEventsQueue pendingEventsQueue = + organizerState.mPendingEventsQueue; + boolean hadPendingAppearedEvents = + pendingEventsQueue.removePendingTaskEvents(task); + if (hadPendingAppearedEvents) { + return; + } + pendingEventsQueue.addPendingTaskEvent(new PendingTaskEvent(task, + organizerState.mOrganizer.mTaskOrganizer, PendingTaskEvent.EVENT_VANISHED)); } @Override @@ -690,48 +837,13 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } void dispatchPendingEvents() { - if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred() - || mPendingTaskEvents.isEmpty()) { + if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) { return; } - - for (int i = 0, n = mPendingTaskEvents.size(); i < n; i++) { - PendingTaskEvent event = mPendingTaskEvents.get(i); - final Task task = event.mTask; - final TaskOrganizerState state; - switch (event.mEventType) { - case PendingTaskEvent.EVENT_APPEARED: - state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder()); - if (state != null && task.taskAppearedReady()) { - state.mOrganizer.onTaskAppeared(task); - } - break; - case PendingTaskEvent.EVENT_VANISHED: - // 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; - case PendingTaskEvent.EVENT_INFO_CHANGED: - dispatchTaskInfoChanged(event.mTask, event.mForce); - break; - case PendingTaskEvent.EVENT_ROOT_BACK_PRESSED: - state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder()); - if (state != null) { - state.mOrganizer.onBackPressedOnTaskRoot(task); - } - break; - } + for (int taskOrgIdx = 0; taskOrgIdx < mTaskOrganizerStates.size(); taskOrgIdx++) { + TaskOrganizerState taskOrganizerState = mTaskOrganizerStates.valueAt(taskOrgIdx); + taskOrganizerState.mPendingEventsQueue.dispatchPendingEvents(); } - mPendingTaskEvents.clear(); } void reportImeDrawnOnTask(Task task) { @@ -750,20 +862,30 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { // Skip if task still not appeared. return; } - if (force && mPendingTaskEvents.isEmpty()) { + final TaskOrganizerState taskOrganizerState = + mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder()); + final TaskOrganizerPendingEventsQueue pendingEventsQueue = + taskOrganizerState.mPendingEventsQueue; + if (pendingEventsQueue == null) { + Slog.i(TAG, "cannot send onTaskInfoChanged because pending events queue is not " + + "present for this organizer"); + return; + } + if (force && pendingEventsQueue.numPendingTaskEvents() == 0) { // There are task-info changed events do not result in // - RootWindowContainer#performSurfacePlacementNoTrace OR // - WindowAnimator#animate // For instance, when an app requesting aspect ratio change when in PiP mode. // To solve this, we directly dispatch the pending event if there are no events queued ( // otherwise, all pending events should be dispatched on next drawn). - dispatchTaskInfoChanged(task, true /* force */); + pendingEventsQueue.dispatchTaskInfoChanged(task, true /* force */); return; } // Defer task info reporting while layout is deferred. This is because layout defer // blocks tend to do lots of re-ordering which can mess up animations in receivers. - PendingTaskEvent pending = getPendingLifecycleTaskEvent(task); + PendingTaskEvent pending = pendingEventsQueue + .getPendingLifecycleTaskEvent(task); if (pending == null) { pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_INFO_CHANGED); } else { @@ -774,45 +896,10 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { return; } // Remove and add for re-ordering. - mPendingTaskEvents.remove(pending); + pendingEventsQueue.removePendingTaskEvent(pending); } pending.mForce |= force; - mPendingTaskEvents.add(pending); - } - - private void dispatchTaskInfoChanged(Task task, boolean force) { - RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task); - if (mTmpTaskInfo == null) { - mTmpTaskInfo = new RunningTaskInfo(); - } - mTmpTaskInfo.configuration.unset(); - task.fillTaskInfo(mTmpTaskInfo); - - boolean changed = !mTmpTaskInfo.equalsForTaskOrganizer(lastInfo) - || !configurationsAreEqualForOrganizer( - mTmpTaskInfo.configuration, lastInfo.configuration); - if (!(changed || force)) { - // mTmpTaskInfo will be reused next time. - return; - } - final RunningTaskInfo newInfo = mTmpTaskInfo; - mLastSentTaskInfos.put(task, mTmpTaskInfo); - // Since we've stored this, clean up the reference so a new one will be created next time. - // Transferring it this way means we only have to construct new RunningTaskInfos when they - // change. - mTmpTaskInfo = null; - - if (task.isOrganized()) { - // Because we defer sending taskAppeared() until the app has drawn, we may receive a - // configuration change before the state actually has the task registered. As such we - // should ignore these change events to the organizer until taskAppeared(). If the task - // was created by the organizer, then we always send the info change. - final TaskOrganizerState state = mTaskOrganizerStates.get( - task.mTaskOrganizer.asBinder()); - if (state != null) { - state.mOrganizer.onTaskInfoChanged(task, newInfo); - } - } + pendingEventsQueue.addPendingTaskEvent(pending); } @Override @@ -1018,50 +1105,36 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) { return false; } + final TaskOrganizerPendingEventsQueue pendingEventsQueue = + mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder()) + .mPendingEventsQueue; + if (pendingEventsQueue == null) { + Slog.w(TAG, "cannot get handle BackPressedOnTaskRoot because organizerState is " + + "not present"); + return false; + } PendingTaskEvent pendingVanished = - getPendingTaskEvent(task, PendingTaskEvent.EVENT_VANISHED); + pendingEventsQueue.getPendingTaskEvent(task, + PendingTaskEvent.EVENT_VANISHED); if (pendingVanished != null) { // This task will vanish before this callback so just ignore. return false; } - PendingTaskEvent pending = getPendingTaskEvent( + PendingTaskEvent pending = pendingEventsQueue.getPendingTaskEvent( task, PendingTaskEvent.EVENT_ROOT_BACK_PRESSED); if (pending == null) { pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_ROOT_BACK_PRESSED); } else { // Pending already exist, remove and add for re-ordering. - mPendingTaskEvents.remove(pending); + pendingEventsQueue.removePendingTaskEvent(pending); } - mPendingTaskEvents.add(pending); + pendingEventsQueue.addPendingTaskEvent(pending); mService.mWindowManager.mWindowPlacerLocked.requestTraversal(); return true; } - @Nullable - private PendingTaskEvent getPendingTaskEvent(Task task, int type) { - for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { - PendingTaskEvent entry = mPendingTaskEvents.get(i); - if (task.mTaskId == entry.mTask.mTaskId && type == entry.mEventType) { - return entry; - } - } - return null; - } - - @VisibleForTesting - @Nullable - PendingTaskEvent getPendingLifecycleTaskEvent(Task task) { - for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) { - PendingTaskEvent entry = mPendingTaskEvents.get(i); - if (task.mTaskId == entry.mTask.mTaskId && entry.isLifecycleEvent()) { - return entry; - } - } - return null; - } - public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.print(prefix); pw.println("TaskOrganizerController:"); @@ -1084,4 +1157,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { TaskOrganizerState getTaskOrganizerState(IBinder taskOrganizer) { return mTaskOrganizerStates.get(taskOrganizer); } + + @VisibleForTesting + TaskOrganizerPendingEventsQueue getTaskOrganizerPendingEvents(IBinder taskOrganizer) { + return mTaskOrganizerStates.get(taskOrganizer).mPendingEventsQueue; + } } 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 08bad70a14119..9c2aac066084e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -223,7 +223,7 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer); // Ensure events dispatch to organizer. mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); - assertTaskVanished(organizer, false /* expectVanished */, rootTask); + verify(organizer, times(0)).onTaskVanished(any()); assertFalse(rootTask.isOrganized()); } @@ -297,7 +297,7 @@ public class WindowOrganizerTests extends WindowTestsBase { // Ensure events dispatch to organizer. mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); - assertTaskVanished(organizer, true /* expectVanished */, rootTask); + verify(organizer, times(0)).onTaskVanished(any()); assertFalse(rootTask.isOrganized()); } @@ -341,7 +341,7 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); verify(organizer, times(3)) .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); - assertTaskVanished(organizer2, true /* expectVanished */, rootTask, rootTask2, rootTask3); + verify(organizer2, times(0)).onTaskVanished(any()); } @Test @@ -395,6 +395,7 @@ public class WindowOrganizerTests extends WindowTestsBase { assertFalse(task2.isAttached()); // Normal task should keep. assertTrue(task.isAttached()); + verify(organizer2, times(0)).onTaskVanished(any()); } @Test @@ -439,7 +440,7 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); verify(organizer, times(3)) .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); - assertTaskVanished(organizer2, true /* expectVanished */, rootTask, rootTask2, rootTask3); + verify(organizer2, times(0)).onTaskVanished(any()); } @Test @@ -1264,7 +1265,7 @@ public class WindowOrganizerTests extends WindowTestsBase { record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription")); waitUntilHandlersIdle(); - ArrayList pendingEvents = getTaskPendingEvent(rootTask); + ArrayList pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_APPEARED, pendingEvents.get(0).mEventType); assertEquals("TestDescription", @@ -1284,7 +1285,7 @@ public class WindowOrganizerTests extends WindowTestsBase { rootTask.removeImmediately(); waitUntilHandlersIdle(); - ArrayList pendingEvents = getTaskPendingEvent(rootTask); + ArrayList pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(0, pendingEvents.size()); } @@ -1302,7 +1303,7 @@ public class WindowOrganizerTests extends WindowTestsBase { record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription")); waitUntilHandlersIdle(); - ArrayList pendingEvents = getTaskPendingEvent(rootTask); + ArrayList pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType); assertEquals("TestDescription", @@ -1311,7 +1312,7 @@ public class WindowOrganizerTests extends WindowTestsBase { record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription2")); waitUntilHandlersIdle(); - pendingEvents = getTaskPendingEvent(rootTask); + pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType); assertEquals("TestDescription2", @@ -1334,7 +1335,7 @@ public class WindowOrganizerTests extends WindowTestsBase { rootTask.removeImmediately(); waitUntilHandlersIdle(); - ArrayList pendingEvents = getTaskPendingEvent(rootTask); + ArrayList pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType); assertEquals("TestDescription", @@ -1355,7 +1356,7 @@ public class WindowOrganizerTests extends WindowTestsBase { rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); waitUntilHandlersIdle(); - ArrayList pendingEvents = getTaskPendingEvent(rootTask); + ArrayList pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType); } @@ -1375,14 +1376,16 @@ public class WindowOrganizerTests extends WindowTestsBase { new IRequestFinishCallback.Default()); waitUntilHandlersIdle(); - ArrayList pendingEvents = getTaskPendingEvent(rootTask); + ArrayList pendingEvents = getTaskPendingEvent(organizer, rootTask); assertEquals(1, pendingEvents.size()); assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType); } - private ArrayList getTaskPendingEvent(Task task) { + private ArrayList getTaskPendingEvent(ITaskOrganizer organizer, Task task) { ArrayList total = - mWm.mAtmService.mTaskOrganizerController.getPendingEventList(); + mWm.mAtmService.mTaskOrganizerController + .getTaskOrganizerPendingEvents(organizer.asBinder()) + .getPendingEventList(); ArrayList result = new ArrayList(); for (int i = 0; i < total.size(); i++) {