Merge "persist desired height of bubbles to disk" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
16fd58a01e
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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.
|
||||
@@ -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)
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ class BubbleVolatileRepositoryTest : SysuiTestCase() {
|
||||
private val user0 = UserHandle.of(0)
|
||||
private val user10 = UserHandle.of(10)
|
||||
|
||||
private val bubble1 = BubbleEntity(0, PKG_MESSENGER, "shortcut-1", "k1")
|
||||
private val bubble2 = BubbleEntity(10, PKG_CHAT, "alice and bob", "k2")
|
||||
private val bubble3 = BubbleEntity(0, PKG_MESSENGER, "shortcut-2", "k3")
|
||||
private val bubble1 = BubbleEntity(0, PKG_MESSENGER, "shortcut-1", "k1", 120, 0)
|
||||
private val bubble2 = BubbleEntity(10, PKG_CHAT, "alice and bob", "k2", 0, 16537428)
|
||||
private val bubble3 = BubbleEntity(0, PKG_MESSENGER, "shortcut-2", "k3", 120, 0)
|
||||
|
||||
private val bubbles = listOf(bubble1, bubble2, bubble3)
|
||||
|
||||
|
||||
@@ -31,17 +31,17 @@ import java.io.ByteArrayOutputStream
|
||||
class BubbleXmlHelperTest : SysuiTestCase() {
|
||||
|
||||
private val bubbles = listOf(
|
||||
BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1"),
|
||||
BubbleEntity(10, "com.example.chat", "alice and bob", "k2"),
|
||||
BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3")
|
||||
BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0),
|
||||
BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428),
|
||||
BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0)
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testWriteXml() {
|
||||
val expectedEntries = """
|
||||
<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" />
|
||||
<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" />
|
||||
<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" />
|
||||
<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" h="0" hid="16537428" />
|
||||
<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" />
|
||||
""".trimIndent()
|
||||
ByteArrayOutputStream().use {
|
||||
writeXml(it, bubbles)
|
||||
@@ -56,9 +56,9 @@ class BubbleXmlHelperTest : SysuiTestCase() {
|
||||
val src = """
|
||||
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
|
||||
<bs>
|
||||
<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" />
|
||||
<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" />
|
||||
<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" />
|
||||
<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" h="0" hid="16537428" />
|
||||
<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" />
|
||||
</bs>
|
||||
""".trimIndent()
|
||||
val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))
|
||||
|
||||
Reference in New Issue
Block a user