Loading services/core/java/com/android/server/notification/PreferencesHelper.java +32 −14 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; Loading Loading @@ -125,7 +126,7 @@ public class PreferencesHelper implements RankingConfig { // pkg|uid => PackagePreferences private final ArrayMap<String, PackagePreferences> mPackagePreferences = new ArrayMap<>(); // pkg => PackagePreferences // pkg|userId => PackagePreferences private final ArrayMap<String, PackagePreferences> mRestoredWithoutUids = new ArrayMap<>(); private final Context mContext; Loading Loading @@ -172,9 +173,6 @@ public class PreferencesHelper implements RankingConfig { String tag = parser.getName(); if (!TAG_RANKING.equals(tag)) return; synchronized (mPackagePreferences) { // Clobber groups and channels with the xml, but don't delete other data that wasn't // present at the time of serialization. mRestoredWithoutUids.clear(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { tag = parser.getName(); if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) { Loading @@ -200,7 +198,8 @@ public class PreferencesHelper implements RankingConfig { } boolean skipWarningLogged = false; PackagePreferences r = getOrCreatePackagePreferencesLocked(name, uid, PackagePreferences r = getOrCreatePackagePreferencesLocked( name, userId, uid, XmlUtils.readIntAttribute( parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE), XmlUtils.readIntAttribute(parser, ATT_PRIORITY, Loading Loading @@ -311,17 +310,27 @@ public class PreferencesHelper implements RankingConfig { return mPackagePreferences.get(key); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, int uid) { return getOrCreatePackagePreferencesLocked(pkg, uid, private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, int uid) { return getOrCreatePackagePreferencesLocked(pkg, UserHandle.getUserId(uid), uid, DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY, DEFAULT_SHOW_BADGE, DEFAULT_ALLOW_BUBBLE); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, @UserIdInt int userId, int uid) { return getOrCreatePackagePreferencesLocked(pkg, userId, uid, DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY, DEFAULT_SHOW_BADGE, DEFAULT_ALLOW_BUBBLE); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, int uid, int importance, int priority, int visibility, boolean showBadge, boolean allowBubble) { private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, @UserIdInt int userId, int uid, int importance, int priority, int visibility, boolean showBadge, boolean allowBubble) { final String key = packagePreferencesKey(pkg, uid); PackagePreferences r = (uid == UNKNOWN_UID) ? mRestoredWithoutUids.get(pkg) r = (uid == UNKNOWN_UID) ? mRestoredWithoutUids.get(unrestoredPackageKey(pkg, userId)) : mPackagePreferences.get(key); if (r == null) { r = new PackagePreferences(); Loading @@ -340,7 +349,7 @@ public class PreferencesHelper implements RankingConfig { } if (r.uid == UNKNOWN_UID) { mRestoredWithoutUids.put(pkg, r); mRestoredWithoutUids.put(unrestoredPackageKey(pkg, userId), r); } else { mPackagePreferences.put(key, r); } Loading Loading @@ -382,6 +391,10 @@ public class PreferencesHelper implements RankingConfig { private boolean createDefaultChannelIfNeededLocked(PackagePreferences r) throws PackageManager.NameNotFoundException { if (r.uid == UNKNOWN_UID) { return false; } if (r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) { r.channels.get(NotificationChannel.DEFAULT_CHANNEL_ID).setName(mContext.getString( com.android.internal.R.string.default_notification_channel_label)); Loading Loading @@ -1769,17 +1782,18 @@ public class PreferencesHelper implements RankingConfig { synchronized (mPackagePreferences) { mPackagePreferences.remove(packagePreferencesKey(pkg, uid)); } mRestoredWithoutUids.remove(pkg); mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId)); updated = true; } } else { for (String pkg : pkgList) { // Package install final PackagePreferences r = mRestoredWithoutUids.get(pkg); final PackagePreferences r = mRestoredWithoutUids.get(unrestoredPackageKey(pkg, changeUserId)); if (r != null) { try { r.uid = mPm.getPackageUidAsUser(r.pkg, changeUserId); mRestoredWithoutUids.remove(pkg); mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId)); synchronized (mPackagePreferences) { mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r); } Loading Loading @@ -1910,6 +1924,10 @@ public class PreferencesHelper implements RankingConfig { return pkg + "|" + uid; } private static String unrestoredPackageKey(String pkg, @UserIdInt int userId) { return pkg + "|" + userId; } private static class PackagePreferences { String pkg; int uid = UNKNOWN_UID; Loading services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +53 −0 Original line number Diff line number Diff line Loading @@ -2715,4 +2715,57 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true)); assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true)); } @Test public void testRestoreMultiUser() throws Exception { String pkg = "restore_pkg"; String channelId = "channelId"; int user0Importance = 3; int user10Importance = 4; when(mPm.getPackageUidAsUser(eq(pkg), anyInt())).thenReturn(UserHandle.USER_NULL); // both users have the same package, but different notification settings final String xmlUser0 = "<ranking version=\"1\">\n" + "<package name=\"" + pkg + "\" >\n" + "<channel id=\"" + channelId + "\" name=\"hi\"" + " importance=\"" + user0Importance + "\"/>" + "</package>" + "</ranking>"; final String xmlUser10 = "<ranking version=\"1\">\n" + "<package name=\"" + pkg + "\" >\n" + "<channel id=\"" + channelId + "\" name=\"hi\"" + " importance=\"" + user10Importance + "\"/>" + "</package>" + "</ranking>"; // trigger a restore for both users XmlPullParser parser = Xml.newPullParser(); parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser0.getBytes())), null); parser.nextTag(); mHelper.readXml(parser, true, 0); parser = Xml.newPullParser(); parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser10.getBytes())), null); parser.nextTag(); mHelper.readXml(parser, true, 10); // "install" package on both users String[] pkgList = new String[] {pkg}; int[] uidList0 = new int[] {UserHandle.PER_USER_RANGE}; int[] uidList10 = new int[] {UserHandle.PER_USER_RANGE + 1}; when(mPm.getPackageUidAsUser(pkg, 0)).thenReturn(uidList0[0]); when(mPm.getPackageUidAsUser(pkg, 10)).thenReturn(uidList10[0]); ApplicationInfo info = new ApplicationInfo(); info.targetSdkVersion = Build.VERSION_CODES.Q; when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(info); mHelper.onPackagesChanged(false, 0, pkgList, uidList0); mHelper.onPackagesChanged(false, 10, pkgList, uidList10); assertEquals(user0Importance, mHelper.getNotificationChannel(pkg, uidList0[0], channelId, false).getImportance()); assertEquals(user10Importance, mHelper.getNotificationChannel( pkg, uidList10[0], channelId, false).getImportance()); } } Loading
services/core/java/com/android/server/notification/PreferencesHelper.java +32 −14 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; Loading Loading @@ -125,7 +126,7 @@ public class PreferencesHelper implements RankingConfig { // pkg|uid => PackagePreferences private final ArrayMap<String, PackagePreferences> mPackagePreferences = new ArrayMap<>(); // pkg => PackagePreferences // pkg|userId => PackagePreferences private final ArrayMap<String, PackagePreferences> mRestoredWithoutUids = new ArrayMap<>(); private final Context mContext; Loading Loading @@ -172,9 +173,6 @@ public class PreferencesHelper implements RankingConfig { String tag = parser.getName(); if (!TAG_RANKING.equals(tag)) return; synchronized (mPackagePreferences) { // Clobber groups and channels with the xml, but don't delete other data that wasn't // present at the time of serialization. mRestoredWithoutUids.clear(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { tag = parser.getName(); if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) { Loading @@ -200,7 +198,8 @@ public class PreferencesHelper implements RankingConfig { } boolean skipWarningLogged = false; PackagePreferences r = getOrCreatePackagePreferencesLocked(name, uid, PackagePreferences r = getOrCreatePackagePreferencesLocked( name, userId, uid, XmlUtils.readIntAttribute( parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE), XmlUtils.readIntAttribute(parser, ATT_PRIORITY, Loading Loading @@ -311,17 +310,27 @@ public class PreferencesHelper implements RankingConfig { return mPackagePreferences.get(key); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, int uid) { return getOrCreatePackagePreferencesLocked(pkg, uid, private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, int uid) { return getOrCreatePackagePreferencesLocked(pkg, UserHandle.getUserId(uid), uid, DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY, DEFAULT_SHOW_BADGE, DEFAULT_ALLOW_BUBBLE); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, @UserIdInt int userId, int uid) { return getOrCreatePackagePreferencesLocked(pkg, userId, uid, DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY, DEFAULT_SHOW_BADGE, DEFAULT_ALLOW_BUBBLE); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, int uid, int importance, int priority, int visibility, boolean showBadge, boolean allowBubble) { private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, @UserIdInt int userId, int uid, int importance, int priority, int visibility, boolean showBadge, boolean allowBubble) { final String key = packagePreferencesKey(pkg, uid); PackagePreferences r = (uid == UNKNOWN_UID) ? mRestoredWithoutUids.get(pkg) r = (uid == UNKNOWN_UID) ? mRestoredWithoutUids.get(unrestoredPackageKey(pkg, userId)) : mPackagePreferences.get(key); if (r == null) { r = new PackagePreferences(); Loading @@ -340,7 +349,7 @@ public class PreferencesHelper implements RankingConfig { } if (r.uid == UNKNOWN_UID) { mRestoredWithoutUids.put(pkg, r); mRestoredWithoutUids.put(unrestoredPackageKey(pkg, userId), r); } else { mPackagePreferences.put(key, r); } Loading Loading @@ -382,6 +391,10 @@ public class PreferencesHelper implements RankingConfig { private boolean createDefaultChannelIfNeededLocked(PackagePreferences r) throws PackageManager.NameNotFoundException { if (r.uid == UNKNOWN_UID) { return false; } if (r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) { r.channels.get(NotificationChannel.DEFAULT_CHANNEL_ID).setName(mContext.getString( com.android.internal.R.string.default_notification_channel_label)); Loading Loading @@ -1769,17 +1782,18 @@ public class PreferencesHelper implements RankingConfig { synchronized (mPackagePreferences) { mPackagePreferences.remove(packagePreferencesKey(pkg, uid)); } mRestoredWithoutUids.remove(pkg); mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId)); updated = true; } } else { for (String pkg : pkgList) { // Package install final PackagePreferences r = mRestoredWithoutUids.get(pkg); final PackagePreferences r = mRestoredWithoutUids.get(unrestoredPackageKey(pkg, changeUserId)); if (r != null) { try { r.uid = mPm.getPackageUidAsUser(r.pkg, changeUserId); mRestoredWithoutUids.remove(pkg); mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId)); synchronized (mPackagePreferences) { mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r); } Loading Loading @@ -1910,6 +1924,10 @@ public class PreferencesHelper implements RankingConfig { return pkg + "|" + uid; } private static String unrestoredPackageKey(String pkg, @UserIdInt int userId) { return pkg + "|" + userId; } private static class PackagePreferences { String pkg; int uid = UNKNOWN_UID; Loading
services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +53 −0 Original line number Diff line number Diff line Loading @@ -2715,4 +2715,57 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true)); assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true)); } @Test public void testRestoreMultiUser() throws Exception { String pkg = "restore_pkg"; String channelId = "channelId"; int user0Importance = 3; int user10Importance = 4; when(mPm.getPackageUidAsUser(eq(pkg), anyInt())).thenReturn(UserHandle.USER_NULL); // both users have the same package, but different notification settings final String xmlUser0 = "<ranking version=\"1\">\n" + "<package name=\"" + pkg + "\" >\n" + "<channel id=\"" + channelId + "\" name=\"hi\"" + " importance=\"" + user0Importance + "\"/>" + "</package>" + "</ranking>"; final String xmlUser10 = "<ranking version=\"1\">\n" + "<package name=\"" + pkg + "\" >\n" + "<channel id=\"" + channelId + "\" name=\"hi\"" + " importance=\"" + user10Importance + "\"/>" + "</package>" + "</ranking>"; // trigger a restore for both users XmlPullParser parser = Xml.newPullParser(); parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser0.getBytes())), null); parser.nextTag(); mHelper.readXml(parser, true, 0); parser = Xml.newPullParser(); parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xmlUser10.getBytes())), null); parser.nextTag(); mHelper.readXml(parser, true, 10); // "install" package on both users String[] pkgList = new String[] {pkg}; int[] uidList0 = new int[] {UserHandle.PER_USER_RANGE}; int[] uidList10 = new int[] {UserHandle.PER_USER_RANGE + 1}; when(mPm.getPackageUidAsUser(pkg, 0)).thenReturn(uidList0[0]); when(mPm.getPackageUidAsUser(pkg, 10)).thenReturn(uidList10[0]); ApplicationInfo info = new ApplicationInfo(); info.targetSdkVersion = Build.VERSION_CODES.Q; when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(info); mHelper.onPackagesChanged(false, 0, pkgList, uidList0); mHelper.onPackagesChanged(false, 10, pkgList, uidList10); assertEquals(user0Importance, mHelper.getNotificationChannel(pkg, uidList0[0], channelId, false).getImportance()); assertEquals(user10Importance, mHelper.getNotificationChannel( pkg, uidList10[0], channelId, false).getImportance()); } }