diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java | 43 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java | 22 |
2 files changed, 62 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java index d91165685c63..6d83fb6d12c9 100644 --- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java @@ -434,6 +434,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr private final TaskFragment mTaskFragment; private final IBinder mErrorCallback; private final Throwable mException; + // Set when the event is deferred due to the host task is invisible. The defer time will + // be the last active time of the host task. + private long mDeferTime; private PendingTaskFragmentEvent(TaskFragment taskFragment, ITaskFragmentOrganizer taskFragmentOrg, @EventType int eventType) { @@ -503,11 +506,45 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr || mPendingTaskFragmentEvents.isEmpty()) { return; } + + final ArrayList<Task> visibleTasks = new ArrayList<>(); + final ArrayList<Task> invisibleTasks = new ArrayList<>(); + final ArrayList<PendingTaskFragmentEvent> candidateEvents = new ArrayList<>(); for (int i = 0, n = mPendingTaskFragmentEvents.size(); i < n; i++) { - PendingTaskFragmentEvent event = mPendingTaskFragmentEvents.get(i); - dispatchEvent(event); + final PendingTaskFragmentEvent event = mPendingTaskFragmentEvents.get(i); + final Task task = event.mTaskFragment != null ? event.mTaskFragment.getTask() : null; + if (task != null && (task.lastActiveTime <= event.mDeferTime + || !isTaskVisible(task, visibleTasks, invisibleTasks))) { + // Defer sending events to the TaskFragment until the host task is active again. + event.mDeferTime = task.lastActiveTime; + continue; + } + candidateEvents.add(event); + } + final int numEvents = candidateEvents.size(); + for (int i = 0; i < numEvents; i++) { + dispatchEvent(candidateEvents.get(i)); + } + if (numEvents > 0) { + mPendingTaskFragmentEvents.removeAll(candidateEvents); + } + } + + private static boolean isTaskVisible(Task task, ArrayList<Task> knownVisibleTasks, + ArrayList<Task> knownInvisibleTasks) { + if (knownVisibleTasks.contains(task)) { + return true; + } + if (knownInvisibleTasks.contains(task)) { + return false; + } + if (task.shouldBeVisible(null /* starting */)) { + knownVisibleTasks.add(task); + return true; + } else { + knownInvisibleTasks.add(task); + return false; } - mPendingTaskFragmentEvents.clear(); } void dispatchPendingInfoChangedEvent(TaskFragment taskFragment) { 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 786c3eae63d0..b8e12d15c5d2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -424,4 +424,26 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities(); } + + @Test + public void testDeferPendingTaskFragmentEventsOfInvisibleTask() { + // Task - TaskFragment - Activity. + final Task task = createTask(mDisplayContent); + final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm) + .setParentTask(task) + .setOrganizer(mOrganizer) + .build(); + + // Mock the task to invisible + doReturn(false).when(task).shouldBeVisible(any()); + + // Sending events + mController.registerOrganizer(mIOrganizer); + taskFragment.mTaskFragmentAppearedSent = true; + mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment); + mController.dispatchPendingEvents(); + + // Verifies that event was not sent + verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); + } } |