Loading services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +40 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -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()); } } Loading
services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +40 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -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()); } }