summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/app/NotificationChannel.java1
-rw-r--r--core/java/android/app/NotificationChannelGroup.java9
-rw-r--r--core/java/android/app/NotificationManager.java35
-rw-r--r--core/tests/coretests/src/android/app/NotificationManagerTest.java69
5 files changed, 101 insertions, 15 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index daa1902edf02..1e21991cd380 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -369,7 +369,7 @@ package android.app {
}
public final class NotificationChannel implements android.os.Parcelable {
- method @FlaggedApi("android.service.notification.notification_conversation_channel_management") @NonNull public android.app.NotificationChannel copy();
+ method @NonNull public android.app.NotificationChannel copy();
method public int getOriginalImportance();
method public boolean isImportanceLockedByCriticalDeviceFunction();
method public void lockFields(int);
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index d88395331656..c1d80c93cfd6 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -508,7 +508,6 @@ public final class NotificationChannel implements Parcelable {
/** @hide */
@TestApi
@NonNull
- @FlaggedApi(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
public NotificationChannel copy() {
NotificationChannel copy = new NotificationChannel(mId, mName, mImportance);
copy.setDescription(mDesc);
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
index 92db8b329045..06b492c417d8 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -221,7 +221,10 @@ public final class NotificationChannelGroup implements Parcelable {
* @hide
*/
public void setChannels(List<NotificationChannel> channels) {
- mChannels = channels;
+ mChannels.clear();
+ if (channels != null) {
+ mChannels.addAll(channels);
+ }
}
/**
@@ -331,7 +334,9 @@ public final class NotificationChannelGroup implements Parcelable {
NotificationChannelGroup cloned = new NotificationChannelGroup(getId(), getName());
cloned.setDescription(getDescription());
cloned.setBlocked(isBlocked());
- cloned.setChannels(getChannels());
+ for (NotificationChannel c : mChannels) {
+ cloned.addChannel(c.copy());
+ }
cloned.lockFields(mUserLockedFields);
return cloned;
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 69e3ef9086d5..f24eb0a63b26 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1317,10 +1317,16 @@ public class NotificationManager {
*/
public List<NotificationChannel> getNotificationChannels() {
if (Flags.nmBinderPerfCacheChannels()) {
- return mNotificationChannelListCache.query(new NotificationChannelQuery(
- mContext.getOpPackageName(),
- mContext.getPackageName(),
- mContext.getUserId()));
+ List<NotificationChannel> channelList = mNotificationChannelListCache.query(
+ new NotificationChannelQuery(mContext.getOpPackageName(),
+ mContext.getPackageName(), mContext.getUserId()));
+ List<NotificationChannel> out = new ArrayList();
+ if (channelList != null) {
+ for (NotificationChannel c : channelList) {
+ out.add(c.copy());
+ }
+ }
+ return out;
} else {
INotificationManager service = service();
try {
@@ -1343,7 +1349,7 @@ public class NotificationManager {
}
for (NotificationChannel channel : channels) {
if (channelId.equals(channel.getId())) {
- return channel;
+ return channel.copy();
}
}
return null;
@@ -1364,12 +1370,12 @@ public class NotificationManager {
for (NotificationChannel channel : channels) {
if (conversationId.equals(channel.getConversationId())
&& channelId.equals(channel.getParentChannelId())) {
- return channel;
+ return channel.copy();
} else if (channelId.equals(channel.getId())) {
parent = channel;
}
}
- return parent;
+ return parent != null ? parent.copy() : null;
}
/**
@@ -1405,8 +1411,9 @@ public class NotificationManager {
new NotificationChannelQuery(pkgName, pkgName, mContext.getUserId()));
Map<String, NotificationChannelGroup> groupHeaders =
mNotificationChannelGroupsCache.query(pkgName);
- return NotificationChannelGroupsHelper.getGroupWithChannels(channelGroupId, channelList,
- groupHeaders, /* includeDeleted= */ false);
+ NotificationChannelGroup ncg = NotificationChannelGroupsHelper.getGroupWithChannels(
+ channelGroupId, channelList, groupHeaders, /* includeDeleted= */ false);
+ return ncg != null ? ncg.clone() : null;
} else {
INotificationManager service = service();
try {
@@ -1428,8 +1435,14 @@ public class NotificationManager {
new NotificationChannelQuery(pkgName, pkgName, mContext.getUserId()));
Map<String, NotificationChannelGroup> groupHeaders =
mNotificationChannelGroupsCache.query(pkgName);
- return NotificationChannelGroupsHelper.getGroupsWithChannels(channelList, groupHeaders,
- NotificationChannelGroupsHelper.Params.forAllGroups());
+ List<NotificationChannelGroup> populatedGroupList =
+ NotificationChannelGroupsHelper.getGroupsWithChannels(channelList, groupHeaders,
+ NotificationChannelGroupsHelper.Params.forAllGroups());
+ List<NotificationChannelGroup> out = new ArrayList<>();
+ for (NotificationChannelGroup g : populatedGroupList) {
+ out.add(g.clone());
+ }
+ return out;
} else {
INotificationManager service = service();
try {
diff --git a/core/tests/coretests/src/android/app/NotificationManagerTest.java b/core/tests/coretests/src/android/app/NotificationManagerTest.java
index 250b9ce8d89d..001eb620dd0f 100644
--- a/core/tests/coretests/src/android/app/NotificationManagerTest.java
+++ b/core/tests/coretests/src/android/app/NotificationManagerTest.java
@@ -442,6 +442,44 @@ public class NotificationManagerTest {
@Test
@EnableFlags(Flags.FLAG_NM_BINDER_PERF_CACHE_CHANNELS)
+ public void getNotificationChannel_localModificationDoesNotChangeCache() throws Exception {
+ NotificationManager.invalidateNotificationChannelCache();
+ NotificationChannel original = new NotificationChannel("id", "name",
+ NotificationManager.IMPORTANCE_DEFAULT);
+ NotificationChannel originalConv = new NotificationChannel("", "name_conversation",
+ NotificationManager.IMPORTANCE_DEFAULT);
+ originalConv.setConversationId("id", "id_conversation");
+ when(mNotificationManager.mBackendService.getNotificationChannels(any(), any(),
+ anyInt())).thenReturn(new ParceledListSlice<>(
+ List.of(original.copy(), originalConv.copy())));
+
+ // modify the output channel, but only locally
+ NotificationChannel out = mNotificationManager.getNotificationChannel("id");
+ out.setName("modified");
+
+ // This should not change the result of getNotificationChannel
+ assertThat(mNotificationManager.getNotificationChannel("id")).isEqualTo(original);
+ assertThat(mNotificationManager.getNotificationChannel("id")).isNotEqualTo(out);
+
+ // and also check the conversation channel
+ NotificationChannel outConv = mNotificationManager.getNotificationChannel("id",
+ "id_conversation");
+ outConv.setName("conversation_modified");
+ assertThat(mNotificationManager.getNotificationChannel("id", "id_conversation")).isEqualTo(
+ originalConv);
+ assertThat(
+ mNotificationManager.getNotificationChannel("id", "id_conversation")).isNotEqualTo(
+ outConv);
+
+ // nonexistent conversation returns the (not modified) parent channel
+ assertThat(mNotificationManager.getNotificationChannel("id", "nonexistent")).isEqualTo(
+ original);
+ assertThat(mNotificationManager.getNotificationChannel("id", "nonexistent")).isNotEqualTo(
+ out);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_CACHE_CHANNELS)
public void getNotificationChannelGroup_cachedUntilInvalidated() throws Exception {
// Data setup: group has some channels in it
NotificationChannelGroup g1 = new NotificationChannelGroup("g1", "group one");
@@ -521,6 +559,37 @@ public class NotificationManagerTest {
}
@Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_CACHE_CHANNELS)
+ public void getNotificationChannelGroup_localModificationDoesNotChangeCache() throws Exception {
+ // Group setup
+ NotificationChannelGroup g1 = new NotificationChannelGroup("g1", "group one");
+ NotificationChannel nc1 = new NotificationChannel("nc1", "channel one",
+ NotificationManager.IMPORTANCE_DEFAULT);
+ nc1.setGroup("g1");
+ NotificationChannel nc2 = new NotificationChannel("nc2", "channel two",
+ NotificationManager.IMPORTANCE_DEFAULT);
+ nc2.setGroup("g1");
+
+ NotificationManager.invalidateNotificationChannelCache();
+ NotificationManager.invalidateNotificationChannelGroupCache();
+ when(mNotificationManager.mBackendService.getNotificationChannelGroupsWithoutChannels(
+ any())).thenReturn(new ParceledListSlice<>(List.of(g1.clone())));
+ when(mNotificationManager.mBackendService.getNotificationChannels(any(), any(), anyInt()))
+ .thenReturn(new ParceledListSlice<>(List.of(nc1.copy(), nc2.copy())));
+
+ NotificationChannelGroup g1result = mNotificationManager.getNotificationChannelGroup("g1");
+ g1result.setDescription("something different!");
+ for (NotificationChannel c : g1result.getChannels()) {
+ c.setDescription("also something different");
+ }
+
+ // expected output equivalent to original, unchanged
+ NotificationChannelGroup expectedG1 = g1.clone();
+ expectedG1.setChannels(List.of(nc1, nc2));
+ assertThat(mNotificationManager.getNotificationChannelGroup("g1")).isEqualTo(expectedG1);
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_MODES_UI)
public void areAutomaticZenRulesUserManaged_handheld_isTrue() {
PackageManager pm = mock(PackageManager.class);