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

Commit 49219bb2 authored by Louis Chang's avatar Louis Chang Committed by Android (Google) Code Review
Browse files

Merge "Reordering the app bubble root task when needed" into main

parents 26d0a878 413f63f0
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -392,6 +392,7 @@ class BubbleControllerTest(flags: FlagsParameterization) {
                true, /* reorder */
                false, /* syncHiddenWithVisibilityOnReorder */
                false, /* nonBlockingIfPossible */
                null, /* overrideTransaction */
            )
        } else {
            verify(baseTransitions).setTaskViewVisible(taskView, true /* visible */)
@@ -414,6 +415,7 @@ class BubbleControllerTest(flags: FlagsParameterization) {
            any(), /* reorder */
            any(), /* syncHiddenWithVisibilityOnReorder */
            any(), /* nonBlockingIfPossible */
            any(), /* overrideTransaction */
        )
    }

@@ -461,7 +463,7 @@ class BubbleControllerTest(flags: FlagsParameterization) {
        assertThat(bubbleController.hasStableBubbleForTask(777)).isFalse()
    }

    @EnableFlags(FLAG_ROOT_TASK_FOR_BUBBLE)
    @EnableFlags(FLAG_ENABLE_CREATE_ANY_BUBBLE, FLAG_ROOT_TASK_FOR_BUBBLE)
    @Test
    fun shouldBeAppBubble_parentTaskMatchesBubbleRootTask_returnsTrue() {
        val bubbleController = createBubbleControllerWithRootTask(bubbleRootTaskId = 777)
@@ -470,7 +472,7 @@ class BubbleControllerTest(flags: FlagsParameterization) {
        assertThat(bubbleController.shouldBeAppBubble(taskInfo)).isTrue()
    }

    @EnableFlags(FLAG_ROOT_TASK_FOR_BUBBLE)
    @EnableFlags(FLAG_ENABLE_CREATE_ANY_BUBBLE, FLAG_ROOT_TASK_FOR_BUBBLE)
    @Test
    fun shouldBeAppBubble_parentTaskDoesNotMatchesBubbleRootTask_returnsFalse() {
        val bubbleController = createBubbleControllerWithRootTask(bubbleRootTaskId = 123)
@@ -1019,7 +1021,10 @@ class BubbleControllerTest(flags: FlagsParameterization) {
            captor.lastValue
        }

        val bubbleRootTask = ActivityManager.RunningTaskInfo().apply { taskId = bubbleRootTaskId }
        val bubbleRootTask = ActivityManager.RunningTaskInfo().apply {
            taskId = bubbleRootTaskId
            token = mock<WindowContainerToken>()
        }
        rootTaskListener.onTaskAppeared(bubbleRootTask, null /* leash */)

        return bubbleController
+4 −0
Original line number Diff line number Diff line
@@ -43,6 +43,10 @@ public class BubbleAnythingFlagHelper {

    /** Whether creating a root task to manage the bubble tasks in the Core. */
    public static boolean enableRootTaskForBubble() {
        if (!Flags.enableCreateAnyBubble()) {
            return false;
        }

        // This is needed to allow the activity behind the root task remains in RESUMED state.
        if (!com.android.window.flags.Flags.enableSeeThroughTaskFragments()) {
            return false;
+34 −2
Original line number Diff line number Diff line
@@ -641,6 +641,12 @@ public class BubbleController implements ConfigurationChangeListener,
                                return;
                            }
                            mAppBubbleRootTaskInfo = taskInfo;

                            final WindowContainerTransaction wct = new WindowContainerTransaction();
                            wct.reorder(taskInfo.token, false /* onTop */);
                            wct.setInterceptBackPressedOnTaskRoot(taskInfo.token,
                                    true /* interceptBackPressed */);
                            mTaskOrganizer.applyTransaction(wct);
                        }
                    });
        }
