Loading core/java/android/app/INotificationManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -271,6 +271,6 @@ interface INotificationManager int[] getAllowedAdjustmentKeyTypes(); void setAssistantAdjustmentKeyTypeState(int type, boolean enabled); int[] getAllowedAdjustmentKeyTypesForPackage(String pkg); void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, boolean enabled); String[] getTypeAdjustmentDeniedPackages(); void setTypeAdjustmentForPackageState(String pkg, boolean enabled); } core/java/android/app/NotificationManager.java +2 −4 Original line number Diff line number Diff line Loading @@ -2163,12 +2163,10 @@ public class NotificationManager { * @hide */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void setAssistantAdjustmentKeyTypeStateForPackage(@NonNull String pkg, @Adjustment.Types int type, boolean enabled) { public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) { INotificationManager service = service(); try { service.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); service.setTypeAdjustmentForPackageState(pkg, enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading services/core/java/com/android/server/notification/NotificationManagerService.java +28 −142 Original line number Diff line number Diff line Loading @@ -3037,10 +3037,9 @@ public class NotificationManagerService extends SystemService { switch(atomTag) { case PACKAGE_NOTIFICATION_PREFERENCES: if (notificationClassificationUi()) { Set<String> pkgs = mAssistants.getPackagesWithKeyTypeAdjustmentSettings(); mPreferencesHelper.pullPackagePreferencesStats(data, getAllUsersNotificationPermissions(), getPackageSpecificAdjustmentKeyTypes(pkgs)); new ArrayMap<>()); } else { mPreferencesHelper.pullPackagePreferencesStats(data, getAllUsersNotificationPermissions()); Loading Loading @@ -4401,16 +4400,16 @@ public class NotificationManagerService extends SystemService { @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { public @NonNull String[] getTypeAdjustmentDeniedPackages() { checkCallerIsSystemOrSystemUiOrShell(); return mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg); return mAssistants.getTypeAdjustmentDeniedPackages(); } @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, boolean enabled) { public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); mAssistants.setTypeAdjustmentForPackageState(pkg, enabled); handleSavePolicyFile(); } Loading Loading @@ -7219,7 +7218,7 @@ public class NotificationManagerService extends SystemService { toRemove.add(potentialKey); } else if (notificationClassificationUi() && !mAssistants.isTypeAdjustmentAllowedForPackage( r.getSbn().getPackageName(), adjustments.getInt(KEY_TYPE))) { r.getSbn().getPackageName())) { toRemove.add(potentialKey); } } Loading Loading @@ -7556,24 +7555,6 @@ public class NotificationManagerService extends SystemService { return allPermissions; } @VisibleForTesting @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected @NonNull Map<String, Set<Integer>> getPackageSpecificAdjustmentKeyTypes( Set<String> pkgs) { ArrayMap<String, Set<Integer>> pkgToAllowedTypes = new ArrayMap<>(); for (String pkg : pkgs) { int[] allowedTypesArray = mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg); if (allowedTypesArray != null) { Set<Integer> allowedTypes = new ArraySet<Integer>(); for (int i : allowedTypesArray) { allowedTypes.add(i); } pkgToAllowedTypes.append(pkg, allowedTypes); } } return pkgToAllowedTypes; } private void dumpJson(PrintWriter pw, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONObject dump = new JSONObject(); Loading Loading @@ -11889,11 +11870,7 @@ public class NotificationManagerService extends SystemService { private static final String ATT_DENIED = "denied_adjustments"; private static final String ATT_ENABLED_TYPES = "enabled_key_types"; private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments"; // Encapsulates a list of packages and the bundle types enabled for each package. private static final String TAG_TYPES_ENABLED_FOR_APPS = "types_enabled_for_apps"; // Encapsulates the bundle types enabled for a package. private static final String ATT_APP_ENABLED_TYPES = "app_enabled_types"; private static final String ATT_PACKAGE = "package"; private static final String ATT_TYPES_DENIED_APPS = "types_denied_apps"; private final Object mLock = new Object(); Loading @@ -11909,14 +11886,8 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mLock") private Map<Integer, HashSet<String>> mNasUnsupported = new ArrayMap<>(); // Types of classifications (aka bundles) enabled/allowed for this package. // If the set is NULL (or package is not in the list), default classification allow list // (the global one) should be used. // If the set is empty, that indicates the package explicitly has all classifications // disallowed. @GuardedBy("mLock") private Map<String, Set<Integer>> mClassificationTypePackagesEnabledTypes = new ArrayMap<>(); private Set<String> mClassificationTypeDeniedPackages = new ArraySet<>(); protected ComponentName mDefaultFromConfig = null; Loading Loading @@ -12120,104 +12091,41 @@ public class NotificationManagerService extends SystemService { } } /** * Returns whether the type adjustment is allowed for this particular package. * If no package-specific restrictions have been set, defaults to the same value as * isAdjustmentKeyTypeAllowed(type). */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected boolean isTypeAdjustmentAllowedForPackage(String pkg, @Adjustment.Types int type) { protected @NonNull boolean isTypeAdjustmentAllowedForPackage(String pkg) { synchronized (mLock) { if (notificationClassificationUi()) { if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg); if (enabled != null) { return enabled.contains(type); } } // If mClassificationTypePackagesEnabledTypes does not contain the pkg, or // the stored set is null, return the default. return isAdjustmentKeyTypeAllowed(type); } } return false; } @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected @NonNull Set<String> getPackagesWithKeyTypeAdjustmentSettings() { if (notificationClassificationUi()) { Set<String> packagesWithModifications = new ArraySet<String>(); synchronized (mLock) { for (String pkg : mClassificationTypePackagesEnabledTypes.keySet()) { if (mClassificationTypePackagesEnabledTypes.get(pkg) != null) { packagesWithModifications.add(pkg); } } return !mClassificationTypeDeniedPackages.contains(pkg); } return packagesWithModifications; } return new ArraySet<String>(); return true; } @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { protected @NonNull String[] getTypeAdjustmentDeniedPackages() { synchronized (mLock) { if (notificationClassificationUi()) { if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg); if (enabled != null) { // Convert Set to int[] for return. int[] returnEnabled = new int[enabled.size()]; int i = 0; for (int val: enabled) { returnEnabled[i] = val; i++; } return returnEnabled; } return mClassificationTypeDeniedPackages.toArray(new String[0]); } // If package is not in the map, or the value is null, return the default. return getAllowedAdjustmentKeyTypes(); } } return new int[]{}; return new String[]{}; } /** * Set whether a particular package can have its notification channels adjusted to have a * different type by NotificationAssistants. * Note: once this method is called to enable or disable a specific type for a package, * the global default is set as the starting point, and the type is enabled/disabled from * there. Future changes to the global default will not apply automatically to this package. */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, @Adjustment.Types int type, boolean enabled) { public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) { if (!notificationClassificationUi()) { return; } synchronized (mLock) { Set<Integer> enabledTypes = null; if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { enabledTypes = mClassificationTypePackagesEnabledTypes.get(pkg); } if (enabledTypes == null) { // Use global default to start. enabledTypes = new ArraySet<Integer>(); // Convert from int[] to Set<Integer> for (int value : getAllowedAdjustmentKeyTypes()) { enabledTypes.add(value); } } if (enabled) { enabledTypes.add(type); mClassificationTypeDeniedPackages.remove(pkg); } else { enabledTypes.remove(type); mClassificationTypeDeniedPackages.add(pkg); } mClassificationTypePackagesEnabledTypes.put(pkg, enabledTypes); } } Loading Loading @@ -12684,25 +12592,16 @@ public class NotificationManagerService extends SystemService { TextUtils.join(",", mAllowedAdjustmentKeyTypes)); out.endTag(null, ATT_ENABLED_TYPES); if (notificationClassificationUi()) { out.startTag(null, TAG_TYPES_ENABLED_FOR_APPS); for (String pkg: mClassificationTypePackagesEnabledTypes.keySet()) { Set<Integer> allowedTypes = mClassificationTypePackagesEnabledTypes.get(pkg); if (allowedTypes != null) { out.startTag(null, ATT_APP_ENABLED_TYPES); out.attribute(null, ATT_PACKAGE, pkg); out.attribute(null, ATT_TYPES, TextUtils.join(",", allowedTypes)); out.endTag(null, ATT_APP_ENABLED_TYPES); } } out.endTag(null, TAG_TYPES_ENABLED_FOR_APPS); out.startTag(null, ATT_TYPES_DENIED_APPS); out.attribute(null, ATT_TYPES, TextUtils.join(",", mClassificationTypeDeniedPackages)); out.endTag(null, ATT_TYPES_DENIED_APPS); } } } @Override protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException, XmlPullParserException { protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException { if (!notificationClassification()) { return; } Loading @@ -12729,25 +12628,12 @@ public class NotificationManagerService extends SystemService { } } } } else if (TAG_TYPES_ENABLED_FOR_APPS.equals(tag)) { final int appsOuterDepth = parser.getDepth(); } else if (notificationClassificationUi() && ATT_TYPES_DENIED_APPS.equals(tag)) { final String apps = XmlUtils.readStringAttribute(parser, ATT_TYPES); synchronized (mLock) { mClassificationTypePackagesEnabledTypes.clear(); while (XmlUtils.nextElementWithin(parser, appsOuterDepth)) { if (!ATT_APP_ENABLED_TYPES.equals(parser.getName())) { continue; } final String app = XmlUtils.readStringAttribute(parser, ATT_PACKAGE); Set<Integer> allowedTypes = new ArraySet<>(); final String typesString = XmlUtils.readStringAttribute(parser, ATT_TYPES); if (!TextUtils.isEmpty(typesString)) { allowedTypes = Arrays.stream(typesString.split(",")) .map(Integer::valueOf) .collect(Collectors.toSet()); } // Empty type list is allowed, because empty type list signifies the user // has manually cleared the package of allowed types. mClassificationTypePackagesEnabledTypes.put(app, allowedTypes); mClassificationTypeDeniedPackages.clear(); if (!TextUtils.isEmpty(apps)) { mClassificationTypeDeniedPackages.addAll(Arrays.asList(apps.split(","))); } } } services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +59 −147 File changed.Preview size limit exceeded, changes collapsed. Show changes services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +12 −17 Original line number Diff line number Diff line Loading @@ -369,9 +369,6 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; Loading @@ -387,6 +384,9 @@ import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @SmallTest @RunWith(ParameterizedAndroidJunit4.class) @RunWithLooper Loading Loading @@ -7662,7 +7662,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Set up notifications that will be adjusted final NotificationRecord r1 = spy(generateNotificationRecord( Loading Loading @@ -17512,7 +17512,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Loading Loading @@ -17556,11 +17556,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_NEWS))) .thenReturn(true); // Blocking adjustments for a different type does nothing when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION))) .thenReturn(false); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Loading @@ -17575,9 +17571,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID); // When we block adjustments for this package/type when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION))) .thenReturn(false); // When we block adjustments for this package when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(false); signals.putInt(KEY_TYPE, TYPE_PROMOTION); mBinderService.applyAdjustmentFromAssistant(null, adjustment); Loading Loading @@ -17907,7 +17902,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post a single notification final boolean hasOriginalSummary = false; Loading Loading @@ -17947,7 +17942,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; Loading Loading @@ -17996,7 +17991,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; Loading Loading @@ -18047,7 +18042,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post a single notification final boolean hasOriginalSummary = false; Loading
core/java/android/app/INotificationManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -271,6 +271,6 @@ interface INotificationManager int[] getAllowedAdjustmentKeyTypes(); void setAssistantAdjustmentKeyTypeState(int type, boolean enabled); int[] getAllowedAdjustmentKeyTypesForPackage(String pkg); void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, boolean enabled); String[] getTypeAdjustmentDeniedPackages(); void setTypeAdjustmentForPackageState(String pkg, boolean enabled); }
core/java/android/app/NotificationManager.java +2 −4 Original line number Diff line number Diff line Loading @@ -2163,12 +2163,10 @@ public class NotificationManager { * @hide */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void setAssistantAdjustmentKeyTypeStateForPackage(@NonNull String pkg, @Adjustment.Types int type, boolean enabled) { public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) { INotificationManager service = service(); try { service.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); service.setTypeAdjustmentForPackageState(pkg, enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +28 −142 Original line number Diff line number Diff line Loading @@ -3037,10 +3037,9 @@ public class NotificationManagerService extends SystemService { switch(atomTag) { case PACKAGE_NOTIFICATION_PREFERENCES: if (notificationClassificationUi()) { Set<String> pkgs = mAssistants.getPackagesWithKeyTypeAdjustmentSettings(); mPreferencesHelper.pullPackagePreferencesStats(data, getAllUsersNotificationPermissions(), getPackageSpecificAdjustmentKeyTypes(pkgs)); new ArrayMap<>()); } else { mPreferencesHelper.pullPackagePreferencesStats(data, getAllUsersNotificationPermissions()); Loading Loading @@ -4401,16 +4400,16 @@ public class NotificationManagerService extends SystemService { @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { public @NonNull String[] getTypeAdjustmentDeniedPackages() { checkCallerIsSystemOrSystemUiOrShell(); return mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg); return mAssistants.getTypeAdjustmentDeniedPackages(); } @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, boolean enabled) { public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); mAssistants.setTypeAdjustmentForPackageState(pkg, enabled); handleSavePolicyFile(); } Loading Loading @@ -7219,7 +7218,7 @@ public class NotificationManagerService extends SystemService { toRemove.add(potentialKey); } else if (notificationClassificationUi() && !mAssistants.isTypeAdjustmentAllowedForPackage( r.getSbn().getPackageName(), adjustments.getInt(KEY_TYPE))) { r.getSbn().getPackageName())) { toRemove.add(potentialKey); } } Loading Loading @@ -7556,24 +7555,6 @@ public class NotificationManagerService extends SystemService { return allPermissions; } @VisibleForTesting @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected @NonNull Map<String, Set<Integer>> getPackageSpecificAdjustmentKeyTypes( Set<String> pkgs) { ArrayMap<String, Set<Integer>> pkgToAllowedTypes = new ArrayMap<>(); for (String pkg : pkgs) { int[] allowedTypesArray = mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg); if (allowedTypesArray != null) { Set<Integer> allowedTypes = new ArraySet<Integer>(); for (int i : allowedTypesArray) { allowedTypes.add(i); } pkgToAllowedTypes.append(pkg, allowedTypes); } } return pkgToAllowedTypes; } private void dumpJson(PrintWriter pw, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONObject dump = new JSONObject(); Loading Loading @@ -11889,11 +11870,7 @@ public class NotificationManagerService extends SystemService { private static final String ATT_DENIED = "denied_adjustments"; private static final String ATT_ENABLED_TYPES = "enabled_key_types"; private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments"; // Encapsulates a list of packages and the bundle types enabled for each package. private static final String TAG_TYPES_ENABLED_FOR_APPS = "types_enabled_for_apps"; // Encapsulates the bundle types enabled for a package. private static final String ATT_APP_ENABLED_TYPES = "app_enabled_types"; private static final String ATT_PACKAGE = "package"; private static final String ATT_TYPES_DENIED_APPS = "types_denied_apps"; private final Object mLock = new Object(); Loading @@ -11909,14 +11886,8 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mLock") private Map<Integer, HashSet<String>> mNasUnsupported = new ArrayMap<>(); // Types of classifications (aka bundles) enabled/allowed for this package. // If the set is NULL (or package is not in the list), default classification allow list // (the global one) should be used. // If the set is empty, that indicates the package explicitly has all classifications // disallowed. @GuardedBy("mLock") private Map<String, Set<Integer>> mClassificationTypePackagesEnabledTypes = new ArrayMap<>(); private Set<String> mClassificationTypeDeniedPackages = new ArraySet<>(); protected ComponentName mDefaultFromConfig = null; Loading Loading @@ -12120,104 +12091,41 @@ public class NotificationManagerService extends SystemService { } } /** * Returns whether the type adjustment is allowed for this particular package. * If no package-specific restrictions have been set, defaults to the same value as * isAdjustmentKeyTypeAllowed(type). */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected boolean isTypeAdjustmentAllowedForPackage(String pkg, @Adjustment.Types int type) { protected @NonNull boolean isTypeAdjustmentAllowedForPackage(String pkg) { synchronized (mLock) { if (notificationClassificationUi()) { if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg); if (enabled != null) { return enabled.contains(type); } } // If mClassificationTypePackagesEnabledTypes does not contain the pkg, or // the stored set is null, return the default. return isAdjustmentKeyTypeAllowed(type); } } return false; } @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected @NonNull Set<String> getPackagesWithKeyTypeAdjustmentSettings() { if (notificationClassificationUi()) { Set<String> packagesWithModifications = new ArraySet<String>(); synchronized (mLock) { for (String pkg : mClassificationTypePackagesEnabledTypes.keySet()) { if (mClassificationTypePackagesEnabledTypes.get(pkg) != null) { packagesWithModifications.add(pkg); } } return !mClassificationTypeDeniedPackages.contains(pkg); } return packagesWithModifications; } return new ArraySet<String>(); return true; } @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) protected @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { protected @NonNull String[] getTypeAdjustmentDeniedPackages() { synchronized (mLock) { if (notificationClassificationUi()) { if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg); if (enabled != null) { // Convert Set to int[] for return. int[] returnEnabled = new int[enabled.size()]; int i = 0; for (int val: enabled) { returnEnabled[i] = val; i++; } return returnEnabled; } return mClassificationTypeDeniedPackages.toArray(new String[0]); } // If package is not in the map, or the value is null, return the default. return getAllowedAdjustmentKeyTypes(); } } return new int[]{}; return new String[]{}; } /** * Set whether a particular package can have its notification channels adjusted to have a * different type by NotificationAssistants. * Note: once this method is called to enable or disable a specific type for a package, * the global default is set as the starting point, and the type is enabled/disabled from * there. Future changes to the global default will not apply automatically to this package. */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, @Adjustment.Types int type, boolean enabled) { public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) { if (!notificationClassificationUi()) { return; } synchronized (mLock) { Set<Integer> enabledTypes = null; if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { enabledTypes = mClassificationTypePackagesEnabledTypes.get(pkg); } if (enabledTypes == null) { // Use global default to start. enabledTypes = new ArraySet<Integer>(); // Convert from int[] to Set<Integer> for (int value : getAllowedAdjustmentKeyTypes()) { enabledTypes.add(value); } } if (enabled) { enabledTypes.add(type); mClassificationTypeDeniedPackages.remove(pkg); } else { enabledTypes.remove(type); mClassificationTypeDeniedPackages.add(pkg); } mClassificationTypePackagesEnabledTypes.put(pkg, enabledTypes); } } Loading Loading @@ -12684,25 +12592,16 @@ public class NotificationManagerService extends SystemService { TextUtils.join(",", mAllowedAdjustmentKeyTypes)); out.endTag(null, ATT_ENABLED_TYPES); if (notificationClassificationUi()) { out.startTag(null, TAG_TYPES_ENABLED_FOR_APPS); for (String pkg: mClassificationTypePackagesEnabledTypes.keySet()) { Set<Integer> allowedTypes = mClassificationTypePackagesEnabledTypes.get(pkg); if (allowedTypes != null) { out.startTag(null, ATT_APP_ENABLED_TYPES); out.attribute(null, ATT_PACKAGE, pkg); out.attribute(null, ATT_TYPES, TextUtils.join(",", allowedTypes)); out.endTag(null, ATT_APP_ENABLED_TYPES); } } out.endTag(null, TAG_TYPES_ENABLED_FOR_APPS); out.startTag(null, ATT_TYPES_DENIED_APPS); out.attribute(null, ATT_TYPES, TextUtils.join(",", mClassificationTypeDeniedPackages)); out.endTag(null, ATT_TYPES_DENIED_APPS); } } } @Override protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException, XmlPullParserException { protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException { if (!notificationClassification()) { return; } Loading @@ -12729,25 +12628,12 @@ public class NotificationManagerService extends SystemService { } } } } else if (TAG_TYPES_ENABLED_FOR_APPS.equals(tag)) { final int appsOuterDepth = parser.getDepth(); } else if (notificationClassificationUi() && ATT_TYPES_DENIED_APPS.equals(tag)) { final String apps = XmlUtils.readStringAttribute(parser, ATT_TYPES); synchronized (mLock) { mClassificationTypePackagesEnabledTypes.clear(); while (XmlUtils.nextElementWithin(parser, appsOuterDepth)) { if (!ATT_APP_ENABLED_TYPES.equals(parser.getName())) { continue; } final String app = XmlUtils.readStringAttribute(parser, ATT_PACKAGE); Set<Integer> allowedTypes = new ArraySet<>(); final String typesString = XmlUtils.readStringAttribute(parser, ATT_TYPES); if (!TextUtils.isEmpty(typesString)) { allowedTypes = Arrays.stream(typesString.split(",")) .map(Integer::valueOf) .collect(Collectors.toSet()); } // Empty type list is allowed, because empty type list signifies the user // has manually cleared the package of allowed types. mClassificationTypePackagesEnabledTypes.put(app, allowedTypes); mClassificationTypeDeniedPackages.clear(); if (!TextUtils.isEmpty(apps)) { mClassificationTypeDeniedPackages.addAll(Arrays.asList(apps.split(","))); } } }
services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +59 −147 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +12 −17 Original line number Diff line number Diff line Loading @@ -369,9 +369,6 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; Loading @@ -387,6 +384,9 @@ import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @SmallTest @RunWith(ParameterizedAndroidJunit4.class) @RunWithLooper Loading Loading @@ -7662,7 +7662,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Set up notifications that will be adjusted final NotificationRecord r1 = spy(generateNotificationRecord( Loading Loading @@ -17512,7 +17512,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Loading Loading @@ -17556,11 +17556,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_NEWS))) .thenReturn(true); // Blocking adjustments for a different type does nothing when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION))) .thenReturn(false); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Loading @@ -17575,9 +17571,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID); // When we block adjustments for this package/type when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION))) .thenReturn(false); // When we block adjustments for this package when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(false); signals.putInt(KEY_TYPE, TYPE_PROMOTION); mBinderService.applyAdjustmentFromAssistant(null, adjustment); Loading Loading @@ -17907,7 +17902,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post a single notification final boolean hasOriginalSummary = false; Loading Loading @@ -17947,7 +17942,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; Loading Loading @@ -17996,7 +17991,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; Loading Loading @@ -18047,7 +18042,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post a single notification final boolean hasOriginalSummary = false;