diff options
5 files changed, 263 insertions, 89 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index a6c1a57a8131..0451ac0d6897 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -270,6 +270,6 @@ interface INotificationManager int[] getAllowedAdjustmentKeyTypes(); void setAssistantAdjustmentKeyTypeState(int type, boolean enabled); - String[] getTypeAdjustmentDeniedPackages(); - void setTypeAdjustmentForPackageState(String pkg, boolean enabled); + int[] getAllowedAdjustmentKeyTypesForPackage(String pkg); + void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, boolean enabled); } diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index ec10913360af..08bd854525ec 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1986,10 +1986,12 @@ public class NotificationManager { * @hide */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) { + public void setAssistantAdjustmentKeyTypeStateForPackage(@NonNull String pkg, + @Adjustment.Types int type, + boolean enabled) { INotificationManager service = service(); try { - service.setTypeAdjustmentForPackageState(pkg, enabled); + service.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 7375a68c547b..eeae6166873a 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4276,16 +4276,16 @@ public class NotificationManagerService extends SystemService { @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public @NonNull String[] getTypeAdjustmentDeniedPackages() { + public @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { checkCallerIsSystemOrSystemUiOrShell(); - return mAssistants.getTypeAdjustmentDeniedPackages(); + return mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg); } - @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) { + public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, + boolean enabled) { checkCallerIsSystemOrSystemUiOrShell(); - mAssistants.setTypeAdjustmentForPackageState(pkg, enabled); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); handleSavePolicyFile(); } @@ -7083,7 +7083,7 @@ public class NotificationManagerService extends SystemService { toRemove.add(potentialKey); } else if (notificationClassificationUi() && !mAssistants.isTypeAdjustmentAllowedForPackage( - r.getSbn().getPackageName())) { + r.getSbn().getPackageName(), adjustments.getInt(KEY_TYPE))) { toRemove.add(potentialKey); } } @@ -11740,7 +11740,11 @@ 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"; - private static final String ATT_TYPES_DENIED_APPS = "types_denied_apps"; + // 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 final Object mLock = new Object(); @@ -11756,8 +11760,14 @@ 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 Set<String> mClassificationTypeDeniedPackages = new ArraySet<>(); + private Map<String, Set<Integer>> mClassificationTypePackagesEnabledTypes = + new ArrayMap<>(); protected ComponentName mDefaultFromConfig = null; @@ -11958,41 +11968,88 @@ 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 @NonNull boolean isTypeAdjustmentAllowedForPackage(String pkg) { + protected boolean isTypeAdjustmentAllowedForPackage(String pkg, + @Adjustment.Types int type) { synchronized (mLock) { if (notificationClassificationUi()) { - return !mClassificationTypeDeniedPackages.contains(pkg); + 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 true; + return false; } @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - protected @NonNull String[] getTypeAdjustmentDeniedPackages() { + protected @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { synchronized (mLock) { if (notificationClassificationUi()) { - return mClassificationTypeDeniedPackages.toArray(new String[0]); + 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; + } + } + // If package is not in the map, or the value is null, return the default. + return getAllowedAdjustmentKeyTypes(); } } - return new String[]{}; + return new int[]{}; } /** * 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 setTypeAdjustmentForPackageState(String pkg, boolean enabled) { + public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, + @Adjustment.Types int type, + 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) { - mClassificationTypeDeniedPackages.remove(pkg); + enabledTypes.add(type); } else { - mClassificationTypeDeniedPackages.add(pkg); + enabledTypes.remove(type); } + mClassificationTypePackagesEnabledTypes.put(pkg, enabledTypes); } } @@ -12459,16 +12516,25 @@ public class NotificationManagerService extends SystemService { TextUtils.join(",", mAllowedAdjustmentKeyTypes)); out.endTag(null, ATT_ENABLED_TYPES); if (notificationClassificationUi()) { - out.startTag(null, ATT_TYPES_DENIED_APPS); - out.attribute(null, ATT_TYPES, - TextUtils.join(",", mClassificationTypeDeniedPackages)); - out.endTag(null, ATT_TYPES_DENIED_APPS); + 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); } } } @Override - protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException { + protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException, + XmlPullParserException { if (!notificationClassification()) { return; } @@ -12495,12 +12561,25 @@ public class NotificationManagerService extends SystemService { } } } - } else if (notificationClassificationUi() && ATT_TYPES_DENIED_APPS.equals(tag)) { - final String apps = XmlUtils.readStringAttribute(parser, ATT_TYPES); + } else if (TAG_TYPES_ENABLED_FOR_APPS.equals(tag)) { + final int appsOuterDepth = parser.getDepth(); synchronized (mLock) { - mClassificationTypeDeniedPackages.clear(); - if (!TextUtils.isEmpty(apps)) { - mClassificationTypeDeniedPackages.addAll(Arrays.asList(apps.split(","))); + 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); } } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java index d1dc8d6e81c8..4f5cdb73edd2 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java @@ -19,9 +19,13 @@ import static android.os.UserHandle.USER_ALL; import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; import static android.service.notification.Adjustment.TYPE_NEWS; +import static android.service.notification.Adjustment.TYPE_OTHER; import static android.service.notification.Adjustment.TYPE_PROMOTION; +import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA; +import static android.service.notification.Flags.notificationClassification; import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENTS; +import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES; import static com.google.common.truth.Truth.assertThat; @@ -144,6 +148,17 @@ public class NotificationAssistantsTest extends UiServiceTestCase { mAssistants.readXml(parser, mNm::canUseManagedServices, false, USER_ALL); } + private void setDefaultAllowedAdjustmentKeyTypes(NotificationAssistants assistants) { + assistants.setAssistantAdjustmentKeyTypeState(TYPE_OTHER, false); + assistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false); + assistants.setAssistantAdjustmentKeyTypeState(TYPE_SOCIAL_MEDIA, false); + assistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, false); + assistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, false); + + for (int type : DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES) { + assistants.setAssistantAdjustmentKeyTypeState(type, true); + } + } @Before public void setUp() throws Exception { @@ -154,6 +169,9 @@ public class NotificationAssistantsTest extends UiServiceTestCase { com.android.internal.R.string.config_defaultAssistantAccessComponent, mCn.flattenToString()); mAssistants = spy(mNm.new NotificationAssistants(mContext, mLock, mUserProfiles, miPm)); + if (notificationClassification()) { + setDefaultAllowedAdjustmentKeyTypes(mAssistants); + } when(mNm.getBinderService()).thenReturn(mINm); mContext.ensureTestableResources(); @@ -695,7 +713,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true); assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList() - .containsExactlyElementsIn(List.of(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION)); + .containsExactly(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION); } @Test @@ -716,7 +734,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { writeXmlAndReload(USER_ALL); assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList() - .containsExactlyElementsIn(List.of(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION)); + .containsExactly(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION); } @Test @@ -732,76 +750,146 @@ public class NotificationAssistantsTest extends UiServiceTestCase { @Test @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) + public void testSetAssistantAdjustmentKeyTypeStateForPackage_usesGlobalDefault() { + String pkg = "my.package"; + setDefaultAllowedAdjustmentKeyTypes(mAssistants); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isFalse(); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() + .containsExactlyElementsIn(DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES); + } + + @Test + @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsAndDenies() { - // Given that a package is allowed to have its type adjusted, - String allowedPackage = "allowed.package"; - assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); - mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true); + setDefaultAllowedAdjustmentKeyTypes(mAssistants); + // Given that a package is set to have a type adjustment allowed, + String pkg = "my.package"; + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, true); - assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); - assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage)); + // The newly set state is the combination of the global default and the newly set type. + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); // Set type adjustment disallowed for this package - mAssistants.setTypeAdjustmentForPackageState(allowedPackage, false); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, false); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, false); // Then the package is marked as denied - assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() - .containsExactly(allowedPackage); - assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage)); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).isEmpty(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isFalse(); // Set type adjustment allowed again - mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, true); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, true); // Then the package is marked as allowed again - assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); - assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage)); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue(); + + // Set type adjustment promotions false, + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, false); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() + .containsExactly(TYPE_NEWS); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isFalse(); } @Test @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void testSetAssistantAdjustmentKeyTypeStateForPackage_deniesMultiple() { - // Given packages not allowed to have their type adjusted, - String deniedPkg1 = "denied.Pkg1"; - String deniedPkg2 = "denied.Pkg2"; - String deniedPkg3 = "denied.Pkg3"; - // Set type adjustment disallowed for these packages - mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false); - mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, false); - mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false); - - // Then the packages are marked as denied - assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() - .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg2, deniedPkg3)); - assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1)); - assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2)); - assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3)); - - // And when we re-allow one of them, - mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, true); - - // Then the rest of the original packages are still marked as denied. - assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() - .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3)); - assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1)); - assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2)); - assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3)); + public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsMultiplePkgs() { + setDefaultAllowedAdjustmentKeyTypes(mAssistants); + // Given packages allowed to have their type adjusted to TYPE_NEWS, + String allowedPkg1 = "allowed.Pkg1"; + String allowedPkg2 = "allowed.Pkg2"; + String allowedPkg3 = "allowed.Pkg3"; + // Set type adjustment allowed for these packages + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg1, TYPE_NEWS, true); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, true); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_NEWS, true); + + // The newly set state is the combination of the global default and the newly set type. + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg1)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg1, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg2, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg3, TYPE_NEWS)).isTrue(); + + // And when we deny some of them, + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, false); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_PROMOTION, + false); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_PROMOTION, + false); + + // Then the rest of the original packages are still marked as allowed. + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg1)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).isEmpty(); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList() + .containsExactly(TYPE_NEWS); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg1, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg2, TYPE_NEWS)).isFalse(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg3, TYPE_NEWS)).isTrue(); } @Test @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void testSetAssistantAdjustmentKeyTypeStateForPackage_readWriteXml() throws Exception { + setDefaultAllowedAdjustmentKeyTypes(mAssistants); mAssistants.loadDefaultsFromConfig(true); String deniedPkg1 = "denied.Pkg1"; String allowedPkg2 = "allowed.Pkg2"; - String deniedPkg3 = "denied.Pkg3"; + String allowedPkg3 = "allowed.Pkg3"; // Set type adjustment disallowed or allowed for these packages - mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false); - mAssistants.setTypeAdjustmentForPackageState(allowedPkg2, true); - mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(deniedPkg1, TYPE_PROMOTION, false); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, true); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_NEWS, true); + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_SOCIAL_MEDIA, + true); writeXmlAndReload(USER_ALL); - assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() - .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3)); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(deniedPkg1)).isEmpty(); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList() + .containsExactly(TYPE_NEWS, TYPE_SOCIAL_MEDIA, TYPE_PROMOTION); + } + + @Test + @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) + public void testSetAssistantAdjustmentKeyTypeStateForPackage_noGlobalImpact() throws Exception { + setDefaultAllowedAdjustmentKeyTypes(mAssistants); + // When the global state is changed, + mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, true); + + // The package state reflects the global state. + String pkg = "my.package"; + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION); + + // Once the package specific state is modified, + mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_SOCIAL_MEDIA, true); + + // The package specific state combines the global state with those modifications + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_SOCIAL_MEDIA)).isTrue(); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION, TYPE_SOCIAL_MEDIA); + + // And further changes to the global state are ignored. + mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, false); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() + .containsExactly(TYPE_NEWS, TYPE_PROMOTION, TYPE_SOCIAL_MEDIA); } }
\ No newline at end of file diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 601023f89656..bcda2c0662ca 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -365,6 +365,9 @@ 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; @@ -380,9 +383,6 @@ 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 @@ -7631,7 +7631,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())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); // Set up notifications that will be adjusted final NotificationRecord r1 = spy(generateNotificationRecord( @@ -17305,7 +17305,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); @@ -17349,7 +17349,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).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); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); @@ -17364,8 +17368,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID); - // When we block adjustments for this package - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(false); + // When we block adjustments for this package/type + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION))) + .thenReturn(false); signals.putInt(KEY_TYPE, TYPE_PROMOTION); mBinderService.applyAdjustmentFromAssistant(null, adjustment); @@ -17695,7 +17700,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())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); // Post a single notification final boolean hasOriginalSummary = false; @@ -17735,7 +17740,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())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; @@ -17784,7 +17789,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())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; |