Loading packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +48 −27 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import android.annotation.DimenRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; Loading Loading @@ -104,27 +105,39 @@ class Bubble implements BubbleViewProvider { private Path mDotPath; private int mFlags; @NonNull private UserHandle mUser; @NonNull private String mPackageName; private int mDesiredHeight; @DimenRes private int mDesiredHeightResId; /** * 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. */ Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo) { Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo, final int desiredHeight, final int desiredHeightResId) { Objects.requireNonNull(key); Objects.requireNonNull(shortcutInfo); mShortcutInfo = shortcutInfo; mKey = key; mFlags = 0; mUser = shortcutInfo.getUserHandle(); mPackageName = shortcutInfo.getPackage(); mDesiredHeight = desiredHeight; mDesiredHeightResId = desiredHeightResId; } /** Used in tests when no UI is required. */ @VisibleForTesting(visibility = PRIVATE) Bubble(NotificationEntry e, BubbleController.NotificationSuppressionChangedListener listener) { mEntry = e; Bubble(@NonNull final NotificationEntry e, @Nullable final BubbleController.NotificationSuppressionChangedListener listener) { Objects.requireNonNull(e); mKey = e.getKey(); mLastUpdated = e.getSbn().getPostTime(); mSuppressionListener = listener; mFlags = e.getSbn().getNotification().flags; setEntry(e); } @Override Loading @@ -137,17 +150,14 @@ class Bubble implements BubbleViewProvider { return mEntry; } @Nullable @NonNull public UserHandle getUser() { if (mEntry != null) return mEntry.getSbn().getUser(); if (mShortcutInfo != null) return mShortcutInfo.getUserHandle(); return null; return mUser; } @NonNull public String getPackageName() { return mEntry == null ? mShortcutInfo == null ? null : mShortcutInfo.getPackage() : mEntry.getSbn().getPackageName(); return mPackageName; } @Override Loading Loading @@ -318,9 +328,18 @@ class Bubble implements BubbleViewProvider { /** * Sets the entry associated with this bubble. */ void setEntry(NotificationEntry entry) { void setEntry(@NonNull final NotificationEntry entry) { Objects.requireNonNull(entry); Objects.requireNonNull(entry.getSbn()); mEntry = entry; mLastUpdated = entry.getSbn().getPostTime(); mFlags = entry.getSbn().getNotification().flags; mPackageName = entry.getSbn().getPackageName(); mUser = entry.getSbn().getUser(); if (entry.getBubbleMetadata() != null) { mDesiredHeight = entry.getBubbleMetadata().getDesiredHeight(); mDesiredHeightResId = entry.getBubbleMetadata().getDesiredHeightResId(); } } /** Loading Loading @@ -434,28 +453,30 @@ class Bubble implements BubbleViewProvider { return mFlyoutMessage; } int getRawDesiredHeight() { return mDesiredHeight; } int getRawDesiredHeightResId() { return mDesiredHeightResId; } float getDesiredHeight(Context context) { if (mEntry == null) return 0; Notification.BubbleMetadata data = mEntry.getBubbleMetadata(); boolean useRes = data.getDesiredHeightResId() != 0; boolean useRes = mDesiredHeightResId != 0; if (useRes) { return getDimenForPackageUser(context, data.getDesiredHeightResId(), mEntry.getSbn().getPackageName(), mEntry.getSbn().getUser().getIdentifier()); return getDimenForPackageUser(context, mDesiredHeightResId, mPackageName, mUser.getIdentifier()); } else { return data.getDesiredHeight() * context.getResources().getDisplayMetrics().density; return mDesiredHeight * context.getResources().getDisplayMetrics().density; } } String getDesiredHeightString() { if (mEntry == null) return String.valueOf(0); Notification.BubbleMetadata data = mEntry.getBubbleMetadata(); boolean useRes = data.getDesiredHeightResId() != 0; boolean useRes = mDesiredHeightResId != 0; if (useRes) { return String.valueOf(data.getDesiredHeightResId()); return String.valueOf(mDesiredHeightResId); } else { return String.valueOf(data.getDesiredHeight()); return String.valueOf(mDesiredHeight); } } Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt +4 −2 Original line number Diff line number Diff line Loading @@ -77,7 +77,8 @@ internal class BubbleDataRepository @Inject constructor( var shortcutId = b.shortcutInfo?.id if (shortcutId == null) shortcutId = b.entry?.bubbleMetadata?.shortcutId if (shortcutId == null) return@mapNotNull null BubbleEntity(userId, b.packageName, shortcutId, b.key) BubbleEntity(userId, b.packageName, shortcutId, b.key, b.rawDesiredHeight, b.rawDesiredHeightResId) } } Loading Loading @@ -158,7 +159,8 @@ internal class BubbleDataRepository @Inject constructor( val bubbles = entities.mapNotNull { entity -> shortcutMap[ShortcutKey(entity.userId, entity.packageName)] ?.first { shortcutInfo -> entity.shortcutId == shortcutInfo.id } ?.let { shortcutInfo -> Bubble(entity.key, shortcutInfo) } ?.let { shortcutInfo -> Bubble(entity.key, shortcutInfo, entity.desiredHeight, entity.desiredHeightResId) } } uiScope.launch { cb(bubbles) } } Loading packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt +4 −1 Original line number Diff line number Diff line Loading @@ -15,11 +15,14 @@ */ package com.android.systemui.bubbles.storage import android.annotation.DimenRes import android.annotation.UserIdInt data class BubbleEntity( @UserIdInt val userId: Int, val packageName: String, val shortcutId: String, val key: String val key: String, val desiredHeight: Int, @DimenRes val desiredHeightResId: Int ) packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt +7 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ private const val ATTR_USER_ID = "uid" private const val ATTR_PACKAGE = "pkg" private const val ATTR_SHORTCUT_ID = "sid" private const val ATTR_KEY = "key" private const val ATTR_DESIRED_HEIGHT = "h" private const val ATTR_DESIRED_HEIGHT_RES_ID = "hid" /** * Writes the bubbles in xml format into given output stream. Loading Loading @@ -59,6 +61,8 @@ private fun writeXmlEntry(serializer: XmlSerializer, bubble: BubbleEntity) { serializer.attribute(null, ATTR_PACKAGE, bubble.packageName) serializer.attribute(null, ATTR_SHORTCUT_ID, bubble.shortcutId) serializer.attribute(null, ATTR_KEY, bubble.key) serializer.attribute(null, ATTR_DESIRED_HEIGHT, bubble.desiredHeight.toString()) serializer.attribute(null, ATTR_DESIRED_HEIGHT_RES_ID, bubble.desiredHeightResId.toString()) serializer.endTag(null, TAG_BUBBLE) } catch (e: IOException) { throw RuntimeException(e) Loading Loading @@ -86,7 +90,9 @@ private fun readXmlEntry(parser: XmlPullParser): BubbleEntity? { parser.getAttributeWithName(ATTR_USER_ID)?.toInt() ?: return null, parser.getAttributeWithName(ATTR_PACKAGE) ?: return null, parser.getAttributeWithName(ATTR_SHORTCUT_ID) ?: return null, parser.getAttributeWithName(ATTR_KEY) ?: return null parser.getAttributeWithName(ATTR_KEY) ?: return null, parser.getAttributeWithName(ATTR_DESIRED_HEIGHT)?.toInt() ?: return null, parser.getAttributeWithName(ATTR_DESIRED_HEIGHT_RES_ID)?.toInt() ?: return null ) } Loading packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt +3 −3 Original line number Diff line number Diff line Loading @@ -29,9 +29,9 @@ import org.junit.runner.RunWith class BubblePersistentRepositoryTest : SysuiTestCase() { private val bubbles = listOf( BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1"), BubbleEntity(10, "com.example.chat", "alice and bob", "key-2"), BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3") BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0), BubbleEntity(10, "com.example.chat", "alice and bob", "key-2", 0, 16537428), BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0) ) private lateinit var repository: BubblePersistentRepository Loading Loading
packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +48 −27 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import android.annotation.DimenRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; Loading Loading @@ -104,27 +105,39 @@ class Bubble implements BubbleViewProvider { private Path mDotPath; private int mFlags; @NonNull private UserHandle mUser; @NonNull private String mPackageName; private int mDesiredHeight; @DimenRes private int mDesiredHeightResId; /** * 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. */ Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo) { Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo, final int desiredHeight, final int desiredHeightResId) { Objects.requireNonNull(key); Objects.requireNonNull(shortcutInfo); mShortcutInfo = shortcutInfo; mKey = key; mFlags = 0; mUser = shortcutInfo.getUserHandle(); mPackageName = shortcutInfo.getPackage(); mDesiredHeight = desiredHeight; mDesiredHeightResId = desiredHeightResId; } /** Used in tests when no UI is required. */ @VisibleForTesting(visibility = PRIVATE) Bubble(NotificationEntry e, BubbleController.NotificationSuppressionChangedListener listener) { mEntry = e; Bubble(@NonNull final NotificationEntry e, @Nullable final BubbleController.NotificationSuppressionChangedListener listener) { Objects.requireNonNull(e); mKey = e.getKey(); mLastUpdated = e.getSbn().getPostTime(); mSuppressionListener = listener; mFlags = e.getSbn().getNotification().flags; setEntry(e); } @Override Loading @@ -137,17 +150,14 @@ class Bubble implements BubbleViewProvider { return mEntry; } @Nullable @NonNull public UserHandle getUser() { if (mEntry != null) return mEntry.getSbn().getUser(); if (mShortcutInfo != null) return mShortcutInfo.getUserHandle(); return null; return mUser; } @NonNull public String getPackageName() { return mEntry == null ? mShortcutInfo == null ? null : mShortcutInfo.getPackage() : mEntry.getSbn().getPackageName(); return mPackageName; } @Override Loading Loading @@ -318,9 +328,18 @@ class Bubble implements BubbleViewProvider { /** * Sets the entry associated with this bubble. */ void setEntry(NotificationEntry entry) { void setEntry(@NonNull final NotificationEntry entry) { Objects.requireNonNull(entry); Objects.requireNonNull(entry.getSbn()); mEntry = entry; mLastUpdated = entry.getSbn().getPostTime(); mFlags = entry.getSbn().getNotification().flags; mPackageName = entry.getSbn().getPackageName(); mUser = entry.getSbn().getUser(); if (entry.getBubbleMetadata() != null) { mDesiredHeight = entry.getBubbleMetadata().getDesiredHeight(); mDesiredHeightResId = entry.getBubbleMetadata().getDesiredHeightResId(); } } /** Loading Loading @@ -434,28 +453,30 @@ class Bubble implements BubbleViewProvider { return mFlyoutMessage; } int getRawDesiredHeight() { return mDesiredHeight; } int getRawDesiredHeightResId() { return mDesiredHeightResId; } float getDesiredHeight(Context context) { if (mEntry == null) return 0; Notification.BubbleMetadata data = mEntry.getBubbleMetadata(); boolean useRes = data.getDesiredHeightResId() != 0; boolean useRes = mDesiredHeightResId != 0; if (useRes) { return getDimenForPackageUser(context, data.getDesiredHeightResId(), mEntry.getSbn().getPackageName(), mEntry.getSbn().getUser().getIdentifier()); return getDimenForPackageUser(context, mDesiredHeightResId, mPackageName, mUser.getIdentifier()); } else { return data.getDesiredHeight() * context.getResources().getDisplayMetrics().density; return mDesiredHeight * context.getResources().getDisplayMetrics().density; } } String getDesiredHeightString() { if (mEntry == null) return String.valueOf(0); Notification.BubbleMetadata data = mEntry.getBubbleMetadata(); boolean useRes = data.getDesiredHeightResId() != 0; boolean useRes = mDesiredHeightResId != 0; if (useRes) { return String.valueOf(data.getDesiredHeightResId()); return String.valueOf(mDesiredHeightResId); } else { return String.valueOf(data.getDesiredHeight()); return String.valueOf(mDesiredHeight); } } Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt +4 −2 Original line number Diff line number Diff line Loading @@ -77,7 +77,8 @@ internal class BubbleDataRepository @Inject constructor( var shortcutId = b.shortcutInfo?.id if (shortcutId == null) shortcutId = b.entry?.bubbleMetadata?.shortcutId if (shortcutId == null) return@mapNotNull null BubbleEntity(userId, b.packageName, shortcutId, b.key) BubbleEntity(userId, b.packageName, shortcutId, b.key, b.rawDesiredHeight, b.rawDesiredHeightResId) } } Loading Loading @@ -158,7 +159,8 @@ internal class BubbleDataRepository @Inject constructor( val bubbles = entities.mapNotNull { entity -> shortcutMap[ShortcutKey(entity.userId, entity.packageName)] ?.first { shortcutInfo -> entity.shortcutId == shortcutInfo.id } ?.let { shortcutInfo -> Bubble(entity.key, shortcutInfo) } ?.let { shortcutInfo -> Bubble(entity.key, shortcutInfo, entity.desiredHeight, entity.desiredHeightResId) } } uiScope.launch { cb(bubbles) } } Loading
packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt +4 −1 Original line number Diff line number Diff line Loading @@ -15,11 +15,14 @@ */ package com.android.systemui.bubbles.storage import android.annotation.DimenRes import android.annotation.UserIdInt data class BubbleEntity( @UserIdInt val userId: Int, val packageName: String, val shortcutId: String, val key: String val key: String, val desiredHeight: Int, @DimenRes val desiredHeightResId: Int )
packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt +7 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ private const val ATTR_USER_ID = "uid" private const val ATTR_PACKAGE = "pkg" private const val ATTR_SHORTCUT_ID = "sid" private const val ATTR_KEY = "key" private const val ATTR_DESIRED_HEIGHT = "h" private const val ATTR_DESIRED_HEIGHT_RES_ID = "hid" /** * Writes the bubbles in xml format into given output stream. Loading Loading @@ -59,6 +61,8 @@ private fun writeXmlEntry(serializer: XmlSerializer, bubble: BubbleEntity) { serializer.attribute(null, ATTR_PACKAGE, bubble.packageName) serializer.attribute(null, ATTR_SHORTCUT_ID, bubble.shortcutId) serializer.attribute(null, ATTR_KEY, bubble.key) serializer.attribute(null, ATTR_DESIRED_HEIGHT, bubble.desiredHeight.toString()) serializer.attribute(null, ATTR_DESIRED_HEIGHT_RES_ID, bubble.desiredHeightResId.toString()) serializer.endTag(null, TAG_BUBBLE) } catch (e: IOException) { throw RuntimeException(e) Loading Loading @@ -86,7 +90,9 @@ private fun readXmlEntry(parser: XmlPullParser): BubbleEntity? { parser.getAttributeWithName(ATTR_USER_ID)?.toInt() ?: return null, parser.getAttributeWithName(ATTR_PACKAGE) ?: return null, parser.getAttributeWithName(ATTR_SHORTCUT_ID) ?: return null, parser.getAttributeWithName(ATTR_KEY) ?: return null parser.getAttributeWithName(ATTR_KEY) ?: return null, parser.getAttributeWithName(ATTR_DESIRED_HEIGHT)?.toInt() ?: return null, parser.getAttributeWithName(ATTR_DESIRED_HEIGHT_RES_ID)?.toInt() ?: return null ) } Loading
packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt +3 −3 Original line number Diff line number Diff line Loading @@ -29,9 +29,9 @@ import org.junit.runner.RunWith class BubblePersistentRepositoryTest : SysuiTestCase() { private val bubbles = listOf( BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1"), BubbleEntity(10, "com.example.chat", "alice and bob", "key-2"), BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3") BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0), BubbleEntity(10, "com.example.chat", "alice and bob", "key-2", 0, 16537428), BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0) ) private lateinit var repository: BubblePersistentRepository Loading