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

Commit 377469f0 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Consolidate Bubble WCT" into main

parents bd2962bd 886bbddb
Loading
Loading
Loading
Loading
+26 −42
Original line number Diff line number Diff line
@@ -859,8 +859,9 @@ public final class WindowContainerTransaction implements Parcelable {
    @NonNull
    public WindowContainerTransaction setDisableLaunchAdjacent(
            @NonNull WindowContainerToken container, boolean disabled) {
        mHierarchyOps.add(HierarchyOp.createForSetDisableLaunchAdjacent(container.asBinder(),
                disabled));
        final Change chg = getOrCreateChange(container.asBinder());
        chg.mChangeMask |= Change.CHANGE_DISABLE_LAUNCH_ADJACENT;
        chg.mDisableLaunchAdjacent = disabled;
        return this;
    }

@@ -1379,6 +1380,7 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int CHANGE_FORCE_EXCLUDED_FROM_RECENTS = 1 << 9;
        public static final int CHANGE_LAUNCH_NEXT_TO_BUBBLE = 1 << 10;
        public static final int CHANGE_DISABLE_PIP = 1 << 11;
        public static final int CHANGE_DISABLE_LAUNCH_ADJACENT = 1 << 12;

        @IntDef(flag = true, prefix = { "CHANGE_" }, value = {
                CHANGE_FOCUSABLE,
@@ -1393,6 +1395,7 @@ public final class WindowContainerTransaction implements Parcelable {
                CHANGE_FORCE_EXCLUDED_FROM_RECENTS,
                CHANGE_LAUNCH_NEXT_TO_BUBBLE,
                CHANGE_DISABLE_PIP,
                CHANGE_DISABLE_LAUNCH_ADJACENT,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface ChangeMask {}
@@ -1405,6 +1408,7 @@ public final class WindowContainerTransaction implements Parcelable {
        private boolean mDragResizing = false;
        private boolean mForceExcludedFromRecents = false;
        private boolean mDisablePip = false;
        private boolean mDisableLaunchAdjacent = false;

        private @ChangeMask int mChangeMask = 0;
        private @ActivityInfo.Config int mConfigSetMask = 0;
@@ -1432,6 +1436,7 @@ public final class WindowContainerTransaction implements Parcelable {
            mForceExcludedFromRecents = in.readBoolean();
            mLaunchNextToBubble = in.readBoolean();
            mDisablePip = in.readBoolean();
            mDisableLaunchAdjacent = in.readBoolean();
            mChangeMask = in.readInt();
            mConfigSetMask = in.readInt();
            mWindowSetMask = in.readInt();
@@ -1486,6 +1491,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((other.mChangeMask & CHANGE_DISABLE_PIP) != 0) {
                mDisablePip = other.mDisablePip;
            }
            if ((other.mChangeMask & CHANGE_DISABLE_LAUNCH_ADJACENT) != 0) {
                mDisableLaunchAdjacent = other.mDisableLaunchAdjacent;
            }
            mChangeMask |= other.mChangeMask;
            if (other.mActivityWindowingMode >= WINDOWING_MODE_UNDEFINED) {
                mActivityWindowingMode = other.mActivityWindowingMode;
@@ -1581,6 +1589,14 @@ public final class WindowContainerTransaction implements Parcelable {
            return mDisablePip;
        }

        /**
         * Gets whether activities are disabled to be started in adjacent tasks for the specified
         * root of any child tasks .
         */
        public boolean getDisableLaunchAdjacent() {
            return mDisableLaunchAdjacent;
        }

        /** Gets whether the config should be sent to the client at the end of the transition. */
        public boolean getConfigAtTransitionEnd() {
            return mConfigAtTransitionEnd;
@@ -1657,6 +1673,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((mChangeMask & CHANGE_DISABLE_PIP) != 0) {
                sb.append("disablePip:" + mDisablePip + ",");
            }
            if ((mChangeMask & CHANGE_DISABLE_LAUNCH_ADJACENT) != 0) {
                sb.append("disableLaunchAdjacent:" + mDisableLaunchAdjacent + ",");
            }
            if (mBoundsChangeTransaction != null) {
                sb.append("hasBoundsTransaction,");
            }
@@ -1687,6 +1706,7 @@ public final class WindowContainerTransaction implements Parcelable {
            dest.writeBoolean(mForceExcludedFromRecents);
            dest.writeBoolean(mLaunchNextToBubble);
            dest.writeBoolean(mDisablePip);
            dest.writeBoolean(mDisableLaunchAdjacent);
            dest.writeInt(mChangeMask);
            dest.writeInt(mConfigSetMask);
            dest.writeInt(mWindowSetMask);
@@ -1751,11 +1771,10 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int HIERARCHY_OP_TYPE_RESTORE_BACK_NAVIGATION = 20;
        public static final int HIERARCHY_OP_TYPE_SET_EXCLUDE_INSETS_TYPES = 21;
        public static final int HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE = 22;
        public static final int HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT = 23;
        public static final int HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK = 24;
        public static final int HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY = 25;
        public static final int HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS = 26;
        public static final int HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE = 27;
        public static final int HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK = 23;
        public static final int HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY = 24;
        public static final int HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS = 25;
        public static final int HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE = 26;

        @IntDef(prefix = {"HIERARCHY_OP_TYPE_"}, value = {
                HIERARCHY_OP_TYPE_REPARENT,
@@ -1781,7 +1800,6 @@ public final class WindowContainerTransaction implements Parcelable {
                HIERARCHY_OP_TYPE_RESTORE_BACK_NAVIGATION,
                HIERARCHY_OP_TYPE_SET_EXCLUDE_INSETS_TYPES,
                HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE,
                HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT,
                HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK,
                HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY,
                HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS,
@@ -1872,8 +1890,6 @@ public final class WindowContainerTransaction implements Parcelable {
        private @InsetsType int mForciblyShowingInsetsTypes;
        private @InsetsType int mForciblyHidingInsetsTypes;

        private boolean mLaunchAdjacentDisabled;

        @Nullable
        private Rect mSafeRegionBounds;

@@ -1977,16 +1993,6 @@ public final class WindowContainerTransaction implements Parcelable {
                    .build();
        }

        /** Creates a hierarchy op for disabling launch adjacent. */
        @NonNull
        public static HierarchyOp createForSetDisableLaunchAdjacent(@Nullable IBinder container,
                boolean disabled) {
            return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT)
                    .setContainer(container)
                    .setLaunchAdjacentDisabled(disabled)
                    .build();
        }

        /** Creates a hierarchy op for deleting a task **/
        @NonNull
        public static HierarchyOp createForRemoveTask(@NonNull IBinder container) {
@@ -2082,7 +2088,6 @@ public final class WindowContainerTransaction implements Parcelable {
            mExcludeInsetsTypes = copy.mExcludeInsetsTypes;
            mForciblyShowingInsetsTypes = copy.mForciblyShowingInsetsTypes;
            mForciblyHidingInsetsTypes = copy.mForciblyHidingInsetsTypes;
            mLaunchAdjacentDisabled = copy.mLaunchAdjacentDisabled;
            mSafeRegionBounds = copy.mSafeRegionBounds;
        }

@@ -2112,7 +2117,6 @@ public final class WindowContainerTransaction implements Parcelable {
            mExcludeInsetsTypes = in.readInt();
            mForciblyShowingInsetsTypes = in.readInt();
            mForciblyHidingInsetsTypes = in.readInt();
            mLaunchAdjacentDisabled = in.readBoolean();
            mSafeRegionBounds = in.readTypedObject(Rect.CREATOR);
        }

@@ -2238,11 +2242,6 @@ public final class WindowContainerTransaction implements Parcelable {
            return mForciblyHidingInsetsTypes;
        }

        /** Denotes whether launch-adjacent flag is respected from this task or its children */
        public boolean isLaunchAdjacentDisabled() {
            return mLaunchAdjacentDisabled;
        }

        /** Denotes the safe region bounds */
        @Nullable
        public Rect getSafeRegionBounds() {
@@ -2259,8 +2258,6 @@ public final class WindowContainerTransaction implements Parcelable {
                case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "setAdjacentRoots";
                case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "launchTask";
                case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: return "setAdjacentFlagRoot";
                case HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT:
                    return "setDisableLaunchAdjacent";
                case HIERARCHY_OP_TYPE_PENDING_INTENT: return "pendingIntent";
                case HIERARCHY_OP_TYPE_START_SHORTCUT: return "startShortcut";
                case HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER: return "restoreTransientOrder";
@@ -2331,10 +2328,6 @@ public final class WindowContainerTransaction implements Parcelable {
                case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT:
                    sb.append("container=").append(mContainer).append(" clearRoot=").append(mToTop);
                    break;
                case HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT:
                    sb.append("container=").append(mContainer).append(" disabled=")
                            .append(mLaunchAdjacentDisabled);
                    break;
                case HIERARCHY_OP_TYPE_START_SHORTCUT:
                    sb.append("options=").append(mLaunchOptions)
                            .append(" info=").append(mShortcutInfo);
@@ -2436,7 +2429,6 @@ public final class WindowContainerTransaction implements Parcelable {
            dest.writeInt(mExcludeInsetsTypes);
            dest.writeInt(mForciblyShowingInsetsTypes);
            dest.writeInt(mForciblyHidingInsetsTypes);
            dest.writeBoolean(mLaunchAdjacentDisabled);
            dest.writeTypedObject(mSafeRegionBounds, flags);
        }

@@ -2524,8 +2516,6 @@ public final class WindowContainerTransaction implements Parcelable {
            private @InsetsType int mForciblyShowingInsetsTypes;
            private @InsetsType int mForciblyHidingInsetsTypes;

            private boolean mLaunchAdjacentDisabled;

            @Nullable
            private Rect mSafeRegionBounds;

@@ -2653,11 +2643,6 @@ public final class WindowContainerTransaction implements Parcelable {
                return this;
            }

            Builder setLaunchAdjacentDisabled(boolean disabled) {
                mLaunchAdjacentDisabled = disabled;
                return this;
            }

            Builder setSafeRegionBounds(Rect safeRegionBounds) {
                mSafeRegionBounds = safeRegionBounds;
                return this;
@@ -2694,7 +2679,6 @@ public final class WindowContainerTransaction implements Parcelable {
                hierarchyOp.mExcludeInsetsTypes = mExcludeInsetsTypes;
                hierarchyOp.mForciblyShowingInsetsTypes = mForciblyShowingInsetsTypes;
                hierarchyOp.mForciblyHidingInsetsTypes = mForciblyHidingInsetsTypes;
                hierarchyOp.mLaunchAdjacentDisabled = mLaunchAdjacentDisabled;
                hierarchyOp.mSafeRegionBounds = mSafeRegionBounds;
                return hierarchyOp;
            }
+6 −4
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ android_robolectric_test {
    // TODO(b/323188766): Include BubbleStackViewTest once the robolectric issue is fixed.
    exclude_srcs: ["src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt"],
    static_libs: [
        "WMShellTests-utils",
        "junit",
        "androidx.core_core-animation-testing",
        "androidx.test.runner",
@@ -66,20 +67,21 @@ android_test {
        "src/**/*.kt",
    ],
    static_libs: [
        "WMShellTests-utils",
        "WindowManager-Shell",
        "junit",
        "androidx.core_core-animation-testing",
        "androidx.test.runner",
        "androidx.test.rules",
        "androidx.test.ext.junit",
        "androidx.test.rules",
        "androidx.test.runner",
        "frameworks-base-testutils",
        "junit",
        "mockito-kotlin2",
        "mockito-target-extended-minus-junit4",
        "platform-parametric-runner-lib",
        "truth",
        "platform-test-annotations",
        "platform-test-rules",
        "testables",
        "truth",
    ],
    libs: [
        "android.test.base.stubs.system",
+20 −22
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.window.WindowContainerTransaction
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SmallTest
import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags.FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP
import com.android.window.flags.Flags.FLAG_EXCLUDE_TASK_FROM_RECENTS
import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING
import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TASK_VIEW_LISTENER
@@ -35,9 +36,9 @@ import com.android.wm.shell.ShellTaskOrganizer
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 com.google.common.util.concurrent.MoreExecutors.directExecutor
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -49,7 +50,13 @@ import org.mockito.kotlin.verify
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters

/** Tests for [BubbleExpandedView] */
/**
 * Tests for [BubbleExpandedView].
 *
 * Build/Install/Run:
 *  atest WMShellRobolectricTests:BubbleExpandedViewTest (on host)
 *  atest WMShellMultivalentTestsOnDevice:BubbleExpandedViewTest (on device)
 */
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
class BubbleExpandedViewTest(flags: FlagsParameterization) {
@@ -102,31 +109,22 @@ class BubbleExpandedViewTest(flags: FlagsParameterization) {
    }

    @Test
    @EnableFlags(FLAG_EXCLUDE_TASK_FROM_RECENTS)
    fun onTaskCreated_excludesTaskFromRecents() {
        bubbleTaskView.listener.onTaskCreated(123 /* taskId */, componentName)

        val wctCaptor = argumentCaptor<WindowContainerTransaction>()
        verify(taskOrganizer).applyTransaction(wctCaptor.capture())
        val wct = wctCaptor.lastValue
        val hasForceExcludedFromRecents = wct.changes.entries.stream()
            .filter { it.key.equals(taskViewTaskToken.asBinder()) }
            .anyMatch { it.value.forceExcludedFromRecents }
        assertTrue(hasForceExcludedFromRecents)
    }

    @Test
    @EnableFlags(FLAG_ENABLE_BUBBLE_ANYTHING)
    fun onTaskCreated_disallowFlagLaunchAdjacent() {
    @EnableFlags(
        FLAG_ENABLE_BUBBLE_ANYTHING,
        FLAG_EXCLUDE_TASK_FROM_RECENTS,
        FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP,
    )
    fun onTaskCreated_appliesWctToEnterBubble() {
        bubbleTaskView.listener.onTaskCreated(123 /* taskId */, componentName)

        val wctCaptor = argumentCaptor<WindowContainerTransaction>()
        verify(taskOrganizer).applyTransaction(wctCaptor.capture())
        val wct = wctCaptor.lastValue
        val hasDisableLaunchAdjacent = wct.hierarchyOps.stream()
            .filter { it.container.equals(taskViewTaskToken.asBinder()) }
            .anyMatch { it.isLaunchAdjacentDisabled }
        assertTrue(hasDisableLaunchAdjacent)
        verifyEnterBubbleTransaction(
            wct,
            taskViewTaskToken.asBinder(),
            isAppBubble = false,
        )
    }

    companion object {
+27 −16
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.wm.shell.bubbles
import android.app.ActivityManager
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.os.IBinder
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.window.IWindowContainerToken
import android.window.WindowContainerToken
@@ -26,12 +27,14 @@ import android.window.WindowContainerTransaction
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags.FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP
import com.android.window.flags.Flags.FLAG_EXCLUDE_TASK_FROM_RECENTS
import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING
import com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper
import com.android.wm.shell.taskview.TaskView
import com.android.wm.shell.taskview.TaskViewTaskController
import com.google.common.truth.Truth.assertThat
import org.junit.Assume.assumeTrue
import com.android.wm.shell.bubbles.util.verifyExitBubbleTransaction
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -42,7 +45,13 @@ import org.mockito.kotlin.mock
import org.mockito.kotlin.stub
import org.mockito.kotlin.verify

/** Unit tests for [BubbleTaskStackListener]. */
/**
 * Unit tests for [BubbleTaskStackListener].
 *
 * Build/Install/Run:
 *  atest WMShellRobolectricTests:BubbleTaskStackListenerTest (on host)
 *  atest WMShellMultivalentTestsOnDevice:BubbleTaskStackListenerTest (on device)
 */
@SmallTest
@RunWith(AndroidJUnit4::class)
class BubbleTaskStackListenerTest {
@@ -97,9 +106,13 @@ class BubbleTaskStackListenerTest {
    }

    @Test
    @EnableFlags(
        FLAG_ENABLE_CREATE_ANY_BUBBLE,
        FLAG_ENABLE_BUBBLE_ANYTHING,
        FLAG_EXCLUDE_TASK_FROM_RECENTS,
        FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP,
    )
    fun onActivityRestartAttempt_inStackAppBubbleToFullscreen_notifiesTaskRemoval() {
        assumeTrue(BubbleAnythingFlagHelper.enableCreateAnyBubbleWithForceExcludedFromRecents())

        task.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
        bubbleData.stub {
            on { getBubbleInStackWithTaskId(bubbleTaskId) } doReturn bubble
@@ -118,10 +131,7 @@ class BubbleTaskStackListenerTest {
            verify(taskOrganizer).applyTransaction(wctCaptor.capture())
            wctCaptor.lastValue
        }
        assertThat(wct.changes).hasSize(1)
        val chg = wct.changes.get(bubbleTaskToken.asBinder())
        assertThat(chg).isNotNull()
        assertThat(chg!!.forceExcludedFromRecents).isFalse()
        verifyExitBubbleTransaction(wct, bubbleTaskToken.asBinder())
        verify(taskOrganizer).setInterceptBackPressedOnTaskRoot(task.token, false /* intercept */)
        verify(taskViewTaskController).notifyTaskRemovalStarted(task)
    }
@@ -144,9 +154,13 @@ class BubbleTaskStackListenerTest {
    }

    @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() {
        assumeTrue(BubbleAnythingFlagHelper.enableCreateAnyBubbleWithForceExcludedFromRecents())

        task.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
        bubbleData.stub {
            on { getOverflowBubbleWithTaskId(bubbleTaskId) } doReturn bubble
@@ -165,10 +179,7 @@ class BubbleTaskStackListenerTest {
            verify(taskOrganizer).applyTransaction(wctCaptor.capture())
            wctCaptor.lastValue
        }
        assertThat(wct.changes).hasSize(1)
        val chg = wct.changes.get(bubbleTaskToken.asBinder())
        assertThat(chg).isNotNull()
        assertThat(chg!!.forceExcludedFromRecents).isFalse()
        verifyExitBubbleTransaction(wct, bubbleTaskToken.asBinder())
        verify(taskOrganizer).setInterceptBackPressedOnTaskRoot(task.token, false /* intercept */)
        verify(taskViewTaskController).notifyTaskRemovalStarted(task)
    }
+17 −31
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags.FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP
import com.android.window.flags.Flags.FLAG_EXCLUDE_TASK_FROM_RECENTS
import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING
import com.android.wm.shell.R
@@ -49,8 +50,8 @@ 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.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -69,6 +70,10 @@ import org.mockito.kotlin.whenever

/**
 * Tests for [BubbleTaskViewListener].
 *
 * Build/Install/Run:
 *  atest WMShellRobolectricTests:BubbleTaskViewListenerTest (on host)
 *  atest WMShellMultivalentTestsOnDevice:BubbleTaskViewListenerTest (on device)
 */
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -416,32 +421,12 @@ class BubbleTaskViewListenerTest {
    }

    @Test
    @EnableFlags(FLAG_EXCLUDE_TASK_FROM_RECENTS)
    fun onTaskCreated_excludesTaskFromRecents() {
        val b = createAppBubble()
        bubbleTaskViewListener.setBubble(b)
        getInstrumentation().runOnMainSync {
            bubbleTaskViewListener.onInitialized()
        }
        getInstrumentation().waitForIdleSync()

        getInstrumentation().runOnMainSync {
            bubbleTaskViewListener.onTaskCreated(123 /* taskId */, mock<ComponentName>())
        }
        getInstrumentation().waitForIdleSync()

        val wctCaptor = argumentCaptor<WindowContainerTransaction>()
        verify(taskOrganizer).applyTransaction(wctCaptor.capture())
        val wct = wctCaptor.lastValue
        val hasForceExcludedFromRecents = wct.changes.entries.stream()
            .filter { it.key.equals(taskViewTaskToken.asBinder()) }
            .anyMatch { it.value.forceExcludedFromRecents }
        assertTrue(hasForceExcludedFromRecents)
    }

    @Test
    @EnableFlags(FLAG_ENABLE_BUBBLE_ANYTHING)
    fun onTaskCreated_disallowFlagLaunchAdjacent() {
    @EnableFlags(
        FLAG_ENABLE_BUBBLE_ANYTHING,
        FLAG_EXCLUDE_TASK_FROM_RECENTS,
        FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP,
    )
    fun onTaskCreated_appliesWctToEnterBubble() {
        val b = createAppBubble()
        bubbleTaskViewListener.setBubble(b)
        getInstrumentation().runOnMainSync {
@@ -457,10 +442,11 @@ class BubbleTaskViewListenerTest {
        val wctCaptor = argumentCaptor<WindowContainerTransaction>()
        verify(taskOrganizer).applyTransaction(wctCaptor.capture())
        val wct = wctCaptor.lastValue
        val hasDisableLaunchAdjacent = wct.hierarchyOps.stream()
            .filter { it.container.equals(taskViewTaskToken.asBinder()) }
            .anyMatch { it.isLaunchAdjacentDisabled }
        assertTrue(hasDisableLaunchAdjacent)
        verifyEnterBubbleTransaction(
            wct,
            taskViewTaskToken.asBinder(),
            b.isApp || b.isShortcut,
        )
    }

    @Test
Loading