@@ -1470,7 +1476,7 @@ public class BubbleController implements ConfigurationChangeListener,

    /** Returns whether the given task should be an App Bubble */
    public boolean shouldBeAppBubble(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
        if (com.android.window.flags.Flags.rootTaskForBubble()) {
        if (BubbleAnythingFlagHelper.enableRootTaskForBubble()) {
            return mAppBubbleRootTaskInfo != null
                    && taskInfo.parentTaskId == mAppBubbleRootTaskInfo.taskId;
        }
@@ -2958,6 +2964,16 @@ public class BubbleController implements ConfigurationChangeListener,
        return mAppBubbleRootTaskInfo;
    }

    @Nullable
    public WindowContainerToken getAppBubbleRootTaskToken() {
        return mAppBubbleRootTaskInfo != null ? mAppBubbleRootTaskInfo.token : null;
    }

    @Nullable
    public boolean isAppBubbleRootTask(int taskId) {
        return mAppBubbleRootTaskInfo != null && mAppBubbleRootTaskInfo.taskId == taskId;
    }

    /**
     * Returns the id of the display to which the current Bubble view is attached if it is currently
     * showing, {@link INVALID_DISPLAY} otherwise.
@@ -3797,12 +3813,28 @@ public class BubbleController implements ConfigurationChangeListener,
                if (!visible && !mBubbleData.hasBubbleInStackWithTaskView(taskView)) {
                    return;
                }

                final WindowContainerTransaction wct;
                if (BubbleAnythingFlagHelper.enableRootTaskForBubble() && shouldBeAppBubble(
                        taskView.getTaskInfo())) {
                    wct = new WindowContainerTransaction();
                    if (visible) {
                        wct.reorder(taskView.getTaskInfo().token, true /* onTop */);
                        wct.setAlwaysOnTop(mAppBubbleRootTaskInfo.token, true /* alwaysOnTop */);
                    } else if (!mBubbleData.isExpanded()) {
                        wct.setAlwaysOnTop(mAppBubbleRootTaskInfo.token, false /* alwaysOnTop */);
                        wct.reorder(mAppBubbleRootTaskInfo.token, false /* onTop */);
                    }
                } else {
                    wct = null;
                }

                // The transaction to hide the TaskView can be executed on the executor to avoid
                // blocking the calling thread.
                final boolean nonBlocking = !visible;
                // Use reorder instead of always-on-top with hidden.
                mBaseTransitions.setTaskViewVisible(taskView, visible, true /* reorder */,
                        false /* toggleHiddenOnReorder */, nonBlocking);
                        false /* toggleHiddenOnReorder */, nonBlocking, wct);
            } else {
                mBaseTransitions.setTaskViewVisible(taskView, visible);
            }
+5 −5
Original line number Diff line number Diff line
@@ -231,7 +231,10 @@ public class BubbleExpandedView extends LinearLayout {
                    Rect launchBounds = new Rect();
                    mTaskView.getBoundsOnScreen(launchBounds);

                    final WindowContainerToken rootToken = mManager.getAppBubbleRootTaskToken();
                    if (rootToken == null) {
                        options.setTaskAlwaysOnTop(true /* alwaysOnTop */);
                    }
                    options.setPendingIntentBackgroundActivityStartMode(
                            MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS);

@@ -252,7 +255,6 @@ public class BubbleExpandedView extends LinearLayout {
                                // Needs to be mutable for the fillInIntent
                                PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
                                /* options= */ null);
                        final WindowContainerToken rootToken = mManager.getAppBubbleRootTaskToken();
                        if (rootToken != null) {
                            options.setLaunchRootTask(rootToken);
                        } else {
@@ -265,8 +267,6 @@ public class BubbleExpandedView extends LinearLayout {
                            options.setLaunchedFromBubble(true);
                            options.setApplyActivityFlagsForBubbles(true);
                        } else {
                            final WindowContainerToken rootToken =
                                    mManager.getAppBubbleRootTaskToken();
                            if (rootToken != null) {
                                options.setLaunchRootTask(rootToken);
                            } else {
@@ -321,7 +321,7 @@ public class BubbleExpandedView extends LinearLayout {
            final boolean isAppBubble = mBubble != null
                    && (mBubble.isApp() || mBubble.isShortcut());
            final WindowContainerTransaction wct = getEnterBubbleTransaction(
                    tvc.getTaskToken(), isAppBubble);
                    tvc.getTaskToken(), mManager.getAppBubbleRootTaskToken(), isAppBubble);
            tvc.getTaskOrganizer().applyTransaction(wct);

            // With the task org, the taskAppeared callback will only happen once the task has
+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ interface BubbleExpandedViewManager {
                }

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

                override fun shouldBeAppBubble(taskInfo: ActivityManager.RunningTaskInfo): Boolean =
                    controller.shouldBeAppBubble(taskInfo)
Loading