Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +48 −10 Original line number Diff line number Diff line Loading @@ -973,22 +973,60 @@ public class BubbleController implements ConfigurationChangeListener { } /** * Adds and expands bubble for a specific intent. These bubbles are <b>not</b> backed by a n * otification and remain until the user dismisses the bubble or bubble stack. Only one intent * bubble is supported at a time. * This method has different behavior depending on: * - if an app bubble exists * - if an app bubble is expanded * * If no app bubble exists, this will add and expand a bubble with the provided intent. The * intent must be explicit (i.e. include a package name or fully qualified component class name) * and the activity for it should be resizable. * * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is * expanded, calling this method will collapse it. If the app bubble is not expanded, calling * this method will expand it. * * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses * the bubble or bubble stack. * * Some notes: * - Only one app bubble is supported at a time * - Calling this method with a different intent than the existing app bubble will do nothing * * @param intent the intent to display in the bubble expanded view. */ public void showAppBubble(Intent intent) { if (intent == null || intent.getPackage() == null) return; public void showOrHideAppBubble(Intent intent) { if (intent == null || intent.getPackage() == null) { Log.w(TAG, "App bubble failed to show, invalid intent: " + intent + ((intent != null) ? " with package: " + intent.getPackage() : " ")); return; } PackageManager packageManager = getPackageManagerForUser(mContext, mCurrentUserId); if (!isResizableActivity(intent, packageManager, KEY_APP_BUBBLE)) return; Bubble existingAppBubble = mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE); if (existingAppBubble != null) { BubbleViewProvider selectedBubble = mBubbleData.getSelectedBubble(); if (isStackExpanded()) { if (selectedBubble != null && KEY_APP_BUBBLE.equals(selectedBubble.getKey())) { // App bubble is expanded, lets collapse collapseStack(); } else { // App bubble is not selected, select it mBubbleData.setSelectedBubble(existingAppBubble); } } else { // App bubble is not selected, select it & expand mBubbleData.setSelectedBubble(existingAppBubble); mBubbleData.setExpanded(true); } } else { // App bubble does not exist, lets add and expand it Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor); b.setShouldAutoExpand(true); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); } } /** * Fills the overflow bubbles by loading them from disk. Loading Loading @@ -1697,9 +1735,9 @@ public class BubbleController implements ConfigurationChangeListener { } @Override public void showAppBubble(Intent intent) { public void showOrHideAppBubble(Intent intent) { mMainExecutor.execute(() -> { BubbleController.this.showAppBubble(intent); BubbleController.this.showOrHideAppBubble(intent); }); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +20 −5 Original line number Diff line number Diff line Loading @@ -109,13 +109,28 @@ public interface Bubbles { void expandStackAndSelectBubble(Bubble bubble); /** * Adds and expands bubble that is not notification based, but instead based on an intent from * the app. The intent must be explicit (i.e. include a package name or fully qualified * component class name) and the activity for it should be resizable. * This method has different behavior depending on: * - if an app bubble exists * - if an app bubble is expanded * * @param intent the intent to populate the bubble. * If no app bubble exists, this will add and expand a bubble with the provided intent. The * intent must be explicit (i.e. include a package name or fully qualified component class name) * and the activity for it should be resizable. * * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is * expanded, calling this method will collapse it. If the app bubble is not expanded, calling * this method will expand it. * * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses * the bubble or bubble stack. * * Some notes: * - Only one app bubble is supported at a time * - Calling this method with a different intent than the existing app bubble will do nothing * * @param intent the intent to display in the bubble expanded view. */ void showAppBubble(Intent intent); void showOrHideAppBubble(Intent intent); /** * @return a bubble that matches the provided shortcutId, if one exists. Loading packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +4 −2 Original line number Diff line number Diff line Loading @@ -57,7 +57,9 @@ constructor( * If the keyguard is locked, notes will open as a full screen experience. A locked device has * no contextual information which let us use the whole screen space available. * * If no in multi-window or the keyguard is unlocked, notes will open as a floating experience. * If no in multi-window or the keyguard is unlocked, notes will open as a bubble OR it will be * collapsed if the notes bubble is already opened. * * That will let users open other apps in full screen, and take contextual notes. */ fun showNoteTask(isInMultiWindowMode: Boolean = false) { Loading @@ -75,7 +77,7 @@ constructor( context.startActivity(intent) } else { // TODO(b/254606432): Should include Intent.EXTRA_FLOATING_WINDOW_MODE parameter. bubbles.showAppBubble(intent) bubbles.showOrHideAppBubble(intent) } } Loading packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt +9 −9 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -102,7 +102,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(bubbles).showAppBubble(notesIntent) verify(bubbles).showOrHideAppBubble(notesIntent) verify(context, never()).startActivity(notesIntent) } Loading @@ -113,7 +113,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = true) verify(context).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -123,7 +123,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -133,7 +133,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -143,7 +143,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -153,7 +153,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -161,7 +161,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController(isEnabled = false).showNoteTask() verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -171,7 +171,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } // endregion Loading packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.service.notification.NotificationListenerService.REASON_AP import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -228,6 +229,8 @@ public class BubblesTest extends SysuiTestCase { private BubbleEntry mBubbleEntryUser11; private BubbleEntry mBubbleEntry2User11; private Intent mAppBubbleIntent; @Mock private ShellInit mShellInit; @Mock Loading Loading @@ -323,6 +326,9 @@ public class BubblesTest extends SysuiTestCase { mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry( mNotificationTestHelper.createBubble(handle)); mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class); mAppBubbleIntent.setPackage(mContext.getPackageName()); mZenModeConfig.suppressedVisualEffects = 0; when(mZenModeController.getConfig()).thenReturn(mZenModeConfig); Loading Loading @@ -1630,6 +1636,62 @@ public class BubblesTest extends SysuiTestCase { any(Bubble.class), anyBoolean(), anyBoolean()); } @Test public void testShowOrHideAppBubble_addsAndExpand() { assertThat(mBubbleController.isStackExpanded()).isFalse(); assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull(); mBubbleController.showOrHideAppBubble(mAppBubbleIntent); verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true), /* showInShade= */ eq(false)); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); } @Test public void testShowOrHideAppBubble_expandIfCollapsed() { mBubbleController.showOrHideAppBubble(mAppBubbleIntent); mBubbleController.updateBubble(mBubbleEntry); mBubbleController.collapseStack(); assertThat(mBubbleController.isStackExpanded()).isFalse(); // Calling this while collapsed will expand the app bubble mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); assertThat(mBubbleData.getBubbles().size()).isEqualTo(2); } @Test public void testShowOrHideAppBubble_collapseIfSelected() { mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); // Calling this while the app bubble is expanded should collapse the stack mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isFalse(); assertThat(mBubbleData.getBubbles().size()).isEqualTo(1); } @Test public void testShowOrHideAppBubble_selectIfNotSelected() { mBubbleController.showOrHideAppBubble(mAppBubbleIntent); mBubbleController.updateBubble(mBubbleEntry); mBubbleController.expandStackAndSelectBubble(mBubbleEntry); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey()); assertThat(mBubbleController.isStackExpanded()).isTrue(); mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); assertThat(mBubbleData.getBubbles().size()).isEqualTo(2); } /** 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/src/com/android/wm/shell/bubbles/BubbleController.java +48 −10 Original line number Diff line number Diff line Loading @@ -973,22 +973,60 @@ public class BubbleController implements ConfigurationChangeListener { } /** * Adds and expands bubble for a specific intent. These bubbles are <b>not</b> backed by a n * otification and remain until the user dismisses the bubble or bubble stack. Only one intent * bubble is supported at a time. * This method has different behavior depending on: * - if an app bubble exists * - if an app bubble is expanded * * If no app bubble exists, this will add and expand a bubble with the provided intent. The * intent must be explicit (i.e. include a package name or fully qualified component class name) * and the activity for it should be resizable. * * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is * expanded, calling this method will collapse it. If the app bubble is not expanded, calling * this method will expand it. * * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses * the bubble or bubble stack. * * Some notes: * - Only one app bubble is supported at a time * - Calling this method with a different intent than the existing app bubble will do nothing * * @param intent the intent to display in the bubble expanded view. */ public void showAppBubble(Intent intent) { if (intent == null || intent.getPackage() == null) return; public void showOrHideAppBubble(Intent intent) { if (intent == null || intent.getPackage() == null) { Log.w(TAG, "App bubble failed to show, invalid intent: " + intent + ((intent != null) ? " with package: " + intent.getPackage() : " ")); return; } PackageManager packageManager = getPackageManagerForUser(mContext, mCurrentUserId); if (!isResizableActivity(intent, packageManager, KEY_APP_BUBBLE)) return; Bubble existingAppBubble = mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE); if (existingAppBubble != null) { BubbleViewProvider selectedBubble = mBubbleData.getSelectedBubble(); if (isStackExpanded()) { if (selectedBubble != null && KEY_APP_BUBBLE.equals(selectedBubble.getKey())) { // App bubble is expanded, lets collapse collapseStack(); } else { // App bubble is not selected, select it mBubbleData.setSelectedBubble(existingAppBubble); } } else { // App bubble is not selected, select it & expand mBubbleData.setSelectedBubble(existingAppBubble); mBubbleData.setExpanded(true); } } else { // App bubble does not exist, lets add and expand it Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor); b.setShouldAutoExpand(true); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); } } /** * Fills the overflow bubbles by loading them from disk. Loading Loading @@ -1697,9 +1735,9 @@ public class BubbleController implements ConfigurationChangeListener { } @Override public void showAppBubble(Intent intent) { public void showOrHideAppBubble(Intent intent) { mMainExecutor.execute(() -> { BubbleController.this.showAppBubble(intent); BubbleController.this.showOrHideAppBubble(intent); }); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +20 −5 Original line number Diff line number Diff line Loading @@ -109,13 +109,28 @@ public interface Bubbles { void expandStackAndSelectBubble(Bubble bubble); /** * Adds and expands bubble that is not notification based, but instead based on an intent from * the app. The intent must be explicit (i.e. include a package name or fully qualified * component class name) and the activity for it should be resizable. * This method has different behavior depending on: * - if an app bubble exists * - if an app bubble is expanded * * @param intent the intent to populate the bubble. * If no app bubble exists, this will add and expand a bubble with the provided intent. The * intent must be explicit (i.e. include a package name or fully qualified component class name) * and the activity for it should be resizable. * * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is * expanded, calling this method will collapse it. If the app bubble is not expanded, calling * this method will expand it. * * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses * the bubble or bubble stack. * * Some notes: * - Only one app bubble is supported at a time * - Calling this method with a different intent than the existing app bubble will do nothing * * @param intent the intent to display in the bubble expanded view. */ void showAppBubble(Intent intent); void showOrHideAppBubble(Intent intent); /** * @return a bubble that matches the provided shortcutId, if one exists. Loading
packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +4 −2 Original line number Diff line number Diff line Loading @@ -57,7 +57,9 @@ constructor( * If the keyguard is locked, notes will open as a full screen experience. A locked device has * no contextual information which let us use the whole screen space available. * * If no in multi-window or the keyguard is unlocked, notes will open as a floating experience. * If no in multi-window or the keyguard is unlocked, notes will open as a bubble OR it will be * collapsed if the notes bubble is already opened. * * That will let users open other apps in full screen, and take contextual notes. */ fun showNoteTask(isInMultiWindowMode: Boolean = false) { Loading @@ -75,7 +77,7 @@ constructor( context.startActivity(intent) } else { // TODO(b/254606432): Should include Intent.EXTRA_FLOATING_WINDOW_MODE parameter. bubbles.showAppBubble(intent) bubbles.showOrHideAppBubble(intent) } } Loading
packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt +9 −9 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -102,7 +102,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(bubbles).showAppBubble(notesIntent) verify(bubbles).showOrHideAppBubble(notesIntent) verify(context, never()).startActivity(notesIntent) } Loading @@ -113,7 +113,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = true) verify(context).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -123,7 +123,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -133,7 +133,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -143,7 +143,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -153,7 +153,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -161,7 +161,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController(isEnabled = false).showNoteTask() verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } @Test Loading @@ -171,7 +171,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { createNoteTaskController().showNoteTask(isInMultiWindowMode = false) verify(context, never()).startActivity(notesIntent) verify(bubbles, never()).showAppBubble(notesIntent) verify(bubbles, never()).showOrHideAppBubble(notesIntent) } // endregion Loading
packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.service.notification.NotificationListenerService.REASON_AP import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -228,6 +229,8 @@ public class BubblesTest extends SysuiTestCase { private BubbleEntry mBubbleEntryUser11; private BubbleEntry mBubbleEntry2User11; private Intent mAppBubbleIntent; @Mock private ShellInit mShellInit; @Mock Loading Loading @@ -323,6 +326,9 @@ public class BubblesTest extends SysuiTestCase { mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry( mNotificationTestHelper.createBubble(handle)); mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class); mAppBubbleIntent.setPackage(mContext.getPackageName()); mZenModeConfig.suppressedVisualEffects = 0; when(mZenModeController.getConfig()).thenReturn(mZenModeConfig); Loading Loading @@ -1630,6 +1636,62 @@ public class BubblesTest extends SysuiTestCase { any(Bubble.class), anyBoolean(), anyBoolean()); } @Test public void testShowOrHideAppBubble_addsAndExpand() { assertThat(mBubbleController.isStackExpanded()).isFalse(); assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull(); mBubbleController.showOrHideAppBubble(mAppBubbleIntent); verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true), /* showInShade= */ eq(false)); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); } @Test public void testShowOrHideAppBubble_expandIfCollapsed() { mBubbleController.showOrHideAppBubble(mAppBubbleIntent); mBubbleController.updateBubble(mBubbleEntry); mBubbleController.collapseStack(); assertThat(mBubbleController.isStackExpanded()).isFalse(); // Calling this while collapsed will expand the app bubble mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); assertThat(mBubbleData.getBubbles().size()).isEqualTo(2); } @Test public void testShowOrHideAppBubble_collapseIfSelected() { mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); // Calling this while the app bubble is expanded should collapse the stack mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isFalse(); assertThat(mBubbleData.getBubbles().size()).isEqualTo(1); } @Test public void testShowOrHideAppBubble_selectIfNotSelected() { mBubbleController.showOrHideAppBubble(mAppBubbleIntent); mBubbleController.updateBubble(mBubbleEntry); mBubbleController.expandStackAndSelectBubble(mBubbleEntry); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey()); assertThat(mBubbleController.isStackExpanded()).isTrue(); mBubbleController.showOrHideAppBubble(mAppBubbleIntent); assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE); assertThat(mBubbleController.isStackExpanded()).isTrue(); assertThat(mBubbleData.getBubbles().size()).isEqualTo(2); } /** Creates a bubble using the userId and package. */ private Bubble createBubble(int userId, String pkg) { final UserHandle userHandle = new UserHandle(userId); Loading