diff options
6 files changed, 51 insertions, 24 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 237780ffbea4..8a54b5d4ec4f 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -258,7 +258,7 @@ interface INotificationManager @EnforcePermission(allOf={"INTERACT_ACROSS_USERS", "ACCESS_NOTIFICATIONS"}) void unregisterCallNotificationEventListener(String packageName, in UserHandle userHandle, in ICallNotificationEventCallback listener); - void setCanBePromoted(String pkg, int uid, boolean promote); + void setCanBePromoted(String pkg, int uid, boolean promote, boolean fromUser); boolean appCanBePromoted(String pkg, int uid); boolean canBePromoted(String pkg); } diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 06f21b882434..c7b84ae6283b 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -976,7 +976,7 @@ public class NotificationManager { public void setCanPostPromotedNotifications(@NonNull String pkg, int uid, boolean allowed) { INotificationManager service = getService(); try { - service.setCanBePromoted(pkg, uid, allowed); + service.setCanBePromoted(pkg, uid, allowed, true); } 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 bcc201989bc6..c3a714b0eef0 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4136,14 +4136,18 @@ public class NotificationManagerService extends SystemService { } + /** + * Any changes from SystemUI or Settings should be fromUser == true. Any changes the + * allowlist should be fromUser == false. + */ @Override @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING) - public void setCanBePromoted(String pkg, int uid, boolean promote) { + public void setCanBePromoted(String pkg, int uid, boolean promote, boolean fromUser) { checkCallerIsSystemOrSystemUiOrShell(); if (!android.app.Flags.apiRichOngoing()) { return; } - boolean changed = mPreferencesHelper.setCanBePromoted(pkg, uid, promote); + boolean changed = mPreferencesHelper.setCanBePromoted(pkg, uid, promote, fromUser); if (changed) { // check for pending/posted notifs from this app and update the flag synchronized (mNotificationLock) { diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index fdb9f672e856..85c395781d0a 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -40,6 +40,7 @@ import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_P import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED; +import static com.android.server.notification.PreferencesHelper.LockableAppFields.USER_LOCKED_PROMOTABLE; import android.annotation.FlaggedApi; import android.annotation.IntDef; @@ -192,10 +193,13 @@ public class PreferencesHelper implements RankingConfig { /** * All user-lockable fields for a given application. */ - @IntDef({LockableAppFields.USER_LOCKED_IMPORTANCE}) + @IntDef({LockableAppFields.USER_LOCKED_IMPORTANCE, + LockableAppFields.USER_LOCKED_BUBBLE, + LockableAppFields.USER_LOCKED_PROMOTABLE}) public @interface LockableAppFields { int USER_LOCKED_IMPORTANCE = 0x00000001; int USER_LOCKED_BUBBLE = 0x00000002; + int USER_LOCKED_PROMOTABLE = 0x00000004; } private final Object mLock = new Object(); @@ -858,13 +862,19 @@ public class PreferencesHelper implements RankingConfig { } @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING) - public boolean setCanBePromoted(String packageName, int uid, boolean promote) { + public boolean setCanBePromoted(String packageName, int uid, boolean promote, + boolean fromUser) { boolean changed = false; synchronized (mLock) { PackagePreferences pkgPrefs = getOrCreatePackagePreferencesLocked(packageName, uid); - if (pkgPrefs.canHavePromotedNotifs != promote) { - pkgPrefs.canHavePromotedNotifs = promote; - changed = true; + if (fromUser || ((pkgPrefs.lockedAppFields & USER_LOCKED_PROMOTABLE) == 0)) { + if (pkgPrefs.canHavePromotedNotifs != promote) { + pkgPrefs.canHavePromotedNotifs = promote; + if (fromUser) { + pkgPrefs.lockedAppFields |= USER_LOCKED_PROMOTABLE; + } + changed = true; + } } } // no need to send a ranking update because we need to update the flag value on all pending 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 d69d678746a6..6c9015d72d5a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -16611,7 +16611,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addNotification(r); mService.addEnqueuedNotification(r1); - mBinderService.setCanBePromoted(mPkg, mUid, true); + mBinderService.setCanBePromoted(mPkg, mUid, true, true); waitForIdle(); @@ -16651,9 +16651,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addNotification(r); - mBinderService.setCanBePromoted(mPkg, mUid, true); + mBinderService.setCanBePromoted(mPkg, mUid, true, true); waitForIdle(); - mBinderService.setCanBePromoted(mPkg, mUid, true); + mBinderService.setCanBePromoted(mPkg, mUid, true, true); waitForIdle(); ArgumentCaptor<NotificationRecord> captor = @@ -16668,7 +16668,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mContext.getTestablePermissions().setPermission( android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED); // start from true state - mBinderService.setCanBePromoted(mPkg, mUid, true); + mBinderService.setCanBePromoted(mPkg, mUid, true, true); // qualifying posted notification Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId()) @@ -16709,7 +16709,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addNotification(r); mService.addEnqueuedNotification(r1); - mBinderService.setCanBePromoted(mPkg, mUid, false); + mBinderService.setCanBePromoted(mPkg, mUid, false, true); waitForIdle(); @@ -16733,7 +16733,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mContext.getTestablePermissions().setPermission( android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED); // start from true state - mBinderService.setCanBePromoted(mPkg, mUid, true); + mBinderService.setCanBePromoted(mPkg, mUid, true, true); // qualifying posted notification Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId()) @@ -16751,9 +16751,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addNotification(r); - mBinderService.setCanBePromoted(mPkg, mUid, false); + mBinderService.setCanBePromoted(mPkg, mUid, false, true); waitForIdle(); - mBinderService.setCanBePromoted(mPkg, mUid, false); + mBinderService.setCanBePromoted(mPkg, mUid, false, true); waitForIdle(); ArgumentCaptor<NotificationRecord> captor = @@ -16765,7 +16765,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING) public void testPostPromotableNotification() throws Exception { - mBinderService.setCanBePromoted(mPkg, mUid, true); + mBinderService.setCanBePromoted(mPkg, mUid, true, true); assertThat(mBinderService.appCanBePromoted(mPkg, mUid)).isTrue(); mContext.getTestablePermissions().setPermission( android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED); @@ -16823,7 +16823,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING) public void testPostPromotableNotification_unimportantNotification() throws Exception { - mBinderService.setCanBePromoted(mPkg, mUid, true); + mBinderService.setCanBePromoted(mPkg, mUid, true, true); mContext.getTestablePermissions().setPermission( android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED); Notification n = new Notification.Builder(mContext, mMinChannel.getId()) diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 7d63062784f9..a0c0df8853f9 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -62,6 +62,7 @@ import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL; import static com.android.server.notification.Flags.FLAG_PERSIST_INCOMPLETE_RESTORE_DATA; import static com.android.server.notification.NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED_BY_USER; import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE; +import static com.android.server.notification.PreferencesHelper.LockableAppFields.USER_LOCKED_PROMOTABLE; import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT; import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; import static com.android.server.notification.PreferencesHelper.UNKNOWN_UID; @@ -643,7 +644,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true); if (android.app.Flags.uiRichOngoing()) { - mHelper.setCanBePromoted(PKG_N_MR1, UID_N_MR1, true); + mHelper.setCanBePromoted(PKG_N_MR1, UID_N_MR1, true, true); } ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false, @@ -657,6 +658,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertTrue(mXmlHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); if (android.app.Flags.uiRichOngoing()) { assertThat(mXmlHelper.canBePromoted(PKG_N_MR1, UID_N_MR1)).isTrue(); + assertThat(mXmlHelper.getAppLockedFields(PKG_N_MR1, UID_N_MR1) & USER_LOCKED_PROMOTABLE) + .isNotEqualTo(0); } assertEquals(channel1, mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false)); @@ -6311,20 +6314,30 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - @EnableFlags(android.app.Flags.FLAG_UI_RICH_ONGOING) + @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING) public void testNoAppHasPermissionToPromoteByDefault() { mHelper.setShowBadge(PKG_P, UID_P, true); assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isFalse(); } @Test - @EnableFlags(android.app.Flags.FLAG_UI_RICH_ONGOING) + @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING) public void testSetCanBePromoted() { - mHelper.setCanBePromoted(PKG_P, UID_P, true); + mHelper.setCanBePromoted(PKG_P, UID_P, true, true); assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isTrue(); - mHelper.setCanBePromoted(PKG_P, UID_P, false); + mHelper.setCanBePromoted(PKG_P, UID_P, false, true); assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isFalse(); verify(mHandler, never()).requestSort(); } + + @Test + @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING) + public void testSetCanBePromoted_allowlistNotOverrideUser() { + mHelper.setCanBePromoted(PKG_P, UID_P, true, true); + assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isTrue(); + + mHelper.setCanBePromoted(PKG_P, UID_P, false, false); + assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isTrue(); + } } |