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

Commit 85ee9e19 authored by Mady Mellor's avatar Mady Mellor
Browse files

Clear out the taskId when the TaskView is removed

We only have a valid taskId for a bubble if we have a TaskView (hosted
by the expanded view) for it. When a bubble is overflowed, we remove
that task.

These code paths looking for an overflowed bubble with a matching
taskId would never would've been hit in reality since we'd never
have a restart with the same taskId for a bubble in the overflow,
because when a bubble is overflowed, we remove the task.

This CL clears out the taskId when the TaskView is cleaned up and
removes related lookups of overflowed bubbles via taskId.

It might also make sense to do away with mTaskId entirely in a bubble,
but this was added to link tasks to persisted bubbles after a sysui
crash and I'm not entirely certain it's not needed for that still;
tracking investigating that separately in b/415106726.

Flag: EXEMPT bugfix / although most of this is behind com.android.wm.shell.enable_create_any_bubble
Test: atest BubbleTest
Bug: 413473792
Change-Id: I5f188b385824b31db71e68bec417f02d9ae1a153
parent 49eebfe3
Loading
Loading
Loading
Loading
+0 −48
Original line number Diff line number Diff line
@@ -135,52 +135,4 @@ class BubbleTaskStackListenerTest {
        verify(taskOrganizer).setInterceptBackPressedOnTaskRoot(task.token, false /* intercept */)
        verify(taskViewTaskController).notifyTaskRemovalStarted(task)
    }

    @Test
    fun onActivityRestartAttempt_overflowAppBubbleRestart_promotesFromOverflow() {
        bubbleData.stub {
            on { getOverflowBubbleWithTaskId(bubbleTaskId) } doReturn bubble
        }

        bubbleTaskStackListener.onActivityRestartAttempt(
            task,
            homeTaskVisible = false,
            clearedTask = false,
            wasVisible = false,
        )

        verify(bubbleController).promoteBubbleFromOverflow(bubble)
        verify(bubbleData).setExpanded(true)
    }

    @Test
    @EnableFlags(
        FLAG_ENABLE_CREATE_ANY_BUBBLE,
        FLAG_ENABLE_BUBBLE_ANYTHING,
        FLAG_EXCLUDE_TASK_FROM_RECENTS,
        FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP,
    )
    fun onActivityRestartAttempt_overflowAppBubbleToFullscreen_notifiesTaskRemoval() {
        task.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
        bubbleData.stub {
            on { getOverflowBubbleWithTaskId(bubbleTaskId) } doReturn bubble
        }

        bubbleTaskStackListener.onActivityRestartAttempt(
            task,
            homeTaskVisible = false,
            clearedTask = false,
            wasVisible = false,
        )

        val taskViewTaskController = bubble.taskView.controller
        val taskOrganizer = taskViewTaskController.taskOrganizer
        val wct = argumentCaptor<WindowContainerTransaction>().let { wctCaptor ->
            verify(taskOrganizer).applyTransaction(wctCaptor.capture())
            wctCaptor.lastValue
        }
        verifyExitBubbleTransaction(wct, bubbleTaskToken.asBinder())
        verify(taskOrganizer).setInterceptBackPressedOnTaskRoot(task.token, false /* intercept */)
        verify(taskViewTaskController).notifyTaskRemovalStarted(task)
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -670,6 +670,7 @@ public class Bubble implements BubbleViewProvider {
            mBubbleTaskView.cleanup();
            mBubbleTaskView = null;
        }
        mTaskId = INVALID_TASK_ID;
    }

    /**
+0 −6
Original line number Diff line number Diff line
@@ -1259,12 +1259,6 @@ public class BubbleData {
                b.getIconView() != null && b.getIconView().equals(view));
    }

    /** @return the overflow bubble that matches the provided taskId. */
    @Nullable
    Bubble getOverflowBubbleWithTaskId(int taskId) {
        return getBubbleWithPredicate(mOverflowBubbles, b -> b.getTaskId() == taskId);
    }

    /** @return the overflow bubble that matches the provided key. */
    @Nullable
    public Bubble getOverflowBubbleWithKey(String key) {
+0 −38
Original line number Diff line number Diff line
@@ -64,14 +64,6 @@ class BubbleTaskStackListener(
            }
            return@onActivityRestartAttempt
        }

        bubbleData.getOverflowBubbleWithTaskId(taskId)?.let { bubble ->
            if (isBubbleToFullscreen(task)) {
                moveCollapsedOverflowBubbleToFullscreen(bubble, task)
            } else {
                selectAndExpandOverflowBubble(bubble, task)
            }
        }
    }

    /** Selects and expands a bubble that is currently in the stack. */
@@ -103,36 +95,6 @@ class BubbleTaskStackListener(
        collapsedBubbleToFullscreenInternal(bubble, task)
    }

    /** Selects and expands a bubble that is currently in the overflow. */
    private fun selectAndExpandOverflowBubble(
        bubble: Bubble,
        task: ActivityManager.RunningTaskInfo,
    ) {
        ProtoLog.d(
            WM_SHELL_BUBBLES,
            "selectAndExpandOverflowBubble - taskId=%d selecting matching overflow bubble=%s",
            task.taskId,
            bubble.key,
        )
        bubbleController.promoteBubbleFromOverflow(bubble)
        bubbleData.setExpanded(true)
    }

    /** Moves a collapsed overflow bubble to fullscreen. */
    private fun moveCollapsedOverflowBubbleToFullscreen(
        bubble: Bubble,
        task: ActivityManager.RunningTaskInfo,
    ) {
        ProtoLog.d(
            WM_SHELL_BUBBLES,
            "moveCollapsedOverflowBubbleToFullscreen - taskId=%d " +
                    "moving matching overflow bubble=%s to fullscreen",
            task.taskId,
            bubble.key,
        )
        collapsedBubbleToFullscreenInternal(bubble, task)
    }

    /** Internal function to move a collapsed bubble to fullscreen task. */
    private fun collapsedBubbleToFullscreenInternal(
        bubble: Bubble,
+16 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.wm.shell.bubbles;

import static android.app.ActivityTaskManager.INVALID_TASK_ID;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
@@ -297,6 +299,20 @@ public class BubbleTest extends ShellTestCase {
        assertThat(bubbleInfo.getPackageName()).isEqualTo(bubble.getPackageName());
    }

    @Test
    public void testCleanupTaskView() {
        // Create a bubble with a task id
        TaskInfo info = mock(TaskInfo.class);
        info.taskId = 123;
        info.baseActivity = new ComponentName(mContext, "SomeActivity");
        Bubble bubble = Bubble.createTaskBubble(info, new UserHandle(1),
                null /* icon */, mMainExecutor, mBgExecutor);
        assertThat(bubble.getTaskId()).isEqualTo(123);

        bubble.cleanupTaskView();
        assertThat(bubble.getTaskId()).isEqualTo(INVALID_TASK_ID);
    }

    private Intent createIntent() {
        Intent intent = new Intent(mContext, BubblesTestActivity.class);
        intent.setPackage(mContext.getPackageName());