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

Commit f6d57b6e authored by Winson Chung's avatar Winson Chung
Browse files

Remove pending launch cookie listeners

- Hypothetical scenario, if a pending launch-cookie task listener
  is added and removed immediately before the task appears (or before
  the next task info changed if the pending launch cookie is set for
  and existing task), then the listener is not removed from the
  cookie-listener map, and we may still attempt to migrate the
  listener on the next event, which can conflict with the caller's
  next listener for the given task.

Bug: 427188589
Flag: EXEMPT bugfix
Test: atest ShellTaskOrganizerTests
Change-Id: I54ecd66ef04a2ccd7cd93c11e9d6ebaa19a64b88
parent 4cb14e51
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -523,7 +523,14 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        synchronized (mLock) {
            ProtoLog.v(WM_SHELL_TASK_ORG, "Remove listener=%s", listener);

            // Remove all occurrences of the pending listener
            // Remove all occurrences of the pending listener by launch cookie
            for (int i = mLaunchCookieToListener.size() - 1; i >= 0; --i) {
                if (mLaunchCookieToListener.valueAt(i) == listener) {
                    mLaunchCookieToListener.removeAt(i);
                }
            }

            // Remove all occurrences of the pending listener by task id
            for (int i = mPendingTaskToListener.size() - 1; i >= 0; --i) {
                if (mPendingTaskToListener.valueAt(i) == listener) {
                    mPendingTaskToListener.removeAt(i);
+27 −0
Original line number Diff line number Diff line
@@ -372,6 +372,33 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
        assertTrue(mOrganizer.hasTaskListener(task1.taskId));
    }

    @Test
    public void testRemoveListenerBeforeCookieMigration() {
        // Add a generic listener for MW tasks
        TrackingTaskListener mwListener = new TrackingTaskListener();
        mOrganizer.addListenerForType(mwListener, TASK_LISTENER_TYPE_MULTI_WINDOW);

        // Create a new task with a specific launch cookie
        IBinder cookie = new Binder();
        RunningTaskInfo task1 = createTaskInfo(/* taskId= */ 1, WINDOWING_MODE_MULTI_WINDOW);
        task1.addLaunchCookie(cookie);

        // Add a pending listener based on the same launch cookie
        TrackingTaskListener cookieListener = new TrackingTaskListener();
        mOrganizer.setPendingLaunchCookieListener(cookie, cookieListener);

        // Remove the listener before the task appears
        mOrganizer.removeListener(cookieListener);

        // Report the task appearing
        mOrganizer.onTaskAppeared(task1, /* leash= */ null);

        // Verify that the cookie listener was actually removed and that the generic MW listener
        // received the task
        assertTrue(mwListener.appeared.contains(task1));
        assertFalse(cookieListener.appeared.contains(task1));
    }

    @Test
    public void testGetTaskListener() {
        RunningTaskInfo task1 = createTaskInfo(/* taskId= */ 1, WINDOWING_MODE_MULTI_WINDOW);