Loading services/core/java/com/android/server/notification/NotificationManagerService.java +8 −7 Original line number Diff line number Diff line Loading @@ -5073,7 +5073,7 @@ public class NotificationManagerService extends SystemService { final DumpFilter filter = DumpFilter.parseFromArguments(args); final long token = Binder.clearCallingIdentity(); try { final ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions = final ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions = getAllUsersNotificationPermissions(); if (filter.stats) { dumpJson(pw, filter, pkgPermissions); Loading Loading @@ -5911,17 +5911,18 @@ public class NotificationManagerService extends SystemService { // Returns a single map containing that info keyed by (uid, package name) for all users. // Because this calls into mPermissionHelper, this method must never be called with a lock held. @VisibleForTesting protected ArrayMap<Pair<Integer, String>, Boolean> getAllUsersNotificationPermissions() { protected ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> getAllUsersNotificationPermissions() { // don't bother if migration is not enabled if (!mEnableAppSettingMigration) { return null; } ArrayMap<Pair<Integer, String>, Boolean> allPermissions = new ArrayMap<>(); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> allPermissions = new ArrayMap<>(); final List<UserInfo> allUsers = mUm.getUsers(); // for each of these, get the package notification permissions that are associated // with this user and add it to the map for (UserInfo ui : allUsers) { ArrayMap<Pair<Integer, String>, Boolean> userPermissions = ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> userPermissions = mPermissionHelper.getNotificationPermissionValues( ui.getUserHandle().getIdentifier()); for (Pair<Integer, String> pair : userPermissions.keySet()) { Loading @@ -5932,7 +5933,7 @@ public class NotificationManagerService extends SystemService { } private void dumpJson(PrintWriter pw, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONObject dump = new JSONObject(); try { dump.put("service", "Notification Manager"); Loading @@ -5956,7 +5957,7 @@ public class NotificationManagerService extends SystemService { } private void dumpProto(FileDescriptor fd, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { final ProtoOutputStream proto = new ProtoOutputStream(fd); synchronized (mNotificationLock) { int N = mNotificationList.size(); Loading Loading @@ -6047,7 +6048,7 @@ public class NotificationManagerService extends SystemService { } void dumpImpl(PrintWriter pw, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { pw.print("Current Notification Manager state"); if (filter.filtered) { pw.print(" (filtered to "); pw.print(filter); pw.print(")"); Loading services/core/java/com/android/server/notification/PermissionHelper.java +18 −6 Original line number Diff line number Diff line Loading @@ -36,10 +36,8 @@ import android.util.Slog; import com.android.server.pm.permission.PermissionManagerServiceInternal; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; Loading Loading @@ -139,15 +137,17 @@ public final class PermissionHelper { return granted; } // Key: (uid, package name); Value: (granted, user set) public @NonNull ArrayMap<Pair<Integer, String>, Boolean> getNotificationPermissionValues( int userId) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> getNotificationPermissionValues(int userId) { assertFlag(); ArrayMap<Pair<Integer, String>, Boolean> notifPermissions = new ArrayMap<>(); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>(); Set<Pair<Integer, String>> allRequestingUids = getAppsRequestingPermission(userId); Set<Pair<Integer, String>> allApprovedUids = getAppsGrantedPermission(userId); for (Pair<Integer, String> pair : allRequestingUids) { notifPermissions.put(pair, allApprovedUids.contains(pair)); notifPermissions.put(pair, new Pair(allApprovedUids.contains(pair), isPermissionUserSet(pair.second /* package name */, userId))); } return notifPermissions; } Loading Loading @@ -196,6 +196,18 @@ public final class PermissionHelper { return false; } boolean isPermissionUserSet(String packageName, @UserIdInt int userId) { assertFlag(); try { int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION, userId); return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; } catch (RemoteException e) { Slog.e(TAG, "Could not reach system server", e); } return false; } private void assertFlag() { if (!mMigrationEnabled) { throw new IllegalStateException("Method called without checking flag value"); Loading services/core/java/com/android/server/notification/PreferencesHelper.java +29 −22 Original line number Diff line number Diff line Loading @@ -557,7 +557,7 @@ public class PreferencesHelper implements RankingConfig { out.attributeBoolean(null, ATT_HIDE_SILENT, mHideSilentStatusBarIcons); out.endTag(null, TAG_STATUS_ICONS); } ArrayMap<Pair<Integer, String>, Boolean> notifPermissions = new ArrayMap<>(); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>(); if (mPermissionHelper.isMigrationEnabled() && forBackup) { notifPermissions = mPermissionHelper.getNotificationPermissionValues(userId); } Loading @@ -573,9 +573,8 @@ public class PreferencesHelper implements RankingConfig { out.attribute(null, ATT_NAME, r.pkg); if (!notifPermissions.isEmpty()) { Pair<Integer, String> app = new Pair(r.uid, r.pkg); out.attributeInt(null, ATT_IMPORTANCE, notifPermissions.get(app) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); out.attributeInt(null, ATT_IMPORTANCE, notifPermissions.get(app).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); notifPermissions.remove(app); } else { if (r.importance != DEFAULT_IMPORTANCE) { Loading Loading @@ -642,7 +641,7 @@ public class PreferencesHelper implements RankingConfig { out.startTag(null, TAG_PACKAGE); out.attribute(null, ATT_NAME, app.second); out.attributeInt(null, ATT_IMPORTANCE, notifPermissions.get(app) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); notifPermissions.get(app).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); out.endTag(null, TAG_PACKAGE); } } Loading Loading @@ -1932,7 +1931,7 @@ public class PreferencesHelper implements RankingConfig { public void dump(PrintWriter pw, String prefix, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { pw.print(prefix); pw.println("per-package config version: " + XML_VERSION); Loading @@ -1946,7 +1945,7 @@ public class PreferencesHelper implements RankingConfig { public void dump(ProtoOutputStream proto, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { synchronized (mPackagePreferences) { dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS, filter, mPackagePreferences, pkgPermissions); Loading @@ -1958,7 +1957,7 @@ public class PreferencesHelper implements RankingConfig { private void dumpPackagePreferencesLocked(PrintWriter pw, String prefix, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<String, PackagePreferences> packagePreferences, ArrayMap<Pair<Integer, String>, Boolean> packagePermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> packagePermissions) { // Used for tracking which package preferences we've seen already for notification // permission reasons; after handling packages with local preferences, we'll want to dump // the ones with notification permissions set but not local prefs. Loading Loading @@ -1987,8 +1986,10 @@ public class PreferencesHelper implements RankingConfig { if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { pw.print(" importance="); pw.print(NotificationListenerService.Ranking.importanceToString( packagePermissions.get(key) packagePermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); pw.print(" userSet="); pw.print(packagePermissions.get(key).second); pkgsWithPermissionsToHandle.remove(key); } } Loading Loading @@ -2042,7 +2043,10 @@ public class PreferencesHelper implements RankingConfig { pw.print(')'); pw.print(" importance="); pw.print(NotificationListenerService.Ranking.importanceToString( packagePermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); packagePermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); pw.print(" userSet="); pw.print(packagePermissions.get(p).second); pw.println(); } } Loading @@ -2052,7 +2056,7 @@ public class PreferencesHelper implements RankingConfig { private void dumpPackagePreferencesLocked(ProtoOutputStream proto, long fieldId, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<String, PackagePreferences> packagePreferences, ArrayMap<Pair<Integer, String>, Boolean> packagePermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> packagePermissions) { Set<Pair<Integer, String>> pkgsWithPermissionsToHandle = null; if (packagePermissions != null) { pkgsWithPermissionsToHandle = packagePermissions.keySet(); Loading @@ -2071,7 +2075,8 @@ public class PreferencesHelper implements RankingConfig { Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { proto.write(RankingHelperProto.RecordProto.IMPORTANCE, packagePermissions.get(key) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); packagePermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); pkgsWithPermissionsToHandle.remove(key); } } else { Loading Loading @@ -2099,7 +2104,8 @@ public class PreferencesHelper implements RankingConfig { proto.write(RankingHelperProto.RecordProto.PACKAGE, p.second); proto.write(RankingHelperProto.RecordProto.UID, p.first); proto.write(RankingHelperProto.RecordProto.IMPORTANCE, packagePermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); packagePermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); proto.end(fToken); } } Loading @@ -2110,7 +2116,7 @@ public class PreferencesHelper implements RankingConfig { * Fills out {@link PackageNotificationPreferences} proto and wraps it in a {@link StatsEvent}. */ public void pullPackagePreferencesStats(List<StatsEvent> events, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { Set<Pair<Integer, String>> pkgsWithPermissionsToHandle = null; if (pkgPermissions != null) { pkgsWithPermissionsToHandle = pkgPermissions.keySet(); Loading @@ -2134,7 +2140,8 @@ public class PreferencesHelper implements RankingConfig { int importance = IMPORTANCE_NONE; Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); if (pkgPermissions != null && pkgsWithPermissionsToHandle.contains(key)) { importance = pkgPermissions.get(key) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE; importance = pkgPermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE; pkgsWithPermissionsToHandle.remove(key); } event.writeInt(importance); Loading @@ -2158,7 +2165,7 @@ public class PreferencesHelper implements RankingConfig { .setAtomId(PACKAGE_NOTIFICATION_PREFERENCES); event.writeInt(p.first); event.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true); event.writeInt(pkgPermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); event.writeInt(pkgPermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); // fill out the rest of the fields with default values so as not to confuse the // builder Loading Loading @@ -2236,7 +2243,7 @@ public class PreferencesHelper implements RankingConfig { } public JSONObject dumpJson(NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONObject ranking = new JSONObject(); JSONArray PackagePreferencess = new JSONArray(); try { Loading Loading @@ -2266,7 +2273,7 @@ public class PreferencesHelper implements RankingConfig { && pkgsWithPermissionsToHandle.contains(key)) { PackagePreferences.put("importance", NotificationListenerService.Ranking.importanceToString( pkgPermissions.get(key) pkgPermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); pkgsWithPermissionsToHandle.remove(key); } Loading Loading @@ -2316,7 +2323,7 @@ public class PreferencesHelper implements RankingConfig { PackagePreferences.put("packageName", p.second); PackagePreferences.put("importance", NotificationListenerService.Ranking.importanceToString( pkgPermissions.get(p) pkgPermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); } catch (JSONException e) { // pass Loading Loading @@ -2344,7 +2351,7 @@ public class PreferencesHelper implements RankingConfig { * @return */ public JSONArray dumpBansJson(NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONArray bans = new JSONArray(); Map<Integer, String> packageBans = mPermissionHelper.isMigrationEnabled() ? getPermissionBasedPackageBans(pkgPermissions) : getPackageBans(); Loading Loading @@ -2383,11 +2390,11 @@ public class PreferencesHelper implements RankingConfig { // Same functionality as getPackageBans by extracting the set of packages from the provided // map that are disallowed from sending notifications. protected Map<Integer, String> getPermissionBasedPackageBans( ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { ArrayMap<Integer, String> packageBans = new ArrayMap<>(); if (pkgPermissions != null) { for (Pair<Integer, String> p : pkgPermissions.keySet()) { if (!pkgPermissions.get(p)) { if (!pkgPermissions.get(p).first) { packageBans.put(p.first, p.second); } } Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +14 −10 Original line number Diff line number Diff line Loading @@ -840,21 +840,25 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { when(mUm.getUsers()).thenReturn(userInfos); // construct the permissions for each of them ArrayMap<Pair<Integer, String>, Boolean> permissions0 = new ArrayMap<>(), ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> permissions0 = new ArrayMap<>(), permissions1 = new ArrayMap<>(); permissions0.put(new Pair<>(10, "package1"), true); permissions0.put(new Pair<>(20, "package2"), false); permissions1.put(new Pair<>(11, "package1"), false); permissions1.put(new Pair<>(21, "package2"), true); permissions0.put(new Pair<>(10, "package1"), new Pair<>(true, false)); permissions0.put(new Pair<>(20, "package2"), new Pair<>(false, true)); permissions1.put(new Pair<>(11, "package1"), new Pair<>(false, false)); permissions1.put(new Pair<>(21, "package2"), new Pair<>(true, true)); when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(permissions0); when(mPermissionHelper.getNotificationPermissionValues(1)).thenReturn(permissions1); when(mPermissionHelper.getNotificationPermissionValues(2)).thenReturn(new ArrayMap<>()); ArrayMap<Pair<Integer, String>, Boolean> combinedPermissions = ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> combinedPermissions = mService.getAllUsersNotificationPermissions(); assertTrue(combinedPermissions.get(new Pair<>(10, "package1"))); assertFalse(combinedPermissions.get(new Pair<>(20, "package2"))); assertFalse(combinedPermissions.get(new Pair<>(11, "package1"))); assertTrue(combinedPermissions.get(new Pair<>(21, "package2"))); assertTrue(combinedPermissions.get(new Pair<>(10, "package1")).first); assertFalse(combinedPermissions.get(new Pair<>(10, "package1")).second); assertFalse(combinedPermissions.get(new Pair<>(20, "package2")).first); assertTrue(combinedPermissions.get(new Pair<>(20, "package2")).second); assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).first); assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).second); assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).first); assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).second); } } services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java +16 −5 Original line number Diff line number Diff line Loading @@ -313,11 +313,22 @@ public class PermissionHelperTest extends UiServiceTestCase { when(mPackageManager.getInstalledPackages(eq((long) GET_PERMISSIONS), anyInt())) .thenReturn(requesting); Map<Pair<Integer, String>, Boolean> expected = ImmutableMap.of(new Pair(1, "first"), true, new Pair(2, "second"), true, new Pair(3, "third"), false); Map<Pair<Integer, String>, Boolean> actual = // 2 and 3 are user-set permissions when(mPermManager.getPermissionFlags( "first", Manifest.permission.POST_NOTIFICATIONS, userId)).thenReturn(0); when(mPermManager.getPermissionFlags( "second", Manifest.permission.POST_NOTIFICATIONS, userId)) .thenReturn(FLAG_PERMISSION_USER_SET); when(mPermManager.getPermissionFlags( "third", Manifest.permission.POST_NOTIFICATIONS, userId)) .thenReturn(FLAG_PERMISSION_USER_SET); Map<Pair<Integer, String>, Pair<Boolean, Boolean>> expected = ImmutableMap.of(new Pair(1, "first"), new Pair(true, false), new Pair(2, "second"), new Pair(true, true), new Pair(3, "third"), new Pair(false, true)); Map<Pair<Integer, String>, Pair<Boolean, Boolean>> actual = mPermissionHelper.getNotificationPermissionValues(userId); assertThat(actual).containsExactlyEntriesIn(expected); Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +8 −7 Original line number Diff line number Diff line Loading @@ -5073,7 +5073,7 @@ public class NotificationManagerService extends SystemService { final DumpFilter filter = DumpFilter.parseFromArguments(args); final long token = Binder.clearCallingIdentity(); try { final ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions = final ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions = getAllUsersNotificationPermissions(); if (filter.stats) { dumpJson(pw, filter, pkgPermissions); Loading Loading @@ -5911,17 +5911,18 @@ public class NotificationManagerService extends SystemService { // Returns a single map containing that info keyed by (uid, package name) for all users. // Because this calls into mPermissionHelper, this method must never be called with a lock held. @VisibleForTesting protected ArrayMap<Pair<Integer, String>, Boolean> getAllUsersNotificationPermissions() { protected ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> getAllUsersNotificationPermissions() { // don't bother if migration is not enabled if (!mEnableAppSettingMigration) { return null; } ArrayMap<Pair<Integer, String>, Boolean> allPermissions = new ArrayMap<>(); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> allPermissions = new ArrayMap<>(); final List<UserInfo> allUsers = mUm.getUsers(); // for each of these, get the package notification permissions that are associated // with this user and add it to the map for (UserInfo ui : allUsers) { ArrayMap<Pair<Integer, String>, Boolean> userPermissions = ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> userPermissions = mPermissionHelper.getNotificationPermissionValues( ui.getUserHandle().getIdentifier()); for (Pair<Integer, String> pair : userPermissions.keySet()) { Loading @@ -5932,7 +5933,7 @@ public class NotificationManagerService extends SystemService { } private void dumpJson(PrintWriter pw, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONObject dump = new JSONObject(); try { dump.put("service", "Notification Manager"); Loading @@ -5956,7 +5957,7 @@ public class NotificationManagerService extends SystemService { } private void dumpProto(FileDescriptor fd, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { final ProtoOutputStream proto = new ProtoOutputStream(fd); synchronized (mNotificationLock) { int N = mNotificationList.size(); Loading Loading @@ -6047,7 +6048,7 @@ public class NotificationManagerService extends SystemService { } void dumpImpl(PrintWriter pw, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { pw.print("Current Notification Manager state"); if (filter.filtered) { pw.print(" (filtered to "); pw.print(filter); pw.print(")"); Loading
services/core/java/com/android/server/notification/PermissionHelper.java +18 −6 Original line number Diff line number Diff line Loading @@ -36,10 +36,8 @@ import android.util.Slog; import com.android.server.pm.permission.PermissionManagerServiceInternal; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; Loading Loading @@ -139,15 +137,17 @@ public final class PermissionHelper { return granted; } // Key: (uid, package name); Value: (granted, user set) public @NonNull ArrayMap<Pair<Integer, String>, Boolean> getNotificationPermissionValues( int userId) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> getNotificationPermissionValues(int userId) { assertFlag(); ArrayMap<Pair<Integer, String>, Boolean> notifPermissions = new ArrayMap<>(); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>(); Set<Pair<Integer, String>> allRequestingUids = getAppsRequestingPermission(userId); Set<Pair<Integer, String>> allApprovedUids = getAppsGrantedPermission(userId); for (Pair<Integer, String> pair : allRequestingUids) { notifPermissions.put(pair, allApprovedUids.contains(pair)); notifPermissions.put(pair, new Pair(allApprovedUids.contains(pair), isPermissionUserSet(pair.second /* package name */, userId))); } return notifPermissions; } Loading Loading @@ -196,6 +196,18 @@ public final class PermissionHelper { return false; } boolean isPermissionUserSet(String packageName, @UserIdInt int userId) { assertFlag(); try { int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION, userId); return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; } catch (RemoteException e) { Slog.e(TAG, "Could not reach system server", e); } return false; } private void assertFlag() { if (!mMigrationEnabled) { throw new IllegalStateException("Method called without checking flag value"); Loading
services/core/java/com/android/server/notification/PreferencesHelper.java +29 −22 Original line number Diff line number Diff line Loading @@ -557,7 +557,7 @@ public class PreferencesHelper implements RankingConfig { out.attributeBoolean(null, ATT_HIDE_SILENT, mHideSilentStatusBarIcons); out.endTag(null, TAG_STATUS_ICONS); } ArrayMap<Pair<Integer, String>, Boolean> notifPermissions = new ArrayMap<>(); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>(); if (mPermissionHelper.isMigrationEnabled() && forBackup) { notifPermissions = mPermissionHelper.getNotificationPermissionValues(userId); } Loading @@ -573,9 +573,8 @@ public class PreferencesHelper implements RankingConfig { out.attribute(null, ATT_NAME, r.pkg); if (!notifPermissions.isEmpty()) { Pair<Integer, String> app = new Pair(r.uid, r.pkg); out.attributeInt(null, ATT_IMPORTANCE, notifPermissions.get(app) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); out.attributeInt(null, ATT_IMPORTANCE, notifPermissions.get(app).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); notifPermissions.remove(app); } else { if (r.importance != DEFAULT_IMPORTANCE) { Loading Loading @@ -642,7 +641,7 @@ public class PreferencesHelper implements RankingConfig { out.startTag(null, TAG_PACKAGE); out.attribute(null, ATT_NAME, app.second); out.attributeInt(null, ATT_IMPORTANCE, notifPermissions.get(app) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); notifPermissions.get(app).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); out.endTag(null, TAG_PACKAGE); } } Loading Loading @@ -1932,7 +1931,7 @@ public class PreferencesHelper implements RankingConfig { public void dump(PrintWriter pw, String prefix, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { pw.print(prefix); pw.println("per-package config version: " + XML_VERSION); Loading @@ -1946,7 +1945,7 @@ public class PreferencesHelper implements RankingConfig { public void dump(ProtoOutputStream proto, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { synchronized (mPackagePreferences) { dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS, filter, mPackagePreferences, pkgPermissions); Loading @@ -1958,7 +1957,7 @@ public class PreferencesHelper implements RankingConfig { private void dumpPackagePreferencesLocked(PrintWriter pw, String prefix, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<String, PackagePreferences> packagePreferences, ArrayMap<Pair<Integer, String>, Boolean> packagePermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> packagePermissions) { // Used for tracking which package preferences we've seen already for notification // permission reasons; after handling packages with local preferences, we'll want to dump // the ones with notification permissions set but not local prefs. Loading Loading @@ -1987,8 +1986,10 @@ public class PreferencesHelper implements RankingConfig { if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { pw.print(" importance="); pw.print(NotificationListenerService.Ranking.importanceToString( packagePermissions.get(key) packagePermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); pw.print(" userSet="); pw.print(packagePermissions.get(key).second); pkgsWithPermissionsToHandle.remove(key); } } Loading Loading @@ -2042,7 +2043,10 @@ public class PreferencesHelper implements RankingConfig { pw.print(')'); pw.print(" importance="); pw.print(NotificationListenerService.Ranking.importanceToString( packagePermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); packagePermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); pw.print(" userSet="); pw.print(packagePermissions.get(p).second); pw.println(); } } Loading @@ -2052,7 +2056,7 @@ public class PreferencesHelper implements RankingConfig { private void dumpPackagePreferencesLocked(ProtoOutputStream proto, long fieldId, @NonNull NotificationManagerService.DumpFilter filter, ArrayMap<String, PackagePreferences> packagePreferences, ArrayMap<Pair<Integer, String>, Boolean> packagePermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> packagePermissions) { Set<Pair<Integer, String>> pkgsWithPermissionsToHandle = null; if (packagePermissions != null) { pkgsWithPermissionsToHandle = packagePermissions.keySet(); Loading @@ -2071,7 +2075,8 @@ public class PreferencesHelper implements RankingConfig { Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { proto.write(RankingHelperProto.RecordProto.IMPORTANCE, packagePermissions.get(key) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); packagePermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); pkgsWithPermissionsToHandle.remove(key); } } else { Loading Loading @@ -2099,7 +2104,8 @@ public class PreferencesHelper implements RankingConfig { proto.write(RankingHelperProto.RecordProto.PACKAGE, p.second); proto.write(RankingHelperProto.RecordProto.UID, p.first); proto.write(RankingHelperProto.RecordProto.IMPORTANCE, packagePermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); packagePermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); proto.end(fToken); } } Loading @@ -2110,7 +2116,7 @@ public class PreferencesHelper implements RankingConfig { * Fills out {@link PackageNotificationPreferences} proto and wraps it in a {@link StatsEvent}. */ public void pullPackagePreferencesStats(List<StatsEvent> events, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { Set<Pair<Integer, String>> pkgsWithPermissionsToHandle = null; if (pkgPermissions != null) { pkgsWithPermissionsToHandle = pkgPermissions.keySet(); Loading @@ -2134,7 +2140,8 @@ public class PreferencesHelper implements RankingConfig { int importance = IMPORTANCE_NONE; Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); if (pkgPermissions != null && pkgsWithPermissionsToHandle.contains(key)) { importance = pkgPermissions.get(key) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE; importance = pkgPermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE; pkgsWithPermissionsToHandle.remove(key); } event.writeInt(importance); Loading @@ -2158,7 +2165,7 @@ public class PreferencesHelper implements RankingConfig { .setAtomId(PACKAGE_NOTIFICATION_PREFERENCES); event.writeInt(p.first); event.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true); event.writeInt(pkgPermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); event.writeInt(pkgPermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); // fill out the rest of the fields with default values so as not to confuse the // builder Loading Loading @@ -2236,7 +2243,7 @@ public class PreferencesHelper implements RankingConfig { } public JSONObject dumpJson(NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONObject ranking = new JSONObject(); JSONArray PackagePreferencess = new JSONArray(); try { Loading Loading @@ -2266,7 +2273,7 @@ public class PreferencesHelper implements RankingConfig { && pkgsWithPermissionsToHandle.contains(key)) { PackagePreferences.put("importance", NotificationListenerService.Ranking.importanceToString( pkgPermissions.get(key) pkgPermissions.get(key).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); pkgsWithPermissionsToHandle.remove(key); } Loading Loading @@ -2316,7 +2323,7 @@ public class PreferencesHelper implements RankingConfig { PackagePreferences.put("packageName", p.second); PackagePreferences.put("importance", NotificationListenerService.Ranking.importanceToString( pkgPermissions.get(p) pkgPermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); } catch (JSONException e) { // pass Loading Loading @@ -2344,7 +2351,7 @@ public class PreferencesHelper implements RankingConfig { * @return */ public JSONArray dumpBansJson(NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONArray bans = new JSONArray(); Map<Integer, String> packageBans = mPermissionHelper.isMigrationEnabled() ? getPermissionBasedPackageBans(pkgPermissions) : getPackageBans(); Loading Loading @@ -2383,11 +2390,11 @@ public class PreferencesHelper implements RankingConfig { // Same functionality as getPackageBans by extracting the set of packages from the provided // map that are disallowed from sending notifications. protected Map<Integer, String> getPermissionBasedPackageBans( ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) { ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { ArrayMap<Integer, String> packageBans = new ArrayMap<>(); if (pkgPermissions != null) { for (Pair<Integer, String> p : pkgPermissions.keySet()) { if (!pkgPermissions.get(p)) { if (!pkgPermissions.get(p).first) { packageBans.put(p.first, p.second); } } Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +14 −10 Original line number Diff line number Diff line Loading @@ -840,21 +840,25 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { when(mUm.getUsers()).thenReturn(userInfos); // construct the permissions for each of them ArrayMap<Pair<Integer, String>, Boolean> permissions0 = new ArrayMap<>(), ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> permissions0 = new ArrayMap<>(), permissions1 = new ArrayMap<>(); permissions0.put(new Pair<>(10, "package1"), true); permissions0.put(new Pair<>(20, "package2"), false); permissions1.put(new Pair<>(11, "package1"), false); permissions1.put(new Pair<>(21, "package2"), true); permissions0.put(new Pair<>(10, "package1"), new Pair<>(true, false)); permissions0.put(new Pair<>(20, "package2"), new Pair<>(false, true)); permissions1.put(new Pair<>(11, "package1"), new Pair<>(false, false)); permissions1.put(new Pair<>(21, "package2"), new Pair<>(true, true)); when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(permissions0); when(mPermissionHelper.getNotificationPermissionValues(1)).thenReturn(permissions1); when(mPermissionHelper.getNotificationPermissionValues(2)).thenReturn(new ArrayMap<>()); ArrayMap<Pair<Integer, String>, Boolean> combinedPermissions = ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> combinedPermissions = mService.getAllUsersNotificationPermissions(); assertTrue(combinedPermissions.get(new Pair<>(10, "package1"))); assertFalse(combinedPermissions.get(new Pair<>(20, "package2"))); assertFalse(combinedPermissions.get(new Pair<>(11, "package1"))); assertTrue(combinedPermissions.get(new Pair<>(21, "package2"))); assertTrue(combinedPermissions.get(new Pair<>(10, "package1")).first); assertFalse(combinedPermissions.get(new Pair<>(10, "package1")).second); assertFalse(combinedPermissions.get(new Pair<>(20, "package2")).first); assertTrue(combinedPermissions.get(new Pair<>(20, "package2")).second); assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).first); assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).second); assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).first); assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).second); } }
services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java +16 −5 Original line number Diff line number Diff line Loading @@ -313,11 +313,22 @@ public class PermissionHelperTest extends UiServiceTestCase { when(mPackageManager.getInstalledPackages(eq((long) GET_PERMISSIONS), anyInt())) .thenReturn(requesting); Map<Pair<Integer, String>, Boolean> expected = ImmutableMap.of(new Pair(1, "first"), true, new Pair(2, "second"), true, new Pair(3, "third"), false); Map<Pair<Integer, String>, Boolean> actual = // 2 and 3 are user-set permissions when(mPermManager.getPermissionFlags( "first", Manifest.permission.POST_NOTIFICATIONS, userId)).thenReturn(0); when(mPermManager.getPermissionFlags( "second", Manifest.permission.POST_NOTIFICATIONS, userId)) .thenReturn(FLAG_PERMISSION_USER_SET); when(mPermManager.getPermissionFlags( "third", Manifest.permission.POST_NOTIFICATIONS, userId)) .thenReturn(FLAG_PERMISSION_USER_SET); Map<Pair<Integer, String>, Pair<Boolean, Boolean>> expected = ImmutableMap.of(new Pair(1, "first"), new Pair(true, false), new Pair(2, "second"), new Pair(true, true), new Pair(3, "third"), new Pair(false, true)); Map<Pair<Integer, String>, Pair<Boolean, Boolean>> actual = mPermissionHelper.getNotificationPermissionValues(userId); assertThat(actual).containsExactlyEntriesIn(expected); Loading