Merge "persist desired height of bubbles to disk" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-06-05 01:42:34 +00:00
committed by Android (Google) Code Review
7 changed files with 78 additions and 46 deletions

View File

@@ -21,6 +21,7 @@ import static android.view.Display.INVALID_DISPLAY;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import android.annotation.DimenRes;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.Notification; import android.app.Notification;
@@ -104,27 +105,39 @@ class Bubble implements BubbleViewProvider {
private Path mDotPath; private Path mDotPath;
private int mFlags; 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}. * 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. * 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(key);
Objects.requireNonNull(shortcutInfo); Objects.requireNonNull(shortcutInfo);
mShortcutInfo = shortcutInfo; mShortcutInfo = shortcutInfo;
mKey = key; mKey = key;
mFlags = 0; mFlags = 0;
mUser = shortcutInfo.getUserHandle();
mPackageName = shortcutInfo.getPackage();
mDesiredHeight = desiredHeight;
mDesiredHeightResId = desiredHeightResId;
} }
/** Used in tests when no UI is required. */ /** Used in tests when no UI is required. */
@VisibleForTesting(visibility = PRIVATE) @VisibleForTesting(visibility = PRIVATE)
Bubble(NotificationEntry e, Bubble(@NonNull final NotificationEntry e,
BubbleController.NotificationSuppressionChangedListener listener) { @Nullable final BubbleController.NotificationSuppressionChangedListener listener) {
mEntry = e; Objects.requireNonNull(e);
mKey = e.getKey(); mKey = e.getKey();
mLastUpdated = e.getSbn().getPostTime();
mSuppressionListener = listener; mSuppressionListener = listener;
mFlags = e.getSbn().getNotification().flags; setEntry(e);
} }
@Override @Override
@@ -137,17 +150,14 @@ class Bubble implements BubbleViewProvider {
return mEntry; return mEntry;
} }
@Nullable @NonNull
public UserHandle getUser() { public UserHandle getUser() {
if (mEntry != null) return mEntry.getSbn().getUser(); return mUser;
if (mShortcutInfo != null) return mShortcutInfo.getUserHandle();
return null;
} }
@NonNull
public String getPackageName() { public String getPackageName() {
return mEntry == null return mPackageName;
? mShortcutInfo == null ? null : mShortcutInfo.getPackage()
: mEntry.getSbn().getPackageName();
} }
@Override @Override
@@ -318,9 +328,18 @@ class Bubble implements BubbleViewProvider {
/** /**
* Sets the entry associated with this bubble. * 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; mEntry = entry;
mLastUpdated = entry.getSbn().getPostTime(); 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();
}
} }
/** /**
@@ -434,28 +453,30 @@ class Bubble implements BubbleViewProvider {
return mFlyoutMessage; return mFlyoutMessage;
} }
int getRawDesiredHeight() {
return mDesiredHeight;
}
int getRawDesiredHeightResId() {
return mDesiredHeightResId;
}
float getDesiredHeight(Context context) { float getDesiredHeight(Context context) {
if (mEntry == null) return 0; boolean useRes = mDesiredHeightResId != 0;
Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
boolean useRes = data.getDesiredHeightResId() != 0;
if (useRes) { if (useRes) {
return getDimenForPackageUser(context, data.getDesiredHeightResId(), return getDimenForPackageUser(context, mDesiredHeightResId, mPackageName,
mEntry.getSbn().getPackageName(), mUser.getIdentifier());
mEntry.getSbn().getUser().getIdentifier());
} else { } else {
return data.getDesiredHeight() return mDesiredHeight * context.getResources().getDisplayMetrics().density;
* context.getResources().getDisplayMetrics().density;
} }
} }
String getDesiredHeightString() { String getDesiredHeightString() {
if (mEntry == null) return String.valueOf(0); boolean useRes = mDesiredHeightResId != 0;
Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
boolean useRes = data.getDesiredHeightResId() != 0;
if (useRes) { if (useRes) {
return String.valueOf(data.getDesiredHeightResId()); return String.valueOf(mDesiredHeightResId);
} else { } else {
return String.valueOf(data.getDesiredHeight()); return String.valueOf(mDesiredHeight);
} }
} }

View File

@@ -77,7 +77,8 @@ internal class BubbleDataRepository @Inject constructor(
var shortcutId = b.shortcutInfo?.id var shortcutId = b.shortcutInfo?.id
if (shortcutId == null) shortcutId = b.entry?.bubbleMetadata?.shortcutId if (shortcutId == null) shortcutId = b.entry?.bubbleMetadata?.shortcutId
if (shortcutId == null) return@mapNotNull null if (shortcutId == null) return@mapNotNull null
BubbleEntity(userId, b.packageName, shortcutId, b.key) BubbleEntity(userId, b.packageName, shortcutId, b.key, b.rawDesiredHeight,
b.rawDesiredHeightResId)
} }
} }
@@ -158,7 +159,8 @@ internal class BubbleDataRepository @Inject constructor(
val bubbles = entities.mapNotNull { entity -> val bubbles = entities.mapNotNull { entity ->
shortcutMap[ShortcutKey(entity.userId, entity.packageName)] shortcutMap[ShortcutKey(entity.userId, entity.packageName)]
?.first { shortcutInfo -> entity.shortcutId == shortcutInfo.id } ?.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) } uiScope.launch { cb(bubbles) }
} }

View File

@@ -15,11 +15,14 @@
*/ */
package com.android.systemui.bubbles.storage package com.android.systemui.bubbles.storage
import android.annotation.DimenRes
import android.annotation.UserIdInt import android.annotation.UserIdInt
data class BubbleEntity( data class BubbleEntity(
@UserIdInt val userId: Int, @UserIdInt val userId: Int,
val packageName: String, val packageName: String,
val shortcutId: String, val shortcutId: String,
val key: String val key: String,
val desiredHeight: Int,
@DimenRes val desiredHeightResId: Int
) )

View File

@@ -31,6 +31,8 @@ private const val ATTR_USER_ID = "uid"
private const val ATTR_PACKAGE = "pkg" private const val ATTR_PACKAGE = "pkg"
private const val ATTR_SHORTCUT_ID = "sid" private const val ATTR_SHORTCUT_ID = "sid"
private const val ATTR_KEY = "key" 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. * Writes the bubbles in xml format into given output stream.
@@ -59,6 +61,8 @@ private fun writeXmlEntry(serializer: XmlSerializer, bubble: BubbleEntity) {
serializer.attribute(null, ATTR_PACKAGE, bubble.packageName) serializer.attribute(null, ATTR_PACKAGE, bubble.packageName)
serializer.attribute(null, ATTR_SHORTCUT_ID, bubble.shortcutId) serializer.attribute(null, ATTR_SHORTCUT_ID, bubble.shortcutId)
serializer.attribute(null, ATTR_KEY, bubble.key) 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) serializer.endTag(null, TAG_BUBBLE)
} catch (e: IOException) { } catch (e: IOException) {
throw RuntimeException(e) throw RuntimeException(e)
@@ -86,7 +90,9 @@ private fun readXmlEntry(parser: XmlPullParser): BubbleEntity? {
parser.getAttributeWithName(ATTR_USER_ID)?.toInt() ?: return null, parser.getAttributeWithName(ATTR_USER_ID)?.toInt() ?: return null,
parser.getAttributeWithName(ATTR_PACKAGE) ?: return null, parser.getAttributeWithName(ATTR_PACKAGE) ?: return null,
parser.getAttributeWithName(ATTR_SHORTCUT_ID) ?: 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
) )
} }

