diff options
Diffstat (limited to 'services/core/java/com/android/server/notification/NotificationManagerService.java')
-rwxr-xr-x | services/core/java/com/android/server/notification/NotificationManagerService.java | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index e94507bccea0..65b3221747a1 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -402,6 +402,7 @@ public class NotificationManagerService extends SystemService { private IActivityManager mAm; private ActivityTaskManagerInternal mAtm; private ActivityManager mActivityManager; + private ActivityManagerInternal mAmi; private IPackageManager mPackageManager; private PackageManager mPackageManagerClient; AudioManager mAudioManager; @@ -1875,7 +1876,7 @@ public class NotificationManagerService extends SystemService { DevicePolicyManagerInternal dpm, IUriGrantsManager ugm, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, UserManager userManager, NotificationHistoryManager historyManager, StatsManager statsManager, - TelephonyManager telephonyManager) { + TelephonyManager telephonyManager, ActivityManagerInternal ami) { mHandler = handler; Resources resources = getContext().getResources(); mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(), @@ -1896,6 +1897,7 @@ public class NotificationManagerService extends SystemService { mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mCompanionManager = companionManager; mActivityManager = activityManager; + mAmi = ami; mDeviceIdleController = IDeviceIdleController.Stub.asInterface( ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); mDpm = dpm; @@ -2111,7 +2113,8 @@ public class NotificationManagerService extends SystemService { new NotificationHistoryManager(getContext(), handler), mStatsManager = (StatsManager) getContext().getSystemService( Context.STATS_MANAGER), - getContext().getSystemService(TelephonyManager.class)); + getContext().getSystemService(TelephonyManager.class), + LocalServices.getService(ActivityManagerInternal.class)); // register for various Intents IntentFilter filter = new IntentFilter(); @@ -3395,15 +3398,30 @@ public class NotificationManagerService extends SystemService { pkg, uid, channelId, conversationId, true, includeDeleted); } + // Returns 'true' if the given channel has a notification associated + // with an active foreground service. + private void enforceDeletingChannelHasNoFgService(String pkg, int userId, + String channelId) { + if (mAmi.hasForegroundServiceNotification(pkg, userId, channelId)) { + Slog.w(TAG, "Package u" + userId + "/" + pkg + + " may not delete notification channel '" + + channelId + "' with fg service"); + throw new SecurityException("Not allowed to delete channel " + channelId + + " with a foreground service"); + } + } + @Override public void deleteNotificationChannel(String pkg, String channelId) { checkCallerIsSystemOrSameApp(pkg); final int callingUid = Binder.getCallingUid(); + final int callingUser = UserHandle.getUserId(callingUid); if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) { throw new IllegalArgumentException("Cannot delete default channel"); } + enforceDeletingChannelHasNoFgService(pkg, callingUser, channelId); cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true, - UserHandle.getUserId(callingUid), REASON_CHANNEL_BANNED, null); + callingUser, REASON_CHANNEL_BANNED, null); mPreferencesHelper.deleteNotificationChannel(pkg, callingUid, channelId); mListeners.notifyNotificationChannelChanged(pkg, UserHandle.getUserHandleForUid(callingUid), @@ -3416,19 +3434,23 @@ public class NotificationManagerService extends SystemService { public void deleteConversationNotificationChannels(String pkg, int uid, String conversationId) { checkCallerIsSystem(); - final int callingUid = Binder.getCallingUid(); List<NotificationChannel> channels = mPreferencesHelper.getNotificationChannelsByConversationId( pkg, uid, conversationId); if (!channels.isEmpty()) { + // Preflight for fg service notifications in these channels: do nothing + // unless they're all eligible + final int appUserId = UserHandle.getUserId(uid); for (NotificationChannel nc : channels) { + final String channelId = nc.getId(); + mAmi.stopForegroundServicesForChannel(pkg, appUserId, channelId); cancelAllNotificationsInt(MY_UID, MY_PID, pkg, nc.getId(), 0, 0, true, - UserHandle.getUserId(callingUid), REASON_CHANNEL_BANNED, null); - mPreferencesHelper.deleteNotificationChannel(pkg, callingUid, nc.getId()); + appUserId, REASON_CHANNEL_BANNED, null); + mPreferencesHelper.deleteNotificationChannel(pkg, uid, channelId); mListeners.notifyNotificationChannelChanged(pkg, - UserHandle.getUserHandleForUid(callingUid), + UserHandle.getUserHandleForUid(uid), mPreferencesHelper.getNotificationChannel( - pkg, callingUid, nc.getId(), true), + pkg, uid, channelId, true), NOTIFICATION_CHANNEL_OR_GROUP_DELETED); } handleSavePolicyFile(); @@ -3459,13 +3481,20 @@ public class NotificationManagerService extends SystemService { NotificationChannelGroup groupToDelete = mPreferencesHelper.getNotificationChannelGroup(groupId, pkg, callingUid); if (groupToDelete != null) { + // Preflight for allowability + final int userId = UserHandle.getUserId(callingUid); + List<NotificationChannel> groupChannels = groupToDelete.getChannels(); + for (int i = 0; i < groupChannels.size(); i++) { + enforceDeletingChannelHasNoFgService(pkg, userId, + groupChannels.get(i).getId()); + } List<NotificationChannel> deletedChannels = mPreferencesHelper.deleteNotificationChannelGroup(pkg, callingUid, groupId); for (int i = 0; i < deletedChannels.size(); i++) { final NotificationChannel deletedChannel = deletedChannels.get(i); cancelAllNotificationsInt(MY_UID, MY_PID, pkg, deletedChannel.getId(), 0, 0, true, - UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED, + userId, REASON_CHANNEL_BANNED, null); mListeners.notifyNotificationChannelChanged(pkg, UserHandle.getUserHandleForUid(callingUid), |