Merge "Revert^2 "Fix binder error when an app has many channels"" into tm-qpr-dev

This commit is contained in:
Julia Reynolds
2022-08-22 13:56:41 +00:00
committed by Android (Google) Code Review
4 changed files with 71 additions and 37 deletions

View File

@@ -20,6 +20,7 @@ import android.annotation.SystemApi;
import android.annotation.TestApi; import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.TextUtils; import android.text.TextUtils;
@@ -66,7 +67,7 @@ public final class NotificationChannelGroup implements Parcelable {
private CharSequence mName; private CharSequence mName;
private String mDescription; private String mDescription;
private boolean mBlocked; private boolean mBlocked;
private List<NotificationChannel> mChannels = new ArrayList<>(); private ParceledListSlice<NotificationChannel> mChannels;
// Bitwise representation of fields that have been changed by the user // Bitwise representation of fields that have been changed by the user
private int mUserLockedFields; private int mUserLockedFields;
@@ -100,7 +101,8 @@ public final class NotificationChannelGroup implements Parcelable {
} else { } else {
mDescription = null; mDescription = null;
} }
in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader(), android.app.NotificationChannel.class); mChannels = in.readParcelable(
NotificationChannelGroup.class.getClassLoader(), ParceledListSlice.class);
mBlocked = in.readBoolean(); mBlocked = in.readBoolean();
mUserLockedFields = in.readInt(); mUserLockedFields = in.readInt();
} }
@@ -127,7 +129,7 @@ public final class NotificationChannelGroup implements Parcelable {
} else { } else {
dest.writeByte((byte) 0); dest.writeByte((byte) 0);
} }
dest.writeParcelableList(mChannels, flags); dest.writeParcelable(mChannels, flags);
dest.writeBoolean(mBlocked); dest.writeBoolean(mBlocked);
dest.writeInt(mUserLockedFields); dest.writeInt(mUserLockedFields);
} }
@@ -157,7 +159,7 @@ public final class NotificationChannelGroup implements Parcelable {
* Returns the list of channels that belong to this group * Returns the list of channels that belong to this group
*/ */
public List<NotificationChannel> getChannels() { public List<NotificationChannel> getChannels() {
return mChannels; return mChannels == null ? new ArrayList<>() : mChannels.getList();
} }
/** /**
@@ -188,18 +190,11 @@ public final class NotificationChannelGroup implements Parcelable {
mBlocked = blocked; mBlocked = blocked;
} }
/**
* @hide
*/
public void addChannel(NotificationChannel channel) {
mChannels.add(channel);
}
/** /**
* @hide * @hide
*/ */
public void setChannels(List<NotificationChannel> channels) { public void setChannels(List<NotificationChannel> channels) {
mChannels = channels; mChannels = new ParceledListSlice<>(channels);
} }
/** /**
@@ -334,7 +329,7 @@ public final class NotificationChannelGroup implements Parcelable {
proto.write(NotificationChannelGroupProto.NAME, mName.toString()); proto.write(NotificationChannelGroupProto.NAME, mName.toString());
proto.write(NotificationChannelGroupProto.DESCRIPTION, mDescription); proto.write(NotificationChannelGroupProto.DESCRIPTION, mDescription);
proto.write(NotificationChannelGroupProto.IS_BLOCKED, mBlocked); proto.write(NotificationChannelGroupProto.IS_BLOCKED, mBlocked);
for (NotificationChannel channel : mChannels) { for (NotificationChannel channel : mChannels.getList()) {
channel.dumpDebug(proto, NotificationChannelGroupProto.CHANNELS); channel.dumpDebug(proto, NotificationChannelGroupProto.CHANNELS);
} }
proto.end(token); proto.end(token);

View File

@@ -98,7 +98,7 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() {
@Test @Test
fun testPrepareDialogForApp_onlyDefaultChannel() { fun testPrepareDialogForApp_onlyDefaultChannel() {
group.addChannel(channelDefault) group.channels = listOf(channelDefault)
controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID, controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
setOf(channelDefault), appIcon, clickListener) setOf(channelDefault), appIcon, clickListener)

View File

@@ -86,6 +86,7 @@ import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@@ -1327,16 +1328,17 @@ public class PreferencesHelper implements RankingConfig {
return null; return null;
} }
NotificationChannelGroup group = r.groups.get(groupId).clone(); NotificationChannelGroup group = r.groups.get(groupId).clone();
group.setChannels(new ArrayList<>()); ArrayList channels = new ArrayList();
int N = r.channels.size(); int N = r.channels.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
final NotificationChannel nc = r.channels.valueAt(i); final NotificationChannel nc = r.channels.valueAt(i);
if (includeDeleted || !nc.isDeleted()) { if (includeDeleted || !nc.isDeleted()) {
if (groupId.equals(nc.getGroup())) { if (groupId.equals(nc.getGroup())) {
group.addChannel(nc); channels.add(nc);
} }
} }
} }
group.setChannels(channels);
return group; return group;
} }
} }
@@ -1349,7 +1351,10 @@ public class PreferencesHelper implements RankingConfig {
if (r == null) { if (r == null) {
return null; return null;
} }
return r.groups.get(groupId); if (r.groups.get(groupId) != null) {
return r.groups.get(groupId).clone();
}
return null;
} }
} }
@@ -1357,44 +1362,48 @@ public class PreferencesHelper implements RankingConfig {
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg, public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty) { int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty) {
Objects.requireNonNull(pkg); Objects.requireNonNull(pkg);
Map<String, NotificationChannelGroup> groups = new ArrayMap<>(); List<NotificationChannelGroup> groups = new ArrayList<>();
synchronized (mPackagePreferences) { synchronized (mPackagePreferences) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid); PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) { if (r == null) {
return ParceledListSlice.emptyList(); return ParceledListSlice.emptyList();
} }
NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null); Map<String, ArrayList<NotificationChannel>> groupedChannels = new HashMap();
int N = r.channels.size(); int N = r.channels.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
final NotificationChannel nc = r.channels.valueAt(i); final NotificationChannel nc = r.channels.valueAt(i);
if (includeDeleted || !nc.isDeleted()) { if (includeDeleted || !nc.isDeleted()) {
if (nc.getGroup() != null) { if (nc.getGroup() != null) {
if (r.groups.get(nc.getGroup()) != null) { if (r.groups.get(nc.getGroup()) != null) {
NotificationChannelGroup ncg = groups.get(nc.getGroup()); ArrayList<NotificationChannel> channels = groupedChannels.getOrDefault(
if (ncg == null) { nc.getGroup(), new ArrayList<>());
ncg = r.groups.get(nc.getGroup()).clone(); channels.add(nc);
ncg.setChannels(new ArrayList<>()); groupedChannels.put(nc.getGroup(), channels);
groups.put(nc.getGroup(), ncg);
}
ncg.addChannel(nc);
} }
} else { } else {
nonGrouped.addChannel(nc); ArrayList<NotificationChannel> channels = groupedChannels.getOrDefault(
null, new ArrayList<>());
channels.add(nc);
groupedChannels.put(null, channels);
} }
} }
} }
if (includeNonGrouped && nonGrouped.getChannels().size() > 0) { for (NotificationChannelGroup group : r.groups.values()) {
groups.put(null, nonGrouped); ArrayList<NotificationChannel> channels =
} groupedChannels.getOrDefault(group.getId(), new ArrayList<>());
if (includeEmpty) { if (includeEmpty || !channels.isEmpty()) {
for (NotificationChannelGroup group : r.groups.values()) { NotificationChannelGroup clone = group.clone();
if (!groups.containsKey(group.getId())) { clone.setChannels(channels);
groups.put(group.getId(), group); groups.add(clone);
}
} }
} }
return new ParceledListSlice<>(new ArrayList<>(groups.values()));
if (includeNonGrouped && groupedChannels.containsKey(null)) {
NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null);
nonGrouped.setChannels(groupedChannels.get(null));
groups.add(nonGrouped);
}
return new ParceledListSlice<>(groups);
} }
} }

View File

@@ -93,6 +93,7 @@ import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel;
import android.os.RemoteCallback; import android.os.RemoteCallback;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
@@ -2446,6 +2447,35 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mLogger.get(6).event); // Final log is the deletion of the channel. 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 @Test
public void testOnUserRemoved() throws Exception { public void testOnUserRemoved() throws Exception {
int[] user0Uids = {98, 235, 16, 3782}; int[] user0Uids = {98, 235, 16, 3782};