Fix delay on TYPE_TASK_FRAGMENT_VANISHED

Before, we call sendTaskFragmentVanished after the removeImmediately,
which may not have any following activity paused/resumed to trigger
relayout to dispatch the pending event to the organizer.

Now, we call mWindowPlacerLocked.requestTraversal() to ensure the
vanished event will be dispatched.

Without this change, the splitInfo callback can be stucked on waiting
for empty TaskFragment vanished event.

Bug: 262666213
Test: atest CtsWindowManagerDeviceTestCases:TaskFragmentOrganizerTest
Test: atest WmTests:TaskFragmentOrganizerControllerTest
Change-Id: Ibf76af205a5fc91400bdd5fc967a0d13591cfe92
This commit is contained in:
Chris Li
2022-12-14 18:23:03 +08:00
parent e87c348fcd
commit a32a2ffce2
3 changed files with 24 additions and 12 deletions

View File

@@ -227,10 +227,15 @@ class TaskFragment extends WindowContainer<WindowContainer> {
private TaskFragment mCompanionTaskFragment;
/**
* Prevents duplicate calls to onTaskAppeared.
* Prevents duplicate calls to onTaskFragmentAppeared.
*/
boolean mTaskFragmentAppearedSent;
/**
* Prevents unnecessary callbacks after onTaskFragmentVanished.
*/
boolean mTaskFragmentVanishedSent;
/**
* The last running activity of the TaskFragment was finished due to clear task while launching
* an activity in the Task.

View File

@@ -553,6 +553,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
void onTaskFragmentAppeared(@NonNull ITaskFragmentOrganizer organizer,
@NonNull TaskFragment taskFragment) {
if (taskFragment.mTaskFragmentVanishedSent) {
return;
}
if (taskFragment.getTask() == null) {
Slog.w(TAG, "onTaskFragmentAppeared failed because it is not attached tf="
+ taskFragment);
@@ -574,6 +577,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
void onTaskFragmentInfoChanged(@NonNull ITaskFragmentOrganizer organizer,
@NonNull TaskFragment taskFragment) {
if (taskFragment.mTaskFragmentVanishedSent) {
return;
}
validateAndGetState(organizer);
if (!taskFragment.mTaskFragmentAppearedSent) {
// Skip if TaskFragment still not appeared.
@@ -586,10 +592,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
.setTaskFragment(taskFragment)
.build();
} else {
if (pendingEvent.mEventType == PendingTaskFragmentEvent.EVENT_VANISHED) {
// Skipped the info changed event if vanished event is pending.
return;
}
// Remove and add for re-ordering.
removePendingEvent(pendingEvent);
// Reset the defer time when TaskFragment is changed, so that it can check again if
@@ -602,6 +604,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
void onTaskFragmentVanished(@NonNull ITaskFragmentOrganizer organizer,
@NonNull TaskFragment taskFragment) {
if (taskFragment.mTaskFragmentVanishedSent) {
return;
}
taskFragment.mTaskFragmentVanishedSent = true;
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
final List<PendingTaskFragmentEvent> pendingEvents = mPendingTaskFragmentEvents
.get(organizer.asBinder());
@@ -617,20 +623,18 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
.setTaskFragment(taskFragment)
.build());
state.removeTaskFragment(taskFragment);
// Make sure the vanished event will be dispatched if there are no other changes.
mAtmService.mWindowManager.mWindowPlacerLocked.requestTraversal();
}
void onTaskFragmentError(@NonNull ITaskFragmentOrganizer organizer,
@Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
int opType, @NonNull Throwable exception) {
validateAndGetState(organizer);
Slog.w(TAG, "onTaskFragmentError ", exception);
final PendingTaskFragmentEvent vanishedEvent = taskFragment != null
? getPendingTaskFragmentEvent(taskFragment, PendingTaskFragmentEvent.EVENT_VANISHED)
: null;
if (vanishedEvent != null) {
// No need to notify if the TaskFragment has been removed.
if (taskFragment != null && taskFragment.mTaskFragmentVanishedSent) {
return;
}
validateAndGetState(organizer);
Slog.w(TAG, "onTaskFragmentError ", exception);
addPendingEvent(new PendingTaskFragmentEvent.Builder(
PendingTaskFragmentEvent.EVENT_ERROR, organizer)
.setErrorCallbackToken(errorCallbackToken)

View File

@@ -247,6 +247,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents();
assertTrue(mTaskFragment.mTaskFragmentVanishedSent);
assertTaskFragmentVanishedTransaction();
}
@@ -259,10 +260,12 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents();
assertTrue(mTaskFragment.mTaskFragmentVanishedSent);
assertTaskFragmentVanishedTransaction();
// Not trigger onTaskFragmentInfoChanged.
// Call onTaskFragmentAppeared before calling onTaskFragmentInfoChanged.
mTaskFragment.mTaskFragmentVanishedSent = false;
mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents();
clearInvocations(mOrganizer);