Merge "Send Task Fragment Info Update When Task Invisible..." into sc-v2-dev

This commit is contained in:
TreeHugger Robot
2022-01-15 06:45:44 +00:00
committed by Android (Google) Code Review
2 changed files with 58 additions and 1 deletions

View File

@@ -22,6 +22,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANI
import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -497,6 +498,23 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return null;
}
private boolean shouldSendEventWhenTaskInvisible(@NonNull Task task,
@NonNull PendingTaskFragmentEvent event) {
final TaskFragmentOrganizerState state =
mTaskFragmentOrganizerState.get(event.mTaskFragmentOrg.asBinder());
final TaskFragmentInfo lastInfo = state.mLastSentTaskFragmentInfos.get(event.mTaskFragment);
final TaskFragmentInfo info = event.mTaskFragment.getTaskFragmentInfo();
// Send an info changed callback if this event is for the last activities to finish in a
// Task so that the {@link TaskFragmentOrganizer} can delete this TaskFragment. Otherwise,
// the Task may be removed before it becomes visible again to send this event because it no
// longer has activities. As a result, the organizer will never get this info changed event
// and will not delete the TaskFragment because the organizer thinks the TaskFragment still
// has running activities.
return event.mEventType == PendingTaskFragmentEvent.EVENT_INFO_CHANGED
&& task.topRunningActivity() == null && lastInfo != null
&& lastInfo.getRunningActivityCount() > 0 && info.getRunningActivityCount() == 0;
}
void dispatchPendingEvents() {
if (mAtmService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()
|| mPendingTaskFragmentEvents.isEmpty()) {
@@ -510,7 +528,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
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))) {
|| !(isTaskVisible(task, visibleTasks, invisibleTasks)
|| shouldSendEventWhenTaskInvisible(task, event)))) {
// Defer sending events to the TaskFragment until the host task is active again.
event.mDeferTime = task.lastActiveTime;
continue;

View File

@@ -21,14 +21,17 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.testing.Assert.assertThrows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import android.content.Intent;
@@ -471,6 +474,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
.setParentTask(task)
.setOrganizer(mOrganizer)
.setFragmentToken(mFragmentToken)
.build();
// Mock the task to invisible
@@ -485,4 +489,38 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
// Verifies that event was not sent
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any());
}
/**
* Tests that a task fragment info changed event is still sent if the task is invisible only
* when the info changed event is because of the last activity in a task finishing.
*/
@Test
public void testLastPendingTaskFragmentInfoChangedEventOfInvisibleTaskSent() {
// Create a TaskFragment with an activity, all within a parent task
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
.setOrganizer(mOrganizer)
.setFragmentToken(mFragmentToken)
.setCreateParentTask()
.createActivityCount(1)
.build();
final Task parentTask = taskFragment.getTask();
final ActivityRecord activity = taskFragment.getTopNonFinishingActivity();
assertTrue(parentTask.shouldBeVisible(null));
// Dispatch pending info changed event from creating the activity
mController.registerOrganizer(mIOrganizer);
taskFragment.mTaskFragmentAppearedSent = true;
mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
mController.dispatchPendingEvents();
// Finish the activity and verify that the task is invisible
activity.finishing = true;
assertFalse(parentTask.shouldBeVisible(null));
// Verify the info changed callback still occurred despite the task being invisible
reset(mOrganizer);
mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentInfoChanged(any());
}
}