From 6e662a45b543873892af32b9e7b5bcf736374df9 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Wed, 24 Aug 2022 12:22:12 +0000 Subject: [PATCH] Revert^3 "Fix binder error when an app has many channels" f6d322577af7231c28d398096b3ca9b88260fa49 Change-Id: Ib42bf11c154e287119a5af0a4f92510cfb3a6cc7 --- .../android/app/NotificationChannelGroup.java | 21 ++++--- .../row/ChannelEditorDialogControllerTest.kt | 2 +- .../notification/PreferencesHelper.java | 55 ++++++++----------- .../notification/PreferencesHelperTest.java | 30 ---------- 4 files changed, 37 insertions(+), 71 deletions(-) diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java index 1769993e0e075..f97415ca20c8a 100644 --- a/core/java/android/app/NotificationChannelGroup.java +++ b/core/java/android/app/NotificationChannelGroup.java @@ -20,7 +20,6 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; -import android.content.pm.ParceledListSlice; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -67,7 +66,7 @@ public final class NotificationChannelGroup implements Parcelable { private CharSequence mName; private String mDescription; private boolean mBlocked; - private ParceledListSlice mChannels; + private List mChannels = new ArrayList<>(); // Bitwise representation of fields that have been changed by the user private int mUserLockedFields; @@ -101,8 +100,7 @@ public final class NotificationChannelGroup implements Parcelable { } else { mDescription = null; } - mChannels = in.readParcelable( - NotificationChannelGroup.class.getClassLoader(), ParceledListSlice.class); + in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader(), android.app.NotificationChannel.class); mBlocked = in.readBoolean(); mUserLockedFields = in.readInt(); } @@ -129,7 +127,7 @@ public final class NotificationChannelGroup implements Parcelable { } else { dest.writeByte((byte) 0); } - dest.writeParcelable(mChannels, flags); + dest.writeParcelableList(mChannels, flags); dest.writeBoolean(mBlocked); dest.writeInt(mUserLockedFields); } @@ -159,7 +157,7 @@ public final class NotificationChannelGroup implements Parcelable { * Returns the list of channels that belong to this group */ public List getChannels() { - return mChannels == null ? new ArrayList<>() : mChannels.getList(); + return mChannels; } /** @@ -190,11 +188,18 @@ public final class NotificationChannelGroup implements Parcelable { mBlocked = blocked; } + /** + * @hide + */ + public void addChannel(NotificationChannel channel) { + mChannels.add(channel); + } + /** * @hide */ public void setChannels(List channels) { - mChannels = new ParceledListSlice<>(channels); + mChannels = channels; } /** @@ -329,7 +334,7 @@ public final class NotificationChannelGroup implements Parcelable { proto.write(NotificationChannelGroupProto.NAME, mName.toString()); proto.write(NotificationChannelGroupProto.DESCRIPTION, mDescription); proto.write(NotificationChannelGroupProto.IS_BLOCKED, mBlocked); - for (NotificationChannel channel : mChannels.getList()) { + for (NotificationChannel channel : mChannels) { channel.dumpDebug(proto, NotificationChannelGroupProto.CHANNELS); } proto.end(token); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt index 214ba16dfc44b..64d0256287541 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt @@ -98,7 +98,7 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() { @Test fun testPrepareDialogForApp_onlyDefaultChannel() { - group.channels = listOf(channelDefault) + group.addChannel(channelDefault) controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID, setOf(channelDefault), appIcon, clickListener) diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 729c521a4ce07..477b8da61e0f5 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -86,7 +86,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -1328,17 +1327,16 @@ public class PreferencesHelper implements RankingConfig { return null; } NotificationChannelGroup group = r.groups.get(groupId).clone(); - ArrayList channels = new ArrayList(); + group.setChannels(new ArrayList<>()); int N = r.channels.size(); for (int i = 0; i < N; i++) { final NotificationChannel nc = r.channels.valueAt(i); if (includeDeleted || !nc.isDeleted()) { if (groupId.equals(nc.getGroup())) { - channels.add(nc); + group.addChannel(nc); } } } - group.setChannels(channels); return group; } } @@ -1351,10 +1349,7 @@ public class PreferencesHelper implements RankingConfig { if (r == null) { return null; } - if (r.groups.get(groupId) != null) { - return r.groups.get(groupId).clone(); - } - return null; + return r.groups.get(groupId); } } @@ -1362,48 +1357,44 @@ public class PreferencesHelper implements RankingConfig { public ParceledListSlice getNotificationChannelGroups(String pkg, int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty) { Objects.requireNonNull(pkg); - List groups = new ArrayList<>(); + Map groups = new ArrayMap<>(); synchronized (mPackagePreferences) { PackagePreferences r = getPackagePreferencesLocked(pkg, uid); if (r == null) { return ParceledListSlice.emptyList(); } - Map> groupedChannels = new HashMap(); + NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null); int N = r.channels.size(); for (int i = 0; i < N; i++) { final NotificationChannel nc = r.channels.valueAt(i); if (includeDeleted || !nc.isDeleted()) { if (nc.getGroup() != null) { if (r.groups.get(nc.getGroup()) != null) { - ArrayList channels = groupedChannels.getOrDefault( - nc.getGroup(), new ArrayList<>()); - channels.add(nc); - groupedChannels.put(nc.getGroup(), channels); + NotificationChannelGroup ncg = groups.get(nc.getGroup()); + if (ncg == null) { + ncg = r.groups.get(nc.getGroup()).clone(); + ncg.setChannels(new ArrayList<>()); + groups.put(nc.getGroup(), ncg); + + } + ncg.addChannel(nc); } } else { - ArrayList channels = groupedChannels.getOrDefault( - null, new ArrayList<>()); - channels.add(nc); - groupedChannels.put(null, channels); + nonGrouped.addChannel(nc); } } } - for (NotificationChannelGroup group : r.groups.values()) { - ArrayList channels = - groupedChannels.getOrDefault(group.getId(), new ArrayList<>()); - if (includeEmpty || !channels.isEmpty()) { - NotificationChannelGroup clone = group.clone(); - clone.setChannels(channels); - groups.add(clone); + if (includeNonGrouped && nonGrouped.getChannels().size() > 0) { + groups.put(null, nonGrouped); + } + if (includeEmpty) { + for (NotificationChannelGroup group : r.groups.values()) { + if (!groups.containsKey(group.getId())) { + groups.put(group.getId(), group); + } } } - - if (includeNonGrouped && groupedChannels.containsKey(null)) { - NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null); - nonGrouped.setChannels(groupedChannels.get(null)); - groups.add(nonGrouped); - } - return new ParceledListSlice<>(groups); + return new ParceledListSlice<>(new ArrayList<>(groups.values())); } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index d62ac99e530bf..598a22bbde393 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -93,7 +93,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.os.Parcel; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; @@ -2447,35 +2446,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { mLogger.get(6).event); // Final log is the deletion of the channel. } - @Test - public void testGetNotificationChannelGroup() throws Exception { - NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted"); - NotificationChannel base = - new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT); - base.setGroup("not"); - NotificationChannel convo = - new NotificationChannel("convo", "belongs to notDeleted", IMPORTANCE_DEFAULT); - convo.setGroup("not"); - convo.setConversationId("not deleted", "banana"); - - mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true); - mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, base, true, false); - mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, convo, true, false); - mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true); - - NotificationChannelGroup g - = mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1); - Parcel parcel = Parcel.obtain(); - g.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - - NotificationChannelGroup g2 - = mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1); - Parcel parcel2 = Parcel.obtain(); - g2.writeToParcel(parcel2, 0); - parcel2.setDataPosition(0); - } - @Test public void testOnUserRemoved() throws Exception { int[] user0Uids = {98, 235, 16, 3782};