summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java97
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java151
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java40
11 files changed, 219 insertions, 119 deletions
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt
index cec67f26af92..71097aba87e2 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt
@@ -64,7 +64,7 @@ import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.util.Optional
-/** Tests for [BubbleControllerTest] */
+/** Tests for [BubbleController] */
@SmallTest
@RunWith(AndroidJUnit4::class)
class BubbleControllerTest {
@@ -140,7 +140,7 @@ class BubbleControllerTest {
assertThat(bubbleController.hasBubbles()).isTrue()
assertThat(bubbleData.getAnyBubbleWithKey(expectedKey)).isNotNull()
- assertThat(bubbleData.getAnyBubbleWithKey(expectedKey)!!.isNoteBubble).isTrue()
+ assertThat(bubbleData.getAnyBubbleWithKey(expectedKey)!!.isNote).isTrue()
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index c1dadada505a..5bd8d86f1144 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -357,9 +357,9 @@ public class BadgedImageView extends ConstraintLayout {
void showBadge() {
Bitmap appBadgeBitmap = mBubble.getAppBadge();
- final boolean isAppLaunchIntent = (mBubble instanceof Bubble)
- && ((Bubble) mBubble).isAppLaunchIntent();
- if (appBadgeBitmap == null || isAppLaunchIntent) {
+ final boolean showAppBadge = (mBubble instanceof Bubble)
+ && ((Bubble) mBubble).showAppBadge();
+ if (appBadgeBitmap == null || !showAppBadge) {
mAppIcon.setVisibility(GONE);
return;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index d77c177437b8..50ff58d7cf22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -56,7 +56,6 @@ import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView;
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
-import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleInfo;
import com.android.wm.shell.shared.bubbles.ParcelableFlyoutMessage;
import com.android.wm.shell.taskview.TaskView;
@@ -78,11 +77,19 @@ public class Bubble implements BubbleViewProvider {
/** A string prefix used in note bubbles' {@link #mKey}. */
public static final String KEY_NOTE_BUBBLE = "key_note_bubble";
- /** Whether the bubble is an app bubble. */
- private final boolean mIsAppBubble;
+ /** The possible types a bubble may be. */
+ public enum BubbleType {
+ /** Chat is from a notification. */
+ TYPE_CHAT,
+ /** Notes are from the note taking API. */
+ TYPE_NOTE,
+ /** Shortcuts from bubble anything, based on {@link ShortcutInfo}. */
+ TYPE_SHORTCUT,
+ /** Apps are from bubble anything. */
+ TYPE_APP,
+ }
- /** Whether the bubble is a notetaking bubble. */
- private final boolean mIsNoteBubble;
+ private final BubbleType mType;
private final String mKey;
@Nullable
@@ -221,7 +228,6 @@ public class Bubble implements BubbleViewProvider {
* Create a bubble with limited information based on given {@link ShortcutInfo}.
* Note: Currently this is only being used when the bubble is persisted to disk.
*/
- @VisibleForTesting(visibility = PRIVATE)
public Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo,
final int desiredHeight, final int desiredHeightResId, @Nullable final String title,
int taskId, @Nullable final String locus, boolean isDismissable,
@@ -248,16 +254,15 @@ public class Bubble implements BubbleViewProvider {
mBgExecutor = bgExecutor;
mTaskId = taskId;
mBubbleMetadataFlagListener = listener;
- mIsAppBubble = false;
- mIsNoteBubble = false;
+ // TODO (b/394085999) read/write type to xml
+ mType = BubbleType.TYPE_CHAT;
}
private Bubble(
Intent intent,
UserHandle user,
@Nullable Icon icon,
- boolean isAppBubble,
- boolean isNoteBubble,
+ BubbleType type,
String key,
@ShellMainThread Executor mainExecutor,
@ShellBackgroundThread Executor bgExecutor) {
@@ -266,8 +271,7 @@ public class Bubble implements BubbleViewProvider {
mFlags = 0;
mUser = user;
mIcon = icon;
- mIsAppBubble = isAppBubble;
- mIsNoteBubble = isNoteBubble;
+ mType = type;
mKey = key;
mShowBubbleUpdateDot = false;
mMainExecutor = mainExecutor;
@@ -285,8 +289,7 @@ public class Bubble implements BubbleViewProvider {
mFlags = 0;
mUser = info.getUserHandle();
mIcon = info.getIcon();
- mIsAppBubble = false;
- mIsNoteBubble = false;
+ mType = BubbleType.TYPE_SHORTCUT;
mKey = getBubbleKeyForShortcut(info);
mShowBubbleUpdateDot = false;
mMainExecutor = mainExecutor;
@@ -310,8 +313,7 @@ public class Bubble implements BubbleViewProvider {
mFlags = 0;
mUser = user;
mIcon = icon;
- mIsAppBubble = true;
- mIsNoteBubble = false;
+ mType = BubbleType.TYPE_APP;
mKey = key;
mShowBubbleUpdateDot = false;
mMainExecutor = mainExecutor;
@@ -322,15 +324,14 @@ public class Bubble implements BubbleViewProvider {
mPackageName = task.baseActivity.getPackageName();
}
- /** Creates a notetaking bubble. */
+ /** Creates a note taking bubble. */
public static Bubble createNotesBubble(Intent intent, UserHandle user, @Nullable Icon icon,
@ShellMainThread Executor mainExecutor, @ShellBackgroundThread Executor bgExecutor) {
return new Bubble(intent,
user,
icon,
- /* isAppBubble= */ true,
- /* isNoteBubble= */ true,
- /* key= */ getNoteBubbleKeyForApp(intent.getPackage(), user),
+ BubbleType.TYPE_NOTE,
+ getNoteBubbleKeyForApp(intent.getPackage(), user),
mainExecutor, bgExecutor);
}
@@ -340,9 +341,8 @@ public class Bubble implements BubbleViewProvider {
return new Bubble(intent,
user,
icon,
- /* isAppBubble= */ true,
- /* isNoteBubble= */ false,
- /* key= */ getAppBubbleKeyForApp(intent.getPackage(), user),
+ BubbleType.TYPE_APP,
+ getAppBubbleKeyForApp(intent.getPackage(), user),
mainExecutor, bgExecutor);
}
@@ -400,13 +400,15 @@ public class Bubble implements BubbleViewProvider {
return KEY_APP_BUBBLE + ":" + taskInfo.taskId;
}
+ /**
+ * Creates a chat bubble based on a notification (contents of {@link BubbleEntry}.
+ */
@VisibleForTesting(visibility = PRIVATE)
public Bubble(@NonNull final BubbleEntry entry,
final Bubbles.BubbleMetadataFlagListener listener,
final Bubbles.PendingIntentCanceledListener intentCancelListener,
@ShellMainThread Executor mainExecutor, @ShellBackgroundThread Executor bgExecutor) {
- mIsAppBubble = false;
- mIsNoteBubble = false;
+ mType = BubbleType.TYPE_CHAT;
mKey = entry.getKey();
mGroupKey = entry.getGroupKey();
mLocusId = entry.getLocusId();
@@ -436,7 +438,7 @@ public class Bubble implements BubbleViewProvider {
getTitle(),
getAppName(),
isImportantConversation(),
- !isAppLaunchIntent(),
+ showAppBadge(),
getParcelableFlyoutMessage());
}
@@ -1005,13 +1007,6 @@ public class Bubble implements BubbleViewProvider {
}
/**
- * Whether this bubble is conversation
- */
- public boolean isConversation() {
- return null != mShortcutInfo;
- }
-
- /**
* Sets whether this notification should be suppressed in the shade.
*/
@VisibleForTesting
@@ -1128,14 +1123,10 @@ public class Bubble implements BubbleViewProvider {
}
/**
- * Whether this bubble represents the full app, i.e. the intent used is the launch
- * intent for an app. In this case we don't show a badge on the icon.
+ * Whether an app badge should be shown for this bubble.
*/
- public boolean isAppLaunchIntent() {
- if (BubbleAnythingFlagHelper.enableCreateAnyBubble() && mIntent != null) {
- return mIntent.hasCategory("android.intent.category.LAUNCHER");
- }
- return false;
+ public boolean showAppBadge() {
+ return isChat() || isShortcut() || isNote();
}
/**
@@ -1162,17 +1153,31 @@ public class Bubble implements BubbleViewProvider {
}
/**
- * Returns whether this bubble is from an app (as well as notetaking) versus a notification.
+ * Returns whether this bubble is a conversation from the notification API.
+ */
+ public boolean isChat() {
+ return mType == BubbleType.TYPE_CHAT;
+ }
+
+ /**
+ * Returns whether this bubble is a note from the note taking API.
+ */
+ public boolean isNote() {
+ return mType == BubbleType.TYPE_NOTE;
+ }
+
+ /**
+ * Returns whether this bubble is a shortcut.
*/
- public boolean isAppBubble() {
- return mIsAppBubble;
+ public boolean isShortcut() {
+ return mType == BubbleType.TYPE_SHORTCUT;
}
/**
- * Returns whether this bubble is specific from the notetaking API.
+ * Returns whether this bubble is an app.
*/
- public boolean isNoteBubble() {
- return mIsNoteBubble;
+ public boolean isApp() {
+ return mType == BubbleType.TYPE_APP;
}
/** Creates open app settings intent */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 10efd8e164e4..66abcabed109 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -2890,7 +2890,7 @@ public class BubbleController implements ConfigurationChangeListener,
mShortcutIdToBubble.put(b.getShortcutId(), b);
updateBubbleSuppressedState(b);
- if (b.isNoteBubble()) {
+ if (b.isNote()) {
mNoteBubbleTaskIds.put(b.getKey(), b.getTaskId());
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt
index bd4708259b50..ed23986d0f64 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt
@@ -83,4 +83,4 @@ class BubbleEducationController(private val context: Context) {
/** Convenience extension method to check if the bubble is a conversation bubble */
private val BubbleViewProvider.isConversationBubble: Boolean
- get() = if (this is Bubble) isConversation else false
+ get() = if (this is Bubble) isChat else false
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index ad9ab7a722ee..3f607a9c52ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -227,10 +227,11 @@ public class BubbleExpandedView extends LinearLayout {
MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS);
final boolean isShortcutBubble = (mBubble.hasMetadataShortcutId()
- || (mBubble.getShortcutInfo() != null
+ || (mBubble.isShortcut()
&& BubbleAnythingFlagHelper.enableCreateAnyBubble()));
- if (mBubble.isAppBubble()) {
+ // TODO - currently based on type, really it's what the "launch item" is.
+ if (mBubble.isApp() || mBubble.isNote()) {
Context context =
mContext.createContextAsUser(
mBubble.getUser(), Context.CONTEXT_RESTRICTED);
@@ -284,7 +285,7 @@ public class BubbleExpandedView extends LinearLayout {
// The taskId is saved to use for removeTask, preventing appearance in recent tasks.
mTaskId = taskId;
- if (mBubble != null && mBubble.isNoteBubble()) {
+ if (mBubble != null && mBubble.isNote()) {
// Let the controller know sooner what the taskId is.
mManager.setNoteBubbleTaskId(mBubble.getKey(), mTaskId);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 3babc0d801c4..dad627f85d95 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -1385,16 +1385,16 @@ public class BubbleStackView extends FrameLayout
/**
* Whether the selected bubble is conversation bubble
*/
- private boolean isConversationBubble() {
+ private boolean isChat() {
BubbleViewProvider bubble = mBubbleData.getSelectedBubble();
- return bubble instanceof Bubble && ((Bubble) bubble).isConversation();
+ return bubble instanceof Bubble && ((Bubble) bubble).isChat();
}
/**
* Whether the educational view should show for the expanded view "manage" menu.
*/
private boolean shouldShowManageEdu() {
- if (!isConversationBubble()) {
+ if (!isChat()) {
// We only show user education for conversation bubbles right now
return false;
}
@@ -1441,7 +1441,7 @@ public class BubbleStackView extends FrameLayout
* Whether education view should show for the collapsed stack.
*/
private boolean shouldShowStackEdu() {
- if (!isConversationBubble()) {
+ if (!isChat()) {
// We only show user education for conversation bubbles right now
return false;
}
@@ -1976,7 +1976,7 @@ public class BubbleStackView extends FrameLayout
return;
}
- if (firstBubble && bubble.isNoteBubble() && !mPositioner.hasUserModifiedDefaultPosition()) {
+ if (firstBubble && bubble.isNote() && !mPositioner.hasUserModifiedDefaultPosition()) {
// If it's an note bubble and we don't have a previous resting position, update the
// controllers to use the default position for the note bubble (it'd be different from
// the position initialized with the controllers originally).
@@ -3322,20 +3322,16 @@ public class BubbleStackView extends FrameLayout
// name and icon.
if (show) {
final Bubble bubble = mBubbleData.getBubbleInStackWithKey(mExpandedBubble.getKey());
- if (bubble != null && !bubble.isAppBubble()) {
- // Setup options for non app bubbles
+ if (bubble != null && bubble.isChat()) {
+ // Setup options for chat bubbles
mManageDontBubbleView.setVisibility(VISIBLE);
mManageSettingsIcon.setImageBitmap(bubble.getRawAppBadge());
mManageSettingsText.setText(getResources().getString(
R.string.bubbles_app_settings, bubble.getAppName()));
mManageSettingsView.setVisibility(VISIBLE);
} else {
- // Setup options for app bubbles
- // App bubbles have no conversations
- // so we don't show the option to not bubble conversation
+ // Not a chat bubble, so don't show conversation / notification settings
mManageDontBubbleView.setVisibility(GONE);
- // App bubbles are not notification based
- // so we don't show the option to go to notification settings
mManageSettingsView.setVisibility(GONE);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
index 0d89bb260bf5..4a0eee861d21 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
@@ -100,6 +100,7 @@ public class BubbleTaskViewHelper {
// TODO: I notice inconsistencies in lifecycle
// Post to keep the lifecycle normal
+ // TODO - currently based on type, really it's what the "launch item" is.
mParentView.post(() -> {
ProtoLog.d(WM_SHELL_BUBBLES, "onInitialized: calling startActivity, bubble=%s",
getBubbleKey());
@@ -108,11 +109,11 @@ public class BubbleTaskViewHelper {
options.setPendingIntentBackgroundActivityStartMode(
MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS);
final boolean isShortcutBubble = (mBubble.hasMetadataShortcutId()
- || (mBubble.getShortcutInfo() != null
+ || (mBubble.isShortcut()
&& BubbleAnythingFlagHelper.enableCreateAnyBubble()));
if (mBubble.getPreparingTransition() != null) {
mBubble.getPreparingTransition().surfaceCreated();
- } else if (mBubble.isAppBubble()) {
+ } else if (mBubble.isApp() || mBubble.isNote()) {
Context context =
mContext.createContextAsUser(
mBubble.getUser(), Context.CONTEXT_RESTRICTED);
@@ -167,7 +168,7 @@ public class BubbleTaskViewHelper {
// The taskId is saved to use for removeTask, preventing appearance in recent tasks.
mTaskId = taskId;
- if (mBubble != null && mBubble.isNoteBubble()) {
+ if (mBubble != null && mBubble.isNote()) {
// Let the controller know sooner what the taskId is.
mExpandedViewManager.setNoteBubbleTaskId(mBubble.getKey(), mTaskId);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
index 5f437d4af40f..b7761ec75782 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
@@ -222,7 +222,7 @@ class BubbleBarMenuViewController {
Resources resources = mContext.getResources();
int tintColor = mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
- if (bubble.isConversation()) {
+ if (bubble.isChat()) {
// Don't bubble conversation action
menuActions.add(new BubbleBarMenuView.MenuAction(
Icon.createWithResource(mContext, R.drawable.bubble_ic_stop_bubble),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
index dca5fc4c2fe0..2c0ced4fd8de 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
@@ -22,18 +22,22 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.PendingIntent;
+import android.app.TaskInfo;
+import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.UserHandle;
+import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -60,13 +64,17 @@ public class BubbleTest extends ShellTestCase {
@Mock
private StatusBarNotification mSbn;
@Mock
+ private NotificationListenerService.Ranking mRanking;
+ @Mock
private ShellExecutor mMainExecutor;
@Mock
private ShellExecutor mBgExecutor;
- private BubbleEntry mBubbleEntry;
private Bundle mExtras;
- private Bubble mBubble;
+
+ // This entry / bubble are set up with PendingIntent / Icon API for chat
+ private BubbleEntry mBubbleEntry;
+ private Bubble mChatBubble;
@Mock
private Bubbles.BubbleMetadataFlagListener mBubbleMetadataFlagListener;
@@ -83,11 +91,16 @@ public class BubbleTest extends ShellTestCase {
PendingIntent.getActivity(mContext, 0, target, PendingIntent.FLAG_MUTABLE),
Icon.createWithResource(mContext, R.drawable.bubble_ic_create_bubble))
.build();
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
+ .setId("shortcutId")
+ .build();
when(mSbn.getNotification()).thenReturn(mNotif);
when(mNotif.getBubbleMetadata()).thenReturn(metadata);
when(mSbn.getKey()).thenReturn("mock");
- mBubbleEntry = new BubbleEntry(mSbn, null, true, false, false, false);
- mBubble = new Bubble(mBubbleEntry, mBubbleMetadataFlagListener, null, mMainExecutor,
+ when(mRanking.getConversationShortcutInfo()).thenReturn(shortcutInfo);
+
+ mBubbleEntry = new BubbleEntry(mSbn, mRanking, true, false, false, false);
+ mChatBubble = new Bubble(mBubbleEntry, mBubbleMetadataFlagListener, null, mMainExecutor,
mBgExecutor);
}
@@ -152,42 +165,113 @@ public class BubbleTest extends ShellTestCase {
@Test
public void testBubbleMetadataFlagListener_change_notified() {
- assertThat(mBubble.showInShade()).isTrue();
+ assertThat(mChatBubble.showInShade()).isTrue();
- mBubble.setSuppressNotification(true);
+ mChatBubble.setSuppressNotification(true);
- assertThat(mBubble.showInShade()).isFalse();
+ assertThat(mChatBubble.showInShade()).isFalse();
- verify(mBubbleMetadataFlagListener).onBubbleMetadataFlagChanged(mBubble);
+ verify(mBubbleMetadataFlagListener).onBubbleMetadataFlagChanged(mChatBubble);
}
@Test
public void testBubbleMetadataFlagListener_noChange_doesntNotify() {
- assertThat(mBubble.showInShade()).isTrue();
+ assertThat(mChatBubble.showInShade()).isTrue();
- mBubble.setSuppressNotification(false);
+ mChatBubble.setSuppressNotification(false);
verify(mBubbleMetadataFlagListener, never()).onBubbleMetadataFlagChanged(any());
}
@Test
- public void testBubbleIsConversation_hasConversationShortcut() {
- Bubble bubble = createBubbleWithShortcut();
- assertThat(bubble.getShortcutInfo()).isNotNull();
- assertThat(bubble.isConversation()).isTrue();
+ public void testBubbleType_conversationShortcut() {
+ Bubble bubble = createChatBubble(true /* useShortcut */);
+ assertThat(bubble.isChat()).isTrue();
}
@Test
- public void testBubbleIsConversation_hasNoShortcut() {
- Bubble bubble = new Bubble(mBubbleEntry, mBubbleMetadataFlagListener, null, mMainExecutor,
- mBgExecutor);
- assertThat(bubble.getShortcutInfo()).isNull();
- assertThat(bubble.isConversation()).isFalse();
+ public void testBubbleType_conversationPendingIntent() {
+ Bubble bubble = createChatBubble(false /* useShortcut */);
+ assertThat(bubble.isChat()).isTrue();
+ }
+
+ @Test
+ public void testBubbleType_note() {
+ Bubble bubble = Bubble.createNotesBubble(createIntent(), UserHandle.of(0),
+ mock(Icon.class),
+ mMainExecutor, mBgExecutor);
+ assertThat(bubble.isNote()).isTrue();
+ }
+
+ @Test
+ public void testBubbleType_shortcut() {
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
+ .setId("mockShortcutId")
+ .build();
+ Bubble bubble = Bubble.createShortcutBubble(shortcutInfo, mMainExecutor, mBgExecutor);
+ assertThat(bubble.isShortcut()).isTrue();
+ }
+
+ @Test
+ public void testBubbleType_intent() {
+ Bubble bubble = Bubble.createAppBubble(createIntent(), UserHandle.of(0),
+ mock(Icon.class),
+ mMainExecutor, mBgExecutor);
+ assertThat(bubble.isApp()).isTrue();
+ }
+
+ @Test
+ public void testBubbleType_taskId() {
+ TaskInfo info = mock(TaskInfo.class);
+ ComponentName componentName = mock(ComponentName.class);
+ when(componentName.getPackageName()).thenReturn(mContext.getPackageName());
+ info.taskId = 1;
+ info.baseActivity = componentName;
+ Bubble bubble = Bubble.createTaskBubble(info, UserHandle.of(0),
+ mock(Icon.class),
+ mMainExecutor, mBgExecutor);
+ assertThat(bubble.isApp()).isTrue();
+ }
+
+ @Test
+ public void testShowAppBadge_chat() {
+ Bubble bubble = createChatBubble(true /* useShortcut */);
+ assertThat(bubble.isChat()).isTrue();
+ assertThat(bubble.showAppBadge()).isTrue();
+ }
+
+ @Test
+ public void testShowAppBadge_note() {
+ Bubble bubble = Bubble.createNotesBubble(createIntent(), UserHandle.of(0),
+ mock(Icon.class),
+ mMainExecutor, mBgExecutor);
+ assertThat(bubble.isNote()).isTrue();
+ assertThat(bubble.showAppBadge()).isTrue();
+ }
+
+ @Test
+ public void testShowAppBadge_app() {
+ Bubble bubble = Bubble.createAppBubble(createIntent(), UserHandle.of(0),
+ mock(Icon.class),
+ mMainExecutor, mBgExecutor);
+ assertThat(bubble.isApp()).isTrue();
+ assertThat(bubble.showAppBadge()).isFalse();
+ }
+
+ @Test
+ public void testShowAppBadge_shortcut() {
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
+ .setId("mockShortcutId")
+ .build();
+ Bubble bubble = Bubble.createShortcutBubble(shortcutInfo,
+ mMainExecutor, mBgExecutor);
+ assertThat(bubble.isShortcut()).isTrue();
+ assertThat(bubble.showAppBadge()).isTrue();
}
@Test
public void testBubbleAsBubbleBarBubble_withShortcut() {
- Bubble bubble = createBubbleWithShortcut();
+ Bubble bubble = createChatBubble(true /* useShortcut */);
BubbleInfo bubbleInfo = bubble.asBubbleBarBubble();
assertThat(bubble.getShortcutInfo()).isNotNull();
@@ -199,7 +283,7 @@ public class BubbleTest extends ShellTestCase {
}
@Test
- public void testBubbleAsBubbleBarBubble_withoutShortcut() {
+ public void testBubbleAsBubbleBarBubble_withIntent() {
Intent intent = new Intent(mContext, BubblesTestActivity.class);
intent.setPackage(mContext.getPackageName());
Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1 /* userId */),
@@ -213,12 +297,23 @@ public class BubbleTest extends ShellTestCase {
assertThat(bubbleInfo.getPackageName()).isEqualTo(bubble.getPackageName());
}
- private Bubble createBubbleWithShortcut() {
- ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
- .setId("mockShortcutId")
- .build();
- return new Bubble("mockKey", shortcutInfo, 10, Resources.ID_NULL,
- "mockTitle", 0 /* taskId */, "mockLocus", true /* isDismissible */,
- mMainExecutor, mBgExecutor, mBubbleMetadataFlagListener);
+ private Intent createIntent() {
+ Intent intent = new Intent(mContext, BubblesTestActivity.class);
+ intent.setPackage(mContext.getPackageName());
+ return intent;
+ }
+
+ private Bubble createChatBubble(boolean useShortcut) {
+ if (useShortcut) {
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
+ .setId("mockShortcutId")
+ .build();
+ return new Bubble("mockKey", shortcutInfo, 10, Resources.ID_NULL,
+ "mockTitle", 0 /* taskId */, "mockLocus", true /* isDismissible */,
+ mMainExecutor, mBgExecutor, mBubbleMetadataFlagListener);
+ } else {
+ return new Bubble(mBubbleEntry, mBubbleMetadataFlagListener, null, mMainExecutor,
+ mBgExecutor);
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index bf10dc6c4aef..a38d71b178e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -1923,13 +1923,13 @@ public class BubblesTest extends SysuiTestCase {
public void testShowStackEdu_isNotConversationBubble() {
// Setup
setPrefBoolean(StackEducationView.PREF_STACK_EDUCATION, false);
- BubbleEntry bubbleEntry = createBubbleEntry(false /* isConversation */);
- mBubbleController.updateBubble(bubbleEntry);
+ mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
assertTrue(mBubbleController.hasBubbles());
-
+ String noteBubbleKey = Bubble.getNoteBubbleKeyForApp(mNotesBubbleIntent.getPackage(),
+ mUser0);
// Click on bubble
- Bubble bubble = mBubbleData.getBubbleInStackWithKey(bubbleEntry.getKey());
- assertFalse(bubble.isConversation());
+ Bubble bubble = mBubbleData.getBubbleInStackWithKey(noteBubbleKey);
+ assertFalse(bubble.isChat());
bubble.getIconView().callOnClick();
// Check education is not shown
@@ -1941,13 +1941,13 @@ public class BubblesTest extends SysuiTestCase {
public void testShowStackEdu_isConversationBubble() {
// Setup
setPrefBoolean(StackEducationView.PREF_STACK_EDUCATION, false);
- BubbleEntry bubbleEntry = createBubbleEntry(true /* isConversation */);
+ BubbleEntry bubbleEntry = createBubbleEntry();
mBubbleController.updateBubble(bubbleEntry);
assertTrue(mBubbleController.hasBubbles());
// Click on bubble
Bubble bubble = mBubbleData.getBubbleInStackWithKey(bubbleEntry.getKey());
- assertTrue(bubble.isConversation());
+ assertTrue(bubble.isChat());
bubble.getIconView().callOnClick();
// Check education is shown
@@ -1959,13 +1959,13 @@ public class BubblesTest extends SysuiTestCase {
public void testShowStackEdu_isSeenConversationBubble() {
// Setup
setPrefBoolean(StackEducationView.PREF_STACK_EDUCATION, true);
- BubbleEntry bubbleEntry = createBubbleEntry(true /* isConversation */);
+ BubbleEntry bubbleEntry = createBubbleEntry();
mBubbleController.updateBubble(bubbleEntry);
assertTrue(mBubbleController.hasBubbles());
// Click on bubble
Bubble bubble = mBubbleData.getBubbleInStackWithKey(bubbleEntry.getKey());
- assertTrue(bubble.isConversation());
+ assertTrue(bubble.isChat());
bubble.getIconView().callOnClick();
// Check education is not shown
@@ -2690,17 +2690,19 @@ public class BubblesTest extends SysuiTestCase {
mock(Bubbles.PendingIntentCanceledListener.class), executor, executor);
}
- private BubbleEntry createBubbleEntry(boolean isConversation) {
+ /**
+ * Creates a BubbleEntry, which will represent a chat bubble.
+ * All bubble entries are notification based & therefore are chat bubbles.
+ */
+ private BubbleEntry createBubbleEntry() {
NotificationEntry notificationEntry = mNotificationTestHelper.createBubble(mDeleteIntent);
- if (isConversation) {
- ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
- .setId("shortcutId")
- .build();
- NotificationEntryHelper.modifyRanking(notificationEntry)
- .setIsConversation(true)
- .setShortcutInfo(shortcutInfo)
- .build();
- }
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
+ .setId("shortcutId")
+ .build();
+ NotificationEntryHelper.modifyRanking(notificationEntry)
+ .setIsConversation(true)
+ .setShortcutInfo(shortcutInfo)
+ .build();
return mBubblesManager.notifToBubbleEntry(notificationEntry);
}