Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt +27 −1 Original line number Diff line number Diff line Loading @@ -70,20 +70,28 @@ import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor import java.util.Optional import org.junit.After import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.isA import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters /** Tests for [BubbleController] */ /** Tests for [BubbleController]. * * Build/Install/Run: * atest WMShellRobolectricTests:BubbleControllerTest (on host) * atest WMShellMultivalentTestsOnDevice:BubbleControllerTest (on device) */ @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class BubbleControllerTest(flags: FlagsParameterization) { Loading Loading @@ -319,6 +327,24 @@ class BubbleControllerTest(flags: FlagsParameterization) { } } @Test fun setTaskViewVisible_lastBubbleRemoval_skipsTaskViewHiding() { assumeTrue(BubbleAnythingFlagHelper.enableCreateAnyBubbleWithForceExcludedFromRecents()) val baseTransitions = mock<TaskViewTransitions>() val taskView = mock<TaskViewTaskController>() val bubbleTaskViewController = bubbleController.BubbleTaskViewController(baseTransitions) bubbleTaskViewController.setTaskViewVisible(taskView, false /* visible */) verify(baseTransitions, never()).setTaskViewVisible( any(), /* taskView */ any(), /* visible */ any(), /* reorder */ any(), /* syncHiddenWithVisibilityOnReorder */ ) } @Test fun hasStableBubbleForTask_whenBubbleIsCollapsed_returnsTrue() { val taskId = 777 Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +10 −0 Original line number Diff line number Diff line Loading @@ -3604,6 +3604,16 @@ public class BubbleController implements ConfigurationChangeListener, @Override public void setTaskViewVisible(TaskViewTaskController taskView, boolean visible) { if (BubbleAnythingFlagHelper.enableCreateAnyBubbleWithForceExcludedFromRecents()) { // When removing the last bubble, BubbleData has already removed the bubble from // the stack before this call occurs. Without this check, the TO_BACK transition // would trigger DesktopModeWindowDecorViewModel#onTaskChanging, which // incorrectly creates desktop mode window decorations for the removed bubble task // since AppHandleAndHeaderVisibilityHelper#allowedForTask can't find the task in // the bubble stack anymore. These decorations then "leak" because the task will be // closed in the subsequent CLOSE transition. See b/416655338 for more details. if (!visible && !mBubbleData.hasBubbleInStackWithTaskView(taskView)) { return; } // Use reorder instead of always-on-top with hidden. mBaseTransitions.setTaskViewVisible(taskView, visible, true /* reorder */, false /* toggleHiddenOnReorder */); Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +6 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.shared.bubbles.BubbleBarLocation; import com.android.wm.shell.shared.bubbles.BubbleBarUpdate; import com.android.wm.shell.shared.bubbles.RemovedBubble; import com.android.wm.shell.taskview.TaskViewTaskController; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -308,6 +309,11 @@ public class BubbleData { return !mBubbles.isEmpty(); } boolean hasBubbleInStackWithTaskView(@NonNull TaskViewTaskController taskView) { return getBubbleWithPredicate(mBubbles, b -> b.getTaskView().getController() == taskView) != null; } public boolean hasOverflowBubbles() { return !mOverflowBubbles.isEmpty(); } Loading Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt +27 −1 Original line number Diff line number Diff line Loading @@ -70,20 +70,28 @@ import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor import java.util.Optional import org.junit.After import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.isA import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters /** Tests for [BubbleController] */ /** Tests for [BubbleController]. * * Build/Install/Run: * atest WMShellRobolectricTests:BubbleControllerTest (on host) * atest WMShellMultivalentTestsOnDevice:BubbleControllerTest (on device) */ @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class BubbleControllerTest(flags: FlagsParameterization) { Loading Loading @@ -319,6 +327,24 @@ class BubbleControllerTest(flags: FlagsParameterization) { } } @Test fun setTaskViewVisible_lastBubbleRemoval_skipsTaskViewHiding() { assumeTrue(BubbleAnythingFlagHelper.enableCreateAnyBubbleWithForceExcludedFromRecents()) val baseTransitions = mock<TaskViewTransitions>() val taskView = mock<TaskViewTaskController>() val bubbleTaskViewController = bubbleController.BubbleTaskViewController(baseTransitions) bubbleTaskViewController.setTaskViewVisible(taskView, false /* visible */) verify(baseTransitions, never()).setTaskViewVisible( any(), /* taskView */ any(), /* visible */ any(), /* reorder */ any(), /* syncHiddenWithVisibilityOnReorder */ ) } @Test fun hasStableBubbleForTask_whenBubbleIsCollapsed_returnsTrue() { val taskId = 777 Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +10 −0 Original line number Diff line number Diff line Loading @@ -3604,6 +3604,16 @@ public class BubbleController implements ConfigurationChangeListener, @Override public void setTaskViewVisible(TaskViewTaskController taskView, boolean visible) { if (BubbleAnythingFlagHelper.enableCreateAnyBubbleWithForceExcludedFromRecents()) { // When removing the last bubble, BubbleData has already removed the bubble from // the stack before this call occurs. Without this check, the TO_BACK transition // would trigger DesktopModeWindowDecorViewModel#onTaskChanging, which // incorrectly creates desktop mode window decorations for the removed bubble task // since AppHandleAndHeaderVisibilityHelper#allowedForTask can't find the task in // the bubble stack anymore. These decorations then "leak" because the task will be // closed in the subsequent CLOSE transition. See b/416655338 for more details. if (!visible && !mBubbleData.hasBubbleInStackWithTaskView(taskView)) { return; } // Use reorder instead of always-on-top with hidden. mBaseTransitions.setTaskViewVisible(taskView, visible, true /* reorder */, false /* toggleHiddenOnReorder */); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +6 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.shared.bubbles.BubbleBarLocation; import com.android.wm.shell.shared.bubbles.BubbleBarUpdate; import com.android.wm.shell.shared.bubbles.RemovedBubble; import com.android.wm.shell.taskview.TaskViewTaskController; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -308,6 +309,11 @@ public class BubbleData { return !mBubbles.isEmpty(); } boolean hasBubbleInStackWithTaskView(@NonNull TaskViewTaskController taskView) { return getBubbleWithPredicate(mBubbles, b -> b.getTaskView().getController() == taskView) != null; } public boolean hasOverflowBubbles() { return !mOverflowBubbles.isEmpty(); } Loading