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

Commit 705f710f authored by Louis Chang's avatar Louis Chang
Browse files

Fix back gesture not working after bubble relaunch to fullscreen

There's a race that the TaskOrganizer#onTaskInfoChanged is called
before TaskStackListener#onActivityRestartAttempt, which removes the
bubble and taskView without reset the Task state in WM Core.

Bug: 416050605
Test: BubbleTaskViewListenerTest
Flag: com.android.wm.shell.enable_create_any_bubble
Change-Id: Ieef3407cb8f57e45dcd479e87f8dc9bb80407489
parent 13c4ea41
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.bubbles

import android.app.ActivityManager
import android.app.ActivityOptions
import android.app.Notification
import android.app.PendingIntent
@@ -46,11 +47,11 @@ import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING
import com.android.wm.shell.R
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.bubbles.Bubbles.BubbleMetadataFlagListener
import com.android.wm.shell.bubbles.util.verifyEnterBubbleTransaction
import com.android.wm.shell.common.TestShellExecutor
import com.android.wm.shell.taskview.TaskView
import com.android.wm.shell.taskview.TaskViewController
import com.android.wm.shell.taskview.TaskViewTaskController
import com.android.wm.shell.bubbles.util.verifyEnterBubbleTransaction
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
@@ -89,9 +90,11 @@ class BubbleTaskViewListenerTest {
        on { asBinder() } doReturn mock<IBinder>()
    })
    private var taskViewController = mock<TaskViewController>()
    private val taskInfo = mock<ActivityManager.RunningTaskInfo>()
    private val taskViewTaskController = mock<TaskViewTaskController> {
        on { taskOrganizer } doReturn taskOrganizer
        on { taskToken } doReturn taskViewTaskToken
        on { taskInfo } doReturn taskInfo
    }
    private var listenerCallback = mock<BubbleTaskViewListener.Callback>()
    private var expandedViewManager = mock<BubbleExpandedViewManager>()
@@ -490,7 +493,9 @@ class BubbleTaskViewListenerTest {

    @Test
    fun onTaskRemovalStarted() {
        val mockTaskView = mock<TaskView>()
        val mockTaskView = mock<TaskView>() {
            on { getController() } doReturn taskViewTaskController
        }
        bubbleTaskView = BubbleTaskView(mockTaskView, mainExecutor)

        bubbleTaskViewListener =
@@ -511,12 +516,16 @@ class BubbleTaskViewListenerTest {
        getInstrumentation().waitForIdleSync()
        verify(mockTaskView).startActivity(any(), anyOrNull(), any(), any())

        taskInfo.isRunning = true
        taskInfo.token = taskViewTaskToken
        whenever(expandedViewManager.shouldBeAppBubble(eq(taskInfo))).doReturn(true)
        getInstrumentation().runOnMainSync {
            bubbleTaskViewListener.onTaskRemovalStarted(1)
        }

        verify(expandedViewManager).removeBubble(eq(b.key), eq(Bubbles.DISMISS_TASK_FINISHED))
        verify(mockTaskView).release()
        verify(taskOrganizer).setInterceptBackPressedOnTaskRoot(eq(taskViewTaskToken), eq(false))
        assertThat(parentView.lastRemovedView).isEqualTo(mockTaskView)
        assertThat(bubbleTaskViewListener.taskView).isNull()
        verify(listenerCallback).onTaskRemovalStarted()
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.bubbles

import android.app.ActivityManager
import android.window.WindowContainerToken
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
import java.util.Collections
@@ -56,4 +57,8 @@ class FakeBubbleExpandedViewManager(var bubbleBar: Boolean = false, var expanded
    override fun getAppBubbleRootTaskToken(): WindowContainerToken? {
        return null
    }

    override fun shouldBeAppBubble(taskInfo: ActivityManager.RunningTaskInfo): Boolean {
        return false
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.bubbles

import android.app.ActivityManager
import android.window.WindowContainerToken
import com.android.wm.shell.shared.bubbles.BubbleBarLocation

@@ -38,6 +39,7 @@ interface BubbleExpandedViewManager {
        @BubbleBarLocation.UpdateSource source: Int,
    )
    fun getAppBubbleRootTaskToken(): WindowContainerToken?
    fun shouldBeAppBubble(taskInfo: ActivityManager.RunningTaskInfo): Boolean

    companion object {
        /**
@@ -96,6 +98,9 @@ interface BubbleExpandedViewManager {

                override fun getAppBubbleRootTaskToken(): WindowContainerToken? =
                    controller.appBubbleRootTaskInfo?.token

                override fun shouldBeAppBubble(taskInfo: ActivityManager.RunningTaskInfo): Boolean =
                    controller.shouldBeAppBubble(taskInfo)
            }
        }
    }
+12 −0
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@ import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;

import static com.android.wm.shell.bubbles.util.BubbleUtilsKt.getEnterBubbleTransaction;
import static com.android.wm.shell.bubbles.util.BubbleUtilsKt.getExitBubbleTransaction;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES;

import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
@@ -236,6 +238,16 @@ public class BubbleTaskViewListener implements TaskView.Listener {
            mExpandedViewManager.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED);
        }
        if (mTaskView != null) {
            final TaskViewTaskController tvc = mTaskView.getController();
            final ActivityManager.RunningTaskInfo taskInfo = tvc.getTaskInfo();
            if (taskInfo != null && taskInfo.isRunning
                    && mExpandedViewManager.shouldBeAppBubble(taskInfo)) {
                final WindowContainerTransaction wct = getExitBubbleTransaction(taskInfo.token,
                        mTaskView.getCaptionInsetsOwner());
                tvc.getTaskOrganizer().applyTransaction(wct);
                tvc.getTaskOrganizer().setInterceptBackPressedOnTaskRoot(taskInfo.token,
                        false /* interceptBackPressed */);
            }
            mTaskView.release();
            ((ViewGroup) mParentView).removeView(mTaskView);
            mTaskView = null;