summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/INotificationManager.aidl4
-rw-r--r--core/java/android/app/NotificationManager.java6
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java133
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java182
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java27
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";