@@ -402,6 +402,7 @@ public class NotificationManagerService extends SystemService {
402402 private IActivityManager mAm ;
403403 private ActivityTaskManagerInternal mAtm ;
404404 private ActivityManager mActivityManager ;
405+ private ActivityManagerInternal mAmi ;
405406 private IPackageManager mPackageManager ;
406407 private PackageManager mPackageManagerClient ;
407408 AudioManager mAudioManager ;
@@ -1875,7 +1876,7 @@ void init(WorkerHandler handler, RankingHandler rankingHandler,
18751876 DevicePolicyManagerInternal dpm , IUriGrantsManager ugm ,
18761877 UriGrantsManagerInternal ugmInternal , AppOpsManager appOps , UserManager userManager ,
18771878 NotificationHistoryManager historyManager , StatsManager statsManager ,
1878- TelephonyManager telephonyManager ) {
1879+ TelephonyManager telephonyManager , ActivityManagerInternal ami ) {
18791880 mHandler = handler ;
18801881 Resources resources = getContext ().getResources ();
18811882 mMaxPackageEnqueueRate = Settings .Global .getFloat (getContext ().getContentResolver (),
@@ -1896,6 +1897,7 @@ void init(WorkerHandler handler, RankingHandler rankingHandler,
18961897 mAlarmManager = (AlarmManager ) getContext ().getSystemService (Context .ALARM_SERVICE );
18971898 mCompanionManager = companionManager ;
18981899 mActivityManager = activityManager ;
1900+ mAmi = ami ;
18991901 mDeviceIdleController = IDeviceIdleController .Stub .asInterface (
19001902 ServiceManager .getService (Context .DEVICE_IDLE_CONTROLLER ));
19011903 mDpm = dpm ;
@@ -2111,7 +2113,8 @@ null, snoozeHelper, new NotificationUsageStats(getContext()),
21112113 new NotificationHistoryManager (getContext (), handler ),
21122114 mStatsManager = (StatsManager ) getContext ().getSystemService (
21132115 Context .STATS_MANAGER ),
2114- getContext ().getSystemService (TelephonyManager .class ));
2116+ getContext ().getSystemService (TelephonyManager .class ),
2117+ LocalServices .getService (ActivityManagerInternal .class ));
21152118
21162119 // register for various Intents
21172120 IntentFilter filter = new IntentFilter ();
@@ -3395,15 +3398,30 @@ public NotificationChannel getNotificationChannelForPackage(String pkg, int uid,
33953398 pkg , uid , channelId , conversationId , true , includeDeleted );
33963399 }
33973400
3401+ // Returns 'true' if the given channel has a notification associated
3402+ // with an active foreground service.
3403+ private void enforceDeletingChannelHasNoFgService (String pkg , int userId ,
3404+ String channelId ) {
3405+ if (mAmi .hasForegroundServiceNotification (pkg , userId , channelId )) {
3406+ Slog .w (TAG , "Package u" + userId + "/" + pkg
3407+ + " may not delete notification channel '"
3408+ + channelId + "' with fg service" );
3409+ throw new SecurityException ("Not allowed to delete channel " + channelId
3410+ + " with a foreground service" );
3411+ }
3412+ }
3413+
33983414 @ Override
33993415 public void deleteNotificationChannel (String pkg , String channelId ) {
34003416 checkCallerIsSystemOrSameApp (pkg );
34013417 final int callingUid = Binder .getCallingUid ();
3418+ final int callingUser = UserHandle .getUserId (callingUid );
34023419 if (NotificationChannel .DEFAULT_CHANNEL_ID .equals (channelId )) {
34033420 throw new IllegalArgumentException ("Cannot delete default channel" );
34043421 }
3422+ enforceDeletingChannelHasNoFgService (pkg , callingUser , channelId );
34053423 cancelAllNotificationsInt (MY_UID , MY_PID , pkg , channelId , 0 , 0 , true ,
3406- UserHandle . getUserId ( callingUid ) , REASON_CHANNEL_BANNED , null );
3424+ callingUser , REASON_CHANNEL_BANNED , null );
34073425 mPreferencesHelper .deleteNotificationChannel (pkg , callingUid , channelId );
34083426 mListeners .notifyNotificationChannelChanged (pkg ,
34093427 UserHandle .getUserHandleForUid (callingUid ),
@@ -3416,19 +3434,23 @@ public void deleteNotificationChannel(String pkg, String channelId) {
34163434 public void deleteConversationNotificationChannels (String pkg , int uid ,
34173435 String conversationId ) {
34183436 checkCallerIsSystem ();
3419- final int callingUid = Binder .getCallingUid ();
34203437 List <NotificationChannel > channels =
34213438 mPreferencesHelper .getNotificationChannelsByConversationId (
34223439 pkg , uid , conversationId );
34233440 if (!channels .isEmpty ()) {
3441+ // Preflight for fg service notifications in these channels: do nothing
3442+ // unless they're all eligible
3443+ final int appUserId = UserHandle .getUserId (uid );
34243444 for (NotificationChannel nc : channels ) {
3445+ final String channelId = nc .getId ();
3446+ mAmi .stopForegroundServicesForChannel (pkg , appUserId , channelId );
34253447 cancelAllNotificationsInt (MY_UID , MY_PID , pkg , nc .getId (), 0 , 0 , true ,
3426- UserHandle . getUserId ( callingUid ) , REASON_CHANNEL_BANNED , null );
3427- mPreferencesHelper .deleteNotificationChannel (pkg , callingUid , nc . getId () );
3448+ appUserId , REASON_CHANNEL_BANNED , null );
3449+ mPreferencesHelper .deleteNotificationChannel (pkg , uid , channelId );
34283450 mListeners .notifyNotificationChannelChanged (pkg ,
3429- UserHandle .getUserHandleForUid (callingUid ),
3451+ UserHandle .getUserHandleForUid (uid ),
34303452 mPreferencesHelper .getNotificationChannel (
3431- pkg , callingUid , nc . getId () , true ),
3453+ pkg , uid , channelId , true ),
34323454 NOTIFICATION_CHANNEL_OR_GROUP_DELETED );
34333455 }
34343456 handleSavePolicyFile ();
@@ -3459,13 +3481,20 @@ public void deleteNotificationChannelGroup(String pkg, String groupId) {
34593481 NotificationChannelGroup groupToDelete =
34603482 mPreferencesHelper .getNotificationChannelGroup (groupId , pkg , callingUid );
34613483 if (groupToDelete != null ) {
3484+ // Preflight for allowability
3485+ final int userId = UserHandle .getUserId (callingUid );
3486+ List <NotificationChannel > groupChannels = groupToDelete .getChannels ();
3487+ for (int i = 0 ; i < groupChannels .size (); i ++) {
3488+ enforceDeletingChannelHasNoFgService (pkg , userId ,
3489+ groupChannels .get (i ).getId ());
3490+ }
34623491 List <NotificationChannel > deletedChannels =
34633492 mPreferencesHelper .deleteNotificationChannelGroup (pkg , callingUid , groupId );
34643493 for (int i = 0 ; i < deletedChannels .size (); i ++) {
34653494 final NotificationChannel deletedChannel = deletedChannels .get (i );
34663495 cancelAllNotificationsInt (MY_UID , MY_PID , pkg , deletedChannel .getId (), 0 , 0 ,
34673496 true ,
3468- UserHandle . getUserId ( Binder . getCallingUid ()) , REASON_CHANNEL_BANNED ,
3497+ userId , REASON_CHANNEL_BANNED ,
34693498 null );
34703499 mListeners .notifyNotificationChannelChanged (pkg ,
34713500 UserHandle .getUserHandleForUid (callingUid ),
0 commit comments