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 0ee1f06423520..8697be9db3fd1 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
@@ -124,6 +124,7 @@ public class Bubble implements BubbleViewProvider {
private int mDesiredHeight;
@DimenRes
private int mDesiredHeightResId;
+ private int mTaskId;
/** for logging **/
@Nullable
@@ -162,7 +163,7 @@ public class Bubble implements BubbleViewProvider {
*/
Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo,
final int desiredHeight, final int desiredHeightResId, @Nullable final String title,
- Executor mainExecutor) {
+ int taskId, Executor mainExecutor) {
Objects.requireNonNull(key);
Objects.requireNonNull(shortcutInfo);
mMetadataShortcutId = shortcutInfo.getId();
@@ -178,6 +179,7 @@ public class Bubble implements BubbleViewProvider {
mTitle = title;
mShowBubbleUpdateDot = false;
mMainExecutor = mainExecutor;
+ mTaskId = taskId;
}
@VisibleForTesting(visibility = PRIVATE)
@@ -197,6 +199,7 @@ public class Bubble implements BubbleViewProvider {
});
};
mMainExecutor = mainExecutor;
+ mTaskId = INVALID_TASK_ID;
setEntry(entry);
}
@@ -520,7 +523,7 @@ public class Bubble implements BubbleViewProvider {
*/
@Override
public int getTaskId() {
- return mExpandedView != null ? mExpandedView.getTaskId() : INVALID_TASK_ID;
+ return mExpandedView != null ? mExpandedView.getTaskId() : mTaskId;
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
index 3108b02cc0102..241755227af02 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
@@ -28,7 +28,6 @@ import com.android.wm.shell.bubbles.storage.BubbleEntity
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.bubbles.storage.BubbleVolatileRepository
import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.common.annotations.ExternalThread
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -36,8 +35,11 @@ import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
-internal class BubbleDataRepository(context: Context, private val launcherApps: LauncherApps,
- private val mainExecutor : ShellExecutor) {
+internal class BubbleDataRepository(
+ context: Context,
+ private val launcherApps: LauncherApps,
+ private val mainExecutor: ShellExecutor
+) {
private val volatileRepository = BubbleVolatileRepository(launcherApps)
private val persistentRepository = BubblePersistentRepository(context)
@@ -78,7 +80,8 @@ internal class BubbleDataRepository(context: Context, private val launcherApps:
b.key,
b.rawDesiredHeight,
b.rawDesiredHeightResId,
- b.title
+ b.title,
+ b.taskId
)
}
}
@@ -168,6 +171,7 @@ internal class BubbleDataRepository(context: Context, private val launcherApps:
entity.desiredHeight,
entity.desiredHeightResId,
entity.title,
+ entity.taskId,
mainExecutor
) }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleEntity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleEntity.kt
index aeba302bf4876..d5cab5af42e4b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleEntity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleEntity.kt
@@ -25,5 +25,6 @@ data class BubbleEntity(
val key: String,
val desiredHeight: Int,
@DimenRes val desiredHeightResId: Int,
- val title: String? = null
+ val title: String? = null,
+ val taskId: Int
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt
index fe72bd301e04d..470011b136fed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt
@@ -15,6 +15,7 @@
*/
package com.android.wm.shell.bubbles.storage
+import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.util.Xml
import com.android.internal.util.FastXmlSerializer
import com.android.internal.util.XmlUtils
@@ -38,6 +39,7 @@ private const val ATTR_KEY = "key"
private const val ATTR_DESIRED_HEIGHT = "h"
private const val ATTR_DESIRED_HEIGHT_RES_ID = "hid"
private const val ATTR_TITLE = "t"
+private const val ATTR_TASK_ID = "tid"
/**
* Writes the bubbles in xml format into given output stream.
@@ -70,6 +72,7 @@ private fun writeXmlEntry(serializer: XmlSerializer, bubble: BubbleEntity) {
serializer.attribute(null, ATTR_DESIRED_HEIGHT, bubble.desiredHeight.toString())
serializer.attribute(null, ATTR_DESIRED_HEIGHT_RES_ID, bubble.desiredHeightResId.toString())
bubble.title?.let { serializer.attribute(null, ATTR_TITLE, it) }
+ serializer.attribute(null, ATTR_TASK_ID, bubble.taskId.toString())
serializer.endTag(null, TAG_BUBBLE)
} catch (e: IOException) {
throw RuntimeException(e)
@@ -103,7 +106,8 @@ private fun readXmlEntry(parser: XmlPullParser): BubbleEntity? {
parser.getAttributeWithName(ATTR_KEY) ?: return null,
parser.getAttributeWithName(ATTR_DESIRED_HEIGHT)?.toInt() ?: return null,
parser.getAttributeWithName(ATTR_DESIRED_HEIGHT_RES_ID)?.toInt() ?: return null,
- parser.getAttributeWithName(ATTR_TITLE)
+ parser.getAttributeWithName(ATTR_TITLE),
+ parser.getAttributeWithName(ATTR_TASK_ID)?.toInt() ?: INVALID_TASK_ID
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
index 416028088294f..bdf75fcd8816f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.bubbles.storage
+import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
@@ -31,9 +32,10 @@ import org.junit.runner.RunWith
class BubblePersistentRepositoryTest : ShellTestCase() {
private val bubbles = listOf(
- BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0),
- BubbleEntity(10, "com.example.chat", "alice and bob", "key-2", 0, 16537428, "title"),
- BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0)
+ BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0, null, 1),
+ BubbleEntity(10, "com.example.chat", "alice and bob", "key-2", 0, 16537428, "title", 2),
+ BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0, null,
+ INVALID_TASK_ID)
)
private lateinit var repository: BubblePersistentRepository
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
index dd1a6a5a281eb..05795fde7d6c8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.bubbles.storage
+import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.content.pm.LauncherApps
import android.os.UserHandle
import android.testing.AndroidTestingRunner
@@ -37,10 +38,12 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
private val user0 = UserHandle.of(0)
private val user10 = UserHandle.of(10)
- private val bubble1 = BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0)
+ private val bubble1 = BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0,
+ null, 1)
private val bubble2 = BubbleEntity(10, "com.example.chat", "alice and bob",
- "key-2", 0, 16537428, "title")
- private val bubble3 = BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0)
+ "key-2", 0, 16537428, "title", 2)
+ private val bubble3 = BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0,
+ null, INVALID_TASK_ID)
private val bubbles = listOf(bubble1, bubble2, bubble3)
@@ -105,13 +108,13 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
@Test
fun testAddBubbleMatchesByKey() {
- val bubble = BubbleEntity(0, "com.example.pkg", "shortcut-id", "key", 120, 0, "title")
+ val bubble = BubbleEntity(0, "com.example.pkg", "shortcut-id", "key", 120, 0, "title", 1)
repository.addBubbles(listOf(bubble))
assertEquals(bubble, repository.bubbles.get(0))
// Same key as first bubble but different entry
val bubbleModified = BubbleEntity(0, "com.example.pkg", "shortcut-id", "key", 120, 0,
- "different title")
+ "different title", 2)
repository.addBubbles(listOf(bubbleModified))
assertEquals(bubbleModified, repository.bubbles.get(0))
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt
index e0891a95c6a6f..839b873d0c238 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.bubbles.storage
+import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
@@ -31,17 +32,18 @@ import java.io.ByteArrayOutputStream
class BubbleXmlHelperTest : ShellTestCase() {
private val bubbles = listOf(
- BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0),
- BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428, "title"),
- BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0)
+ BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, null, 1),
+ BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428, "title", 2),
+ BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0, null,
+ INVALID_TASK_ID)
)
@Test
fun testWriteXml() {
val expectedEntries = """
-
-
-
+
+
+
""".trimIndent()
ByteArrayOutputStream().use {
writeXml(it, bubbles)
@@ -56,9 +58,9 @@ class BubbleXmlHelperTest : ShellTestCase() {
val src = """
-
-
-
+
+
+
""".trimIndent()
val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))
@@ -79,4 +81,32 @@ class BubbleXmlHelperTest : ShellTestCase() {
val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))
assertEquals("failed parsing bubbles from xml\n$src", emptyList(), actual)
}
+
+ /**
+ * In S we changed the XML to include a taskId, version didn't increase because we can set a
+ * reasonable default for taskId (INVALID_TASK_ID) if it wasn't in the XML previously, this
+ * tests that that works.
+ */
+ @Test
+ fun testReadXMLWithoutTaskId() {
+ val expectedBubbles = listOf(
+ BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, null,
+ INVALID_TASK_ID),
+ BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428, "title",
+ INVALID_TASK_ID),
+ BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0, null,
+ INVALID_TASK_ID)
+ )
+
+ val src = """
+
+
+
+
+
+
+ """.trimIndent()
+ val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))
+ assertEquals("failed parsing bubbles from xml\n$src", expectedBubbles, actual)
+ }
}
\ No newline at end of file