Loading core/java/android/app/AppOpsManager.java +14 −19 Original line number Diff line number Diff line Loading @@ -1505,15 +1505,6 @@ public class AppOpsManager { */ public static final int OP_USE_FULL_SCREEN_INTENT = AppOpEnums.APP_OP_USE_FULL_SCREEN_INTENT; /** * Post promoted notifications in the notification shade and status bar chips. * * @hide */ public static final int OP_POST_PROMOTED_NOTIFICATIONS = AppOpEnums.APP_OP_POST_PROMOTED_NOTIFICATIONS; /** * Hides camera indicator for sandboxed detection apps that directly access the service. * Loading Loading @@ -1715,6 +1706,14 @@ public class AppOpsManager { public static final int OP_SCENE_UNDERSTANDING_FINE = AppOpEnums.APP_OP_SCENE_UNDERSTANDING_FINE; /** * Post promoted notifications in the notification shade and status bar chips. * * @hide */ public static final int OP_POST_PROMOTED_NOTIFICATIONS = AppOpEnums.APP_OP_POST_PROMOTED_NOTIFICATIONS; /** @hide */ public static final int OP_SYSTEM_APPLICATION_OVERLAY = AppOpEnums.APP_OP_SYSTEM_APPLICATION_OVERLAY; Loading Loading @@ -2532,14 +2531,6 @@ public class AppOpsManager { */ public static final String OPSTR_USE_FULL_SCREEN_INTENT = "android:use_full_screen_intent"; /** * Permission to post promoted notifications. * * @hide */ public static final String OPSTR_POST_PROMOTED_NOTIFICATIONS = "android:post_promoted_notifications"; /** * Allows the assistant app to be voice-triggered by detected hotwords from a trusted detection * service. Loading Loading @@ -2696,6 +2687,10 @@ public class AppOpsManager { public static final String OPSTR_SCENE_UNDERSTANDING_FINE = "android:scene_understanding_fine"; /** @hide Permission to post promoted notifications. */ public static final String OPSTR_POST_PROMOTED_NOTIFICATIONS = "android:post_promoted_notifications"; /** @hide Required to draw system application overlays. */ public static final String OPSTR_SYSTEM_APPLICATION_OVERLAY = "android:system_application_overlay"; Loading Loading @@ -2825,7 +2820,7 @@ public class AppOpsManager { OP_MEDIA_ROUTING_CONTROL, OP_READ_SYSTEM_GRAMMATICAL_GENDER, OP_WRITE_SYSTEM_PREFERENCES, android.app.Flags.apiRichOngoingPermission() android.app.Flags.uiRichOngoing() ? OP_POST_PROMOTED_NOTIFICATIONS : OP_NONE, com.android.media.projection.flags.Flags.recordingOverlay() ? OP_SYSTEM_APPLICATION_OVERLAY : OP_NONE, Loading Loading @@ -3362,7 +3357,7 @@ public class AppOpsManager { .build(), new AppOpInfo.Builder(OP_POST_PROMOTED_NOTIFICATIONS, OPSTR_POST_PROMOTED_NOTIFICATIONS, "POST_PROMOTED_NOTIFICATIONS") .setPermission(android.app.Flags.apiRichOngoingPermission() .setPermission(android.app.Flags.uiRichOngoing() ? Manifest.permission.POST_PROMOTED_NOTIFICATIONS : null) .build(), new AppOpInfo.Builder(OP_SYSTEM_APPLICATION_OVERLAY, OPSTR_SYSTEM_APPLICATION_OVERLAY, Loading core/res/AndroidManifest.xml +3 −1 Original line number Diff line number Diff line Loading @@ -8232,6 +8232,8 @@ android:protectionLevel="normal|appop" /> <!-- Required for apps to post promoted notifications. <p>This is required in addition to (not instead of) {@link android.app.Manifest.permission#POST_NOTIFICATIONS}. <p>Protection level: normal|appops @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING_PERMISSION) --> Loading @@ -8239,7 +8241,7 @@ android:label="@string/permlab_postPromotedNotifications" android:description="@string/permdesc_postPromotedNotifications" android:protectionLevel="normal|appop" android:featureFlag="android.app.api_rich_ongoing_permission"/> android:featureFlag="android.app.ui_rich_ongoing"/> <!-- @SystemApi Required for the privileged assistant apps targeting {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} Loading services/core/java/com/android/server/notification/NotificationManagerService.java +4 −5 Original line number Diff line number Diff line Loading @@ -4741,7 +4741,7 @@ public class NotificationManagerService extends SystemService { final boolean changed; if (android.app.Flags.apiRichOngoingPermission()) { if (android.app.Flags.uiRichOngoing()) { // Use permission backend for allowing promotion per app if (!fromUser) { Loading @@ -4750,8 +4750,7 @@ public class NotificationManagerService extends SystemService { return; } boolean wasPromoted = checkPostPromotedNotificationPermission( pkg, uid); boolean wasPromoted = checkPostPromotedNotificationPermission(pkg, uid); int mode = promote ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED; mAppOps.setUidMode(OP_POST_PROMOTED_NOTIFICATIONS, uid, mode); Loading Loading @@ -9017,7 +9016,7 @@ public class NotificationManagerService extends SystemService { // Check permission last - after we make sure this is actually an attempted usage // of promotion - since AppOps tracks usage attempts. boolean canPostPromoted; if (android.app.Flags.apiRichOngoingPermission()) { if (android.app.Flags.uiRichOngoing()) { final AttributionSource attributionSource = new AttributionSource.Builder(notificationUid) .setPackageName(pkg).build(); Loading Loading @@ -9099,7 +9098,7 @@ public class NotificationManagerService extends SystemService { private boolean checkPostPromotedNotificationPermission( String pkg, int uid) { if (!android.app.Flags.apiRichOngoingPermission()) { if (!android.app.Flags.uiRichOngoing()) { return mPreferencesHelper.canBePromoted(pkg, uid); } else { final AttributionSource attributionSource = Loading services/core/java/com/android/server/notification/PreferencesHelper.java +4 −4 Original line number Diff line number Diff line Loading @@ -877,8 +877,8 @@ public class PreferencesHelper implements RankingConfig { @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING) public boolean canBePromoted(String packageName, int uid) { if (android.app.Flags.apiRichOngoingPermission()) { Log.e(TAG, "Should not be checking here if apiRichOngoingPermission flag enabled"); if (android.app.Flags.uiRichOngoing()) { Log.e(TAG, "Should not be checking here if uiRichOngoingPermission flag enabled"); return false; } Loading @@ -891,8 +891,8 @@ public class PreferencesHelper implements RankingConfig { public boolean setCanBePromoted(String packageName, int uid, boolean promote, boolean fromUser) { if (android.app.Flags.apiRichOngoingPermission()) { Log.e(TAG, "Should not be writing here if apiRichOngoingPermission flag enabled"); if (android.app.Flags.uiRichOngoing()) { Log.e(TAG, "Should not be writing here if uiRichOngoingPermission flag enabled"); return false; } Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +35 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static android.app.Flags.FLAG_API_RICH_ONGOING; import static android.app.Flags.FLAG_API_RICH_ONGOING_PERMISSION; import static android.app.Flags.FLAG_NM_SUMMARIZATION; import static android.app.Flags.FLAG_NM_SUMMARIZATION_UI; import static android.app.Flags.FLAG_OPT_IN_RICH_ONGOING; import static android.app.Flags.FLAG_UI_RICH_ONGOING; import static android.app.Notification.EXTRA_ALLOW_DURING_SETUP; import static android.app.Notification.EXTRA_PICTURE; Loading Loading @@ -585,6 +584,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private NotificationManagerService.WorkerHandler mWorkerHandler; private Handler mBroadcastsHandler; private int mPromotedMode = 0; private class TestableToastCallback extends ITransientNotification.Stub { @Override Loading Loading @@ -788,6 +788,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { initNMS(SystemService.PHASE_BOOT_COMPLETED); } @SuppressLint("MissingPermission") private void initNMS(int upToBootPhase) throws Exception { mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, mNotificationInstanceIdSequence); Loading Loading @@ -18078,9 +18079,38 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION}) public void testSetCanBePromoted_granted_ui() throws Exception { // UI flag includes permission enforcement via PermissionMgr/AppOps preparePermissionManagerFake(); testSetCanBePromoted_granted(); } private void preparePermissionManagerFake() { when(mPermissionHelper.hasRequestedPermission(Manifest.permission.USE_FULL_SCREEN_INTENT, mPkg, mUserId)).thenReturn(true); doAnswer(invocation -> { mPromotedMode = invocation.getArgument(2); Log.i(TAG, "Setting promoted mode to: " + mPromotedMode); return null; }).when(mAppOpsManager).setUidMode(eq(AppOpsManager.OP_POST_PROMOTED_NOTIFICATIONS), anyInt(), anyInt()); when(mPermissionManager.checkPermissionForPreflight( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any())) .thenAnswer( invocationOnMock -> { return mPromotedMode == AppOpsManager.MODE_ALLOWED ? PermissionManager.PERMISSION_GRANTED : PermissionManager.PERMISSION_SOFT_DENIED; }); when(mPermissionManager.checkPermissionForDataDelivery( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any(), any())) .thenAnswer( invocationOnMock -> { return mPromotedMode == AppOpsManager.MODE_ALLOWED ? PermissionManager.PERMISSION_GRANTED : PermissionManager.PERMISSION_SOFT_DENIED; }); } private void testSetCanBePromoted_granted() throws Exception { // qualifying posted notification Notification n = createPromotableNotification(); Loading Loading @@ -18151,6 +18181,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION}) public void testSetCanBePromoted_granted_onlyNotifiesOnce_ui() throws Exception { // UI flag includes permission enforcement via PermissionMgr/AppOps preparePermissionManagerFake(); testSetCanBePromoted_granted_onlyNotifiesOnce(); } Loading Loading @@ -18279,8 +18311,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags({FLAG_API_RICH_ONGOING}) @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION}) public void testPostPromotableNotification_noPermission() throws Exception { @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION, FLAG_UI_RICH_ONGOING}) public void testPostPromotableNotification_noPermission_preferences() throws Exception { mBinderService.setCanBePromoted(mPkg, mUid, false, true); postAndVerifyPromotableNotification(false); } Loading
core/java/android/app/AppOpsManager.java +14 −19 Original line number Diff line number Diff line Loading @@ -1505,15 +1505,6 @@ public class AppOpsManager { */ public static final int OP_USE_FULL_SCREEN_INTENT = AppOpEnums.APP_OP_USE_FULL_SCREEN_INTENT; /** * Post promoted notifications in the notification shade and status bar chips. * * @hide */ public static final int OP_POST_PROMOTED_NOTIFICATIONS = AppOpEnums.APP_OP_POST_PROMOTED_NOTIFICATIONS; /** * Hides camera indicator for sandboxed detection apps that directly access the service. * Loading Loading @@ -1715,6 +1706,14 @@ public class AppOpsManager { public static final int OP_SCENE_UNDERSTANDING_FINE = AppOpEnums.APP_OP_SCENE_UNDERSTANDING_FINE; /** * Post promoted notifications in the notification shade and status bar chips. * * @hide */ public static final int OP_POST_PROMOTED_NOTIFICATIONS = AppOpEnums.APP_OP_POST_PROMOTED_NOTIFICATIONS; /** @hide */ public static final int OP_SYSTEM_APPLICATION_OVERLAY = AppOpEnums.APP_OP_SYSTEM_APPLICATION_OVERLAY; Loading Loading @@ -2532,14 +2531,6 @@ public class AppOpsManager { */ public static final String OPSTR_USE_FULL_SCREEN_INTENT = "android:use_full_screen_intent"; /** * Permission to post promoted notifications. * * @hide */ public static final String OPSTR_POST_PROMOTED_NOTIFICATIONS = "android:post_promoted_notifications"; /** * Allows the assistant app to be voice-triggered by detected hotwords from a trusted detection * service. Loading Loading @@ -2696,6 +2687,10 @@ public class AppOpsManager { public static final String OPSTR_SCENE_UNDERSTANDING_FINE = "android:scene_understanding_fine"; /** @hide Permission to post promoted notifications. */ public static final String OPSTR_POST_PROMOTED_NOTIFICATIONS = "android:post_promoted_notifications"; /** @hide Required to draw system application overlays. */ public static final String OPSTR_SYSTEM_APPLICATION_OVERLAY = "android:system_application_overlay"; Loading Loading @@ -2825,7 +2820,7 @@ public class AppOpsManager { OP_MEDIA_ROUTING_CONTROL, OP_READ_SYSTEM_GRAMMATICAL_GENDER, OP_WRITE_SYSTEM_PREFERENCES, android.app.Flags.apiRichOngoingPermission() android.app.Flags.uiRichOngoing() ? OP_POST_PROMOTED_NOTIFICATIONS : OP_NONE, com.android.media.projection.flags.Flags.recordingOverlay() ? OP_SYSTEM_APPLICATION_OVERLAY : OP_NONE, Loading Loading @@ -3362,7 +3357,7 @@ public class AppOpsManager { .build(), new AppOpInfo.Builder(OP_POST_PROMOTED_NOTIFICATIONS, OPSTR_POST_PROMOTED_NOTIFICATIONS, "POST_PROMOTED_NOTIFICATIONS") .setPermission(android.app.Flags.apiRichOngoingPermission() .setPermission(android.app.Flags.uiRichOngoing() ? Manifest.permission.POST_PROMOTED_NOTIFICATIONS : null) .build(), new AppOpInfo.Builder(OP_SYSTEM_APPLICATION_OVERLAY, OPSTR_SYSTEM_APPLICATION_OVERLAY, Loading
core/res/AndroidManifest.xml +3 −1 Original line number Diff line number Diff line Loading @@ -8232,6 +8232,8 @@ android:protectionLevel="normal|appop" /> <!-- Required for apps to post promoted notifications. <p>This is required in addition to (not instead of) {@link android.app.Manifest.permission#POST_NOTIFICATIONS}. <p>Protection level: normal|appops @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING_PERMISSION) --> Loading @@ -8239,7 +8241,7 @@ android:label="@string/permlab_postPromotedNotifications" android:description="@string/permdesc_postPromotedNotifications" android:protectionLevel="normal|appop" android:featureFlag="android.app.api_rich_ongoing_permission"/> android:featureFlag="android.app.ui_rich_ongoing"/> <!-- @SystemApi Required for the privileged assistant apps targeting {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +4 −5 Original line number Diff line number Diff line Loading @@ -4741,7 +4741,7 @@ public class NotificationManagerService extends SystemService { final boolean changed; if (android.app.Flags.apiRichOngoingPermission()) { if (android.app.Flags.uiRichOngoing()) { // Use permission backend for allowing promotion per app if (!fromUser) { Loading @@ -4750,8 +4750,7 @@ public class NotificationManagerService extends SystemService { return; } boolean wasPromoted = checkPostPromotedNotificationPermission( pkg, uid); boolean wasPromoted = checkPostPromotedNotificationPermission(pkg, uid); int mode = promote ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED; mAppOps.setUidMode(OP_POST_PROMOTED_NOTIFICATIONS, uid, mode); Loading Loading @@ -9017,7 +9016,7 @@ public class NotificationManagerService extends SystemService { // Check permission last - after we make sure this is actually an attempted usage // of promotion - since AppOps tracks usage attempts. boolean canPostPromoted; if (android.app.Flags.apiRichOngoingPermission()) { if (android.app.Flags.uiRichOngoing()) { final AttributionSource attributionSource = new AttributionSource.Builder(notificationUid) .setPackageName(pkg).build(); Loading Loading @@ -9099,7 +9098,7 @@ public class NotificationManagerService extends SystemService { private boolean checkPostPromotedNotificationPermission( String pkg, int uid) { if (!android.app.Flags.apiRichOngoingPermission()) { if (!android.app.Flags.uiRichOngoing()) { return mPreferencesHelper.canBePromoted(pkg, uid); } else { final AttributionSource attributionSource = Loading
services/core/java/com/android/server/notification/PreferencesHelper.java +4 −4 Original line number Diff line number Diff line Loading @@ -877,8 +877,8 @@ public class PreferencesHelper implements RankingConfig { @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING) public boolean canBePromoted(String packageName, int uid) { if (android.app.Flags.apiRichOngoingPermission()) { Log.e(TAG, "Should not be checking here if apiRichOngoingPermission flag enabled"); if (android.app.Flags.uiRichOngoing()) { Log.e(TAG, "Should not be checking here if uiRichOngoingPermission flag enabled"); return false; } Loading @@ -891,8 +891,8 @@ public class PreferencesHelper implements RankingConfig { public boolean setCanBePromoted(String packageName, int uid, boolean promote, boolean fromUser) { if (android.app.Flags.apiRichOngoingPermission()) { Log.e(TAG, "Should not be writing here if apiRichOngoingPermission flag enabled"); if (android.app.Flags.uiRichOngoing()) { Log.e(TAG, "Should not be writing here if uiRichOngoingPermission flag enabled"); return false; } Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +35 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static android.app.Flags.FLAG_API_RICH_ONGOING; import static android.app.Flags.FLAG_API_RICH_ONGOING_PERMISSION; import static android.app.Flags.FLAG_NM_SUMMARIZATION; import static android.app.Flags.FLAG_NM_SUMMARIZATION_UI; import static android.app.Flags.FLAG_OPT_IN_RICH_ONGOING; import static android.app.Flags.FLAG_UI_RICH_ONGOING; import static android.app.Notification.EXTRA_ALLOW_DURING_SETUP; import static android.app.Notification.EXTRA_PICTURE; Loading Loading @@ -585,6 +584,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private NotificationManagerService.WorkerHandler mWorkerHandler; private Handler mBroadcastsHandler; private int mPromotedMode = 0; private class TestableToastCallback extends ITransientNotification.Stub { @Override Loading Loading @@ -788,6 +788,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { initNMS(SystemService.PHASE_BOOT_COMPLETED); } @SuppressLint("MissingPermission") private void initNMS(int upToBootPhase) throws Exception { mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, mNotificationInstanceIdSequence); Loading Loading @@ -18078,9 +18079,38 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION}) public void testSetCanBePromoted_granted_ui() throws Exception { // UI flag includes permission enforcement via PermissionMgr/AppOps preparePermissionManagerFake(); testSetCanBePromoted_granted(); } private void preparePermissionManagerFake() { when(mPermissionHelper.hasRequestedPermission(Manifest.permission.USE_FULL_SCREEN_INTENT, mPkg, mUserId)).thenReturn(true); doAnswer(invocation -> { mPromotedMode = invocation.getArgument(2); Log.i(TAG, "Setting promoted mode to: " + mPromotedMode); return null; }).when(mAppOpsManager).setUidMode(eq(AppOpsManager.OP_POST_PROMOTED_NOTIFICATIONS), anyInt(), anyInt()); when(mPermissionManager.checkPermissionForPreflight( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any())) .thenAnswer( invocationOnMock -> { return mPromotedMode == AppOpsManager.MODE_ALLOWED ? PermissionManager.PERMISSION_GRANTED : PermissionManager.PERMISSION_SOFT_DENIED; }); when(mPermissionManager.checkPermissionForDataDelivery( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any(), any())) .thenAnswer( invocationOnMock -> { return mPromotedMode == AppOpsManager.MODE_ALLOWED ? PermissionManager.PERMISSION_GRANTED : PermissionManager.PERMISSION_SOFT_DENIED; }); } private void testSetCanBePromoted_granted() throws Exception { // qualifying posted notification Notification n = createPromotableNotification(); Loading Loading @@ -18151,6 +18181,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION}) public void testSetCanBePromoted_granted_onlyNotifiesOnce_ui() throws Exception { // UI flag includes permission enforcement via PermissionMgr/AppOps preparePermissionManagerFake(); testSetCanBePromoted_granted_onlyNotifiesOnce(); } Loading Loading @@ -18279,8 +18311,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags({FLAG_API_RICH_ONGOING}) @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION}) public void testPostPromotableNotification_noPermission() throws Exception { @DisableFlags({FLAG_API_RICH_ONGOING_PERMISSION, FLAG_UI_RICH_ONGOING}) public void testPostPromotableNotification_noPermission_preferences() throws Exception { mBinderService.setCanBePromoted(mPkg, mUid, false, true); postAndVerifyPromotableNotification(false); }