Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt +122 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.res.Resources import android.graphics.Color import android.graphics.drawable.Icon import android.os.UserHandle import android.platform.test.flag.junit.SetFlagsRule import android.view.IWindowManager import android.view.WindowManager import android.view.WindowManagerGlobal Loading @@ -33,6 +34,7 @@ import androidx.test.platform.app.InstrumentationRegistry import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.protolog.common.ProtoLog import com.android.launcher3.icons.BubbleIconFactory import com.android.wm.shell.Flags import com.android.wm.shell.R import com.android.wm.shell.bubbles.Bubbles.SysuiProxy import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix Loading @@ -44,19 +46,24 @@ import com.android.wm.shell.taskview.TaskViewTaskController import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor import org.junit.After import java.util.concurrent.Semaphore import java.util.concurrent.TimeUnit import java.util.function.Consumer import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import java.util.concurrent.Semaphore import java.util.concurrent.TimeUnit import java.util.function.Consumer /** Unit tests for [BubbleStackView]. */ @SmallTest @RunWith(AndroidJUnit4::class) class BubbleStackViewTest { @get:Rule val setFlagsRule = SetFlagsRule() private val context = ApplicationProvider.getApplicationContext<Context>() private lateinit var positioner: BubblePositioner private lateinit var iconFactory: BubbleIconFactory Loading @@ -66,6 +73,8 @@ class BubbleStackViewTest { private lateinit var windowManager: IWindowManager private lateinit var bubbleTaskViewFactory: BubbleTaskViewFactory private lateinit var bubbleData: BubbleData private lateinit var bubbleStackViewManager: FakeBubbleStackViewManager private var sysuiProxy = mock<SysuiProxy>() @Before fun setUp() { Loading @@ -86,7 +95,6 @@ class BubbleStackViewTest { ) ) positioner = BubblePositioner(context, windowManager) val bubbleStackViewManager = FakeBubbleStackViewManager() bubbleData = BubbleData( context, Loading @@ -95,8 +103,7 @@ class BubbleStackViewTest { BubbleEducationController(context), shellExecutor ) val sysuiProxy = mock<SysuiProxy>() bubbleStackViewManager = FakeBubbleStackViewManager() expandedViewManager = FakeBubbleExpandedViewManager() bubbleTaskViewFactory = FakeBubbleTaskViewFactory() bubbleStackView = Loading Loading @@ -234,6 +241,115 @@ class BubbleStackViewTest { .inOrder() } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun testCreateStackView_noOverflowContents_noOverflow() { bubbleStackView = BubbleStackView( context, bubbleStackViewManager, positioner, bubbleData, null, FloatingContentCoordinator(), { sysuiProxy }, shellExecutor ) assertThat(bubbleData.overflowBubbles).isEmpty() val bubbleOverflow = bubbleData.overflow // Overflow shouldn't be attached assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isEqualTo(-1) } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun testCreateStackView_hasOverflowContents_hasOverflow() { // Add a bubble to the overflow val bubble1 = createAndInflateChatBubble(key = "bubble1") bubbleData.notificationEntryUpdated(bubble1, false, false) bubbleData.dismissBubbleWithKey(bubble1.key, Bubbles.DISMISS_USER_GESTURE) assertThat(bubbleData.overflowBubbles).isNotEmpty() bubbleStackView = BubbleStackView( context, bubbleStackViewManager, positioner, bubbleData, null, FloatingContentCoordinator(), { sysuiProxy }, shellExecutor ) val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } @DisableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun testCreateStackView_noOverflowContents_hasOverflow() { bubbleStackView = BubbleStackView( context, bubbleStackViewManager, positioner, bubbleData, null, FloatingContentCoordinator(), { sysuiProxy }, shellExecutor ) assertThat(bubbleData.overflowBubbles).isEmpty() val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun showOverflow_true() { InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(true) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun showOverflow_false() { InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(true) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(false) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() // The overflow should've been removed assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isEqualTo(-1) } @DisableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun showOverflow_ignored() { InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(false) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() // showOverflow should've been ignored, so the overflow would be attached val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } private fun createAndInflateChatBubble(key: String): Bubble { val icon = Icon.createWithResource(context.resources, R.drawable.bubble_ic_overflow_button) val shortcutInfo = ShortcutInfo.Builder(context, "fakeId").setIcon(icon).build() Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +1 −1 Original line number Diff line number Diff line Loading @@ -3541,7 +3541,7 @@ public class BubbleStackView extends FrameLayout */ int getBubbleIndex(@Nullable BubbleViewProvider provider) { if (provider == null) { return 0; return -1; } return mBubbleContainer.indexOfChild(provider.getIconView()); } Loading packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +61 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ import com.android.systemui.util.FakeEventLog; import com.android.systemui.util.settings.FakeGlobalSettings; import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.Flags; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.bubbles.Bubble; Loading Loading @@ -2300,6 +2301,66 @@ public class BubblesTest extends SysuiTestCase { assertThat(bubbleStateListener.mStateChangeCalls).isEqualTo(0); } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test public void showBubbleOverflow_hasOverflowContents() { mEntryListener.onEntryAdded(mRow); mEntryListener.onEntryUpdated(mRow, /* fromSystem= */ true); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); BubbleStackView stackView = mBubbleController.getStackView(); spyOn(stackView); // Dismiss the bubble so it's in the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); verify(stackView).showOverflow(eq(true)); } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test public void showBubbleOverflow_isEmpty() { mEntryListener.onEntryAdded(mRow); mEntryListener.onEntryUpdated(mRow, /* fromSystem= */ true); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); BubbleStackView stackView = mBubbleController.getStackView(); spyOn(stackView); // Dismiss the bubble so it's in the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); verify(stackView).showOverflow(eq(true)); // Cancel the bubble so it's removed from the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); verify(stackView).showOverflow(eq(false)); } @DisableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test public void showBubbleOverflow_ignored() { mEntryListener.onEntryAdded(mRow); mEntryListener.onEntryUpdated(mRow, /* fromSystem= */ true); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); BubbleStackView stackView = mBubbleController.getStackView(); spyOn(stackView); // Dismiss the bubble so it's in the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); // Cancel the bubble so it's removed from the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); // Show overflow should never be called if the flag is off verify(stackView, never()).showOverflow(anyBoolean()); } /** Creates a bubble using the userId and package. */ private Bubble createBubble(int userId, String pkg) { final UserHandle userHandle = new UserHandle(userId); Loading Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt +122 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.res.Resources import android.graphics.Color import android.graphics.drawable.Icon import android.os.UserHandle import android.platform.test.flag.junit.SetFlagsRule import android.view.IWindowManager import android.view.WindowManager import android.view.WindowManagerGlobal Loading @@ -33,6 +34,7 @@ import androidx.test.platform.app.InstrumentationRegistry import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.protolog.common.ProtoLog import com.android.launcher3.icons.BubbleIconFactory import com.android.wm.shell.Flags import com.android.wm.shell.R import com.android.wm.shell.bubbles.Bubbles.SysuiProxy import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix Loading @@ -44,19 +46,24 @@ import com.android.wm.shell.taskview.TaskViewTaskController import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor import org.junit.After import java.util.concurrent.Semaphore import java.util.concurrent.TimeUnit import java.util.function.Consumer import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import java.util.concurrent.Semaphore import java.util.concurrent.TimeUnit import java.util.function.Consumer /** Unit tests for [BubbleStackView]. */ @SmallTest @RunWith(AndroidJUnit4::class) class BubbleStackViewTest { @get:Rule val setFlagsRule = SetFlagsRule() private val context = ApplicationProvider.getApplicationContext<Context>() private lateinit var positioner: BubblePositioner private lateinit var iconFactory: BubbleIconFactory Loading @@ -66,6 +73,8 @@ class BubbleStackViewTest { private lateinit var windowManager: IWindowManager private lateinit var bubbleTaskViewFactory: BubbleTaskViewFactory private lateinit var bubbleData: BubbleData private lateinit var bubbleStackViewManager: FakeBubbleStackViewManager private var sysuiProxy = mock<SysuiProxy>() @Before fun setUp() { Loading @@ -86,7 +95,6 @@ class BubbleStackViewTest { ) ) positioner = BubblePositioner(context, windowManager) val bubbleStackViewManager = FakeBubbleStackViewManager() bubbleData = BubbleData( context, Loading @@ -95,8 +103,7 @@ class BubbleStackViewTest { BubbleEducationController(context), shellExecutor ) val sysuiProxy = mock<SysuiProxy>() bubbleStackViewManager = FakeBubbleStackViewManager() expandedViewManager = FakeBubbleExpandedViewManager() bubbleTaskViewFactory = FakeBubbleTaskViewFactory() bubbleStackView = Loading Loading @@ -234,6 +241,115 @@ class BubbleStackViewTest { .inOrder() } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun testCreateStackView_noOverflowContents_noOverflow() { bubbleStackView = BubbleStackView( context, bubbleStackViewManager, positioner, bubbleData, null, FloatingContentCoordinator(), { sysuiProxy }, shellExecutor ) assertThat(bubbleData.overflowBubbles).isEmpty() val bubbleOverflow = bubbleData.overflow // Overflow shouldn't be attached assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isEqualTo(-1) } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun testCreateStackView_hasOverflowContents_hasOverflow() { // Add a bubble to the overflow val bubble1 = createAndInflateChatBubble(key = "bubble1") bubbleData.notificationEntryUpdated(bubble1, false, false) bubbleData.dismissBubbleWithKey(bubble1.key, Bubbles.DISMISS_USER_GESTURE) assertThat(bubbleData.overflowBubbles).isNotEmpty() bubbleStackView = BubbleStackView( context, bubbleStackViewManager, positioner, bubbleData, null, FloatingContentCoordinator(), { sysuiProxy }, shellExecutor ) val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } @DisableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun testCreateStackView_noOverflowContents_hasOverflow() { bubbleStackView = BubbleStackView( context, bubbleStackViewManager, positioner, bubbleData, null, FloatingContentCoordinator(), { sysuiProxy }, shellExecutor ) assertThat(bubbleData.overflowBubbles).isEmpty() val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun showOverflow_true() { InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(true) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun showOverflow_false() { InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(true) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(false) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() // The overflow should've been removed assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isEqualTo(-1) } @DisableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test fun showOverflow_ignored() { InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.showOverflow(false) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() // showOverflow should've been ignored, so the overflow would be attached val bubbleOverflow = bubbleData.overflow assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1) } private fun createAndInflateChatBubble(key: String): Bubble { val icon = Icon.createWithResource(context.resources, R.drawable.bubble_ic_overflow_button) val shortcutInfo = ShortcutInfo.Builder(context, "fakeId").setIcon(icon).build() Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +1 −1 Original line number Diff line number Diff line Loading @@ -3541,7 +3541,7 @@ public class BubbleStackView extends FrameLayout */ int getBubbleIndex(@Nullable BubbleViewProvider provider) { if (provider == null) { return 0; return -1; } return mBubbleContainer.indexOfChild(provider.getIconView()); } Loading
packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +61 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ import com.android.systemui.util.FakeEventLog; import com.android.systemui.util.settings.FakeGlobalSettings; import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.Flags; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.bubbles.Bubble; Loading Loading @@ -2300,6 +2301,66 @@ public class BubblesTest extends SysuiTestCase { assertThat(bubbleStateListener.mStateChangeCalls).isEqualTo(0); } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test public void showBubbleOverflow_hasOverflowContents() { mEntryListener.onEntryAdded(mRow); mEntryListener.onEntryUpdated(mRow, /* fromSystem= */ true); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); BubbleStackView stackView = mBubbleController.getStackView(); spyOn(stackView); // Dismiss the bubble so it's in the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); verify(stackView).showOverflow(eq(true)); } @EnableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test public void showBubbleOverflow_isEmpty() { mEntryListener.onEntryAdded(mRow); mEntryListener.onEntryUpdated(mRow, /* fromSystem= */ true); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); BubbleStackView stackView = mBubbleController.getStackView(); spyOn(stackView); // Dismiss the bubble so it's in the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); verify(stackView).showOverflow(eq(true)); // Cancel the bubble so it's removed from the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); verify(stackView).showOverflow(eq(false)); } @DisableFlags(Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW) @Test public void showBubbleOverflow_ignored() { mEntryListener.onEntryAdded(mRow); mEntryListener.onEntryUpdated(mRow, /* fromSystem= */ true); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); BubbleStackView stackView = mBubbleController.getStackView(); spyOn(stackView); // Dismiss the bubble so it's in the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE); assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty(); // Cancel the bubble so it's removed from the overflow mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); // Show overflow should never be called if the flag is off verify(stackView, never()).showOverflow(anyBoolean()); } /** Creates a bubble using the userId and package. */ private Bubble createBubble(int userId, String pkg) { final UserHandle userHandle = new UserHandle(userId); Loading