summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java43
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java22
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());
+ }
}