View File

@@ -29,9 +29,9 @@ import org.junit.runner.RunWith
class BubblePersistentRepositoryTest : SysuiTestCase() { class BubblePersistentRepositoryTest : SysuiTestCase() {
private val bubbles = listOf( private val bubbles = listOf(
BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1"), BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0),
BubbleEntity(10, "com.example.chat", "alice and bob", "key-2"), BubbleEntity(10, "com.example.chat", "alice and bob", "key-2", 0, 16537428),
BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3") BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0)
) )
private lateinit var repository: BubblePersistentRepository private lateinit var repository: BubblePersistentRepository

View File

@@ -37,9 +37,9 @@ class BubbleVolatileRepositoryTest : SysuiTestCase() {
private val user0 = UserHandle.of(0) private val user0 = UserHandle.of(0)
private val user10 = UserHandle.of(10) private val user10 = UserHandle.of(10)
private val bubble1 = BubbleEntity(0, PKG_MESSENGER, "shortcut-1", "k1") private val bubble1 = BubbleEntity(0, PKG_MESSENGER, "shortcut-1", "k1", 120, 0)
private val bubble2 = BubbleEntity(10, PKG_CHAT, "alice and bob", "k2") private val bubble2 = BubbleEntity(10, PKG_CHAT, "alice and bob", "k2", 0, 16537428)
private val bubble3 = BubbleEntity(0, PKG_MESSENGER, "shortcut-2", "k3") private val bubble3 = BubbleEntity(0, PKG_MESSENGER, "shortcut-2", "k3", 120, 0)
private val bubbles = listOf(bubble1, bubble2, bubble3) private val bubbles = listOf(bubble1, bubble2, bubble3)

View File

@@ -31,17 +31,17 @@ import java.io.ByteArrayOutputStream
class BubbleXmlHelperTest : SysuiTestCase() { class BubbleXmlHelperTest : SysuiTestCase() {
private val bubbles = listOf( private val bubbles = listOf(
BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1"), BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0),
BubbleEntity(10, "com.example.chat", "alice and bob", "k2"), BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428),
BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3") BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0)
) )
@Test @Test
fun testWriteXml() { fun testWriteXml() {
val expectedEntries = """ val expectedEntries = """
<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" /> <bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" />
<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" /> <bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" />
<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" /> <bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" />
""".trimIndent() """.trimIndent()
ByteArrayOutputStream().use { ByteArrayOutputStream().use {
writeXml(it, bubbles) writeXml(it, bubbles)
@@ -56,9 +56,9 @@ class BubbleXmlHelperTest : SysuiTestCase() {
val src = """ val src = """
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<bs> <bs>
<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" /> <bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" />
<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" /> <bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" />
<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" /> <bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" />
</bs> </bs>
""".trimIndent() """.trimIndent()
val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8))) val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))