Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a32a2ffc authored by Chris Li's avatar Chris Li
Browse files

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
parent e87c348f
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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.
+15 −11
Original line number Diff line number Diff line
@@ -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)
+3 −0
Original line number Diff line number Diff line
@@ -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);