Loading services/core/java/com/android/server/notification/NotificationManagerService.java +21 −16 Original line number Diff line number Diff line Loading @@ -1477,7 +1477,7 @@ public class NotificationManagerService extends SystemService { return ; } final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg)); final boolean isSystemToast = isCallerSystemOrPhone() || ("android".equals(pkg)); final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, Binder.getCallingUid()); Loading Loading @@ -1581,12 +1581,10 @@ public class NotificationManagerService extends SystemService { Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg); // Don't allow client applications to cancel foreground service notis or autobundled // summaries. final int mustNotHaveFlags = isCallingUidSystem() ? 0 : (Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTOGROUP_SUMMARY); cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0, (Binder.getCallingUid() == Process.SYSTEM_UID ? 0 : Notification.FLAG_FOREGROUND_SERVICE) | (Binder.getCallingUid() == Process.SYSTEM_UID ? 0 : Notification.FLAG_AUTOGROUP_SUMMARY), false, userId, REASON_APP_CANCEL, null); mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null); } @Override Loading Loading @@ -2452,7 +2450,7 @@ public class NotificationManagerService extends SystemService { } private void enforceSystemOrSystemUI(String message) { if (isCallerSystem()) return; if (isCallerSystemOrPhone()) return; getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE, message); } Loading Loading @@ -3276,7 +3274,7 @@ public class NotificationManagerService extends SystemService { private int resolveNotificationUid(String opPackageName, int callingUid, int userId) { // The system can post notifications on behalf of any package it wants if (isCallerSystem() && opPackageName != null && !"android".equals(opPackageName)) { if (isCallerSystemOrPhone() && opPackageName != null && !"android".equals(opPackageName)) { try { return getContext().getPackageManager() .getPackageUidAsUser(opPackageName, userId); Loading @@ -3295,7 +3293,8 @@ public class NotificationManagerService extends SystemService { private boolean checkDisqualifyingFeatures(int userId, int callingUid, int id, String tag, NotificationRecord r) { final String pkg = r.sbn.getPackageName(); final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg)); final boolean isSystemNotification = isUidSystemOrPhone(callingUid) || ("android".equals(pkg)); final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg); // Limit the number of notifications that any given package except the android Loading Loading @@ -4192,7 +4191,7 @@ public class NotificationManagerService extends SystemService { mNotificationsByKey.remove(recordInList.sbn.getKey()); wasPosted = true; } if ((recordInList = findNotificationByListLocked(mEnqueuedNotifications, r.getKey())) while ((recordInList = findNotificationByListLocked(mEnqueuedNotifications, r.getKey())) != null) { mEnqueuedNotifications.remove(recordInList); } Loading Loading @@ -4690,24 +4689,30 @@ public class NotificationManagerService extends SystemService { } } protected boolean isUidSystem(int uid) { protected boolean isCallingUidSystem() { final int uid = Binder.getCallingUid(); return uid == Process.SYSTEM_UID; } protected boolean isUidSystemOrPhone(int uid) { final int appid = UserHandle.getAppId(uid); return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0); } protected boolean isCallerSystem() { return isUidSystem(Binder.getCallingUid()); // TODO: Most calls should probably move to isCallerSystem. protected boolean isCallerSystemOrPhone() { return isUidSystemOrPhone(Binder.getCallingUid()); } private void checkCallerIsSystem() { if (isCallerSystem()) { if (isCallerSystemOrPhone()) { return; } throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid()); } private void checkCallerIsSystemOrSameApp(String pkg) { if (isCallerSystem()) { if (isCallerSystemOrPhone()) { return; } checkCallerIsSameApp(pkg); Loading @@ -4715,7 +4720,7 @@ public class NotificationManagerService extends SystemService { private boolean isCallerInstantApp(String pkg) { // System is always allowed to act for ephemeral apps. if (isCallerSystem()) { if (isCallerSystemOrPhone()) { return false; } Loading services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java +21 −2 Original line number Diff line number Diff line Loading @@ -104,7 +104,12 @@ public class NotificationManagerServiceTest { public TestableNotificationManagerService(Context context) { super(context); } @Override protected boolean isCallerSystem() { protected boolean isCallingUidSystem() { return true; } @Override protected boolean isCallerSystemOrPhone() { return true; } Loading Loading @@ -410,6 +415,21 @@ public class NotificationManagerServiceTest { assertEquals(0, notifs[0].getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE); } @Test public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception { final StatusBarNotification sbn = generateNotificationRecord(null).sbn; sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE; mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", sbn.getId(), sbn.getNotification(), sbn.getUserId()); sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT; mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", sbn.getId(), sbn.getNotification(), sbn.getUserId()); mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId()); waitForIdle(); assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); } @Test public void testFindGroupNotificationsLocked() throws Exception { // make sure the same notification can be found in both lists and returned Loading Loading @@ -449,7 +469,6 @@ public class NotificationManagerServiceTest { } } @Test public void testTvExtenderChannelOverride_onTv() throws Exception { mNotificationManagerService.setIsTelevision(true); Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +21 −16 Original line number Diff line number Diff line Loading @@ -1477,7 +1477,7 @@ public class NotificationManagerService extends SystemService { return ; } final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg)); final boolean isSystemToast = isCallerSystemOrPhone() || ("android".equals(pkg)); final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, Binder.getCallingUid()); Loading Loading @@ -1581,12 +1581,10 @@ public class NotificationManagerService extends SystemService { Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg); // Don't allow client applications to cancel foreground service notis or autobundled // summaries. final int mustNotHaveFlags = isCallingUidSystem() ? 0 : (Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTOGROUP_SUMMARY); cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0, (Binder.getCallingUid() == Process.SYSTEM_UID ? 0 : Notification.FLAG_FOREGROUND_SERVICE) | (Binder.getCallingUid() == Process.SYSTEM_UID ? 0 : Notification.FLAG_AUTOGROUP_SUMMARY), false, userId, REASON_APP_CANCEL, null); mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null); } @Override Loading Loading @@ -2452,7 +2450,7 @@ public class NotificationManagerService extends SystemService { } private void enforceSystemOrSystemUI(String message) { if (isCallerSystem()) return; if (isCallerSystemOrPhone()) return; getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE, message); } Loading Loading @@ -3276,7 +3274,7 @@ public class NotificationManagerService extends SystemService { private int resolveNotificationUid(String opPackageName, int callingUid, int userId) { // The system can post notifications on behalf of any package it wants if (isCallerSystem() && opPackageName != null && !"android".equals(opPackageName)) { if (isCallerSystemOrPhone() && opPackageName != null && !"android".equals(opPackageName)) { try { return getContext().getPackageManager() .getPackageUidAsUser(opPackageName, userId); Loading @@ -3295,7 +3293,8 @@ public class NotificationManagerService extends SystemService { private boolean checkDisqualifyingFeatures(int userId, int callingUid, int id, String tag, NotificationRecord r) { final String pkg = r.sbn.getPackageName(); final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg)); final boolean isSystemNotification = isUidSystemOrPhone(callingUid) || ("android".equals(pkg)); final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg); // Limit the number of notifications that any given package except the android Loading Loading @@ -4192,7 +4191,7 @@ public class NotificationManagerService extends SystemService { mNotificationsByKey.remove(recordInList.sbn.getKey()); wasPosted = true; } if ((recordInList = findNotificationByListLocked(mEnqueuedNotifications, r.getKey())) while ((recordInList = findNotificationByListLocked(mEnqueuedNotifications, r.getKey())) != null) { mEnqueuedNotifications.remove(recordInList); } Loading Loading @@ -4690,24 +4689,30 @@ public class NotificationManagerService extends SystemService { } } protected boolean isUidSystem(int uid) { protected boolean isCallingUidSystem() { final int uid = Binder.getCallingUid(); return uid == Process.SYSTEM_UID; } protected boolean isUidSystemOrPhone(int uid) { final int appid = UserHandle.getAppId(uid); return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0); } protected boolean isCallerSystem() { return isUidSystem(Binder.getCallingUid()); // TODO: Most calls should probably move to isCallerSystem. protected boolean isCallerSystemOrPhone() { return isUidSystemOrPhone(Binder.getCallingUid()); } private void checkCallerIsSystem() { if (isCallerSystem()) { if (isCallerSystemOrPhone()) { return; } throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid()); } private void checkCallerIsSystemOrSameApp(String pkg) { if (isCallerSystem()) { if (isCallerSystemOrPhone()) { return; } checkCallerIsSameApp(pkg); Loading @@ -4715,7 +4720,7 @@ public class NotificationManagerService extends SystemService { private boolean isCallerInstantApp(String pkg) { // System is always allowed to act for ephemeral apps. if (isCallerSystem()) { if (isCallerSystemOrPhone()) { return false; } Loading
services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java +21 −2 Original line number Diff line number Diff line Loading @@ -104,7 +104,12 @@ public class NotificationManagerServiceTest { public TestableNotificationManagerService(Context context) { super(context); } @Override protected boolean isCallerSystem() { protected boolean isCallingUidSystem() { return true; } @Override protected boolean isCallerSystemOrPhone() { return true; } Loading Loading @@ -410,6 +415,21 @@ public class NotificationManagerServiceTest { assertEquals(0, notifs[0].getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE); } @Test public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception { final StatusBarNotification sbn = generateNotificationRecord(null).sbn; sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE; mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", sbn.getId(), sbn.getNotification(), sbn.getUserId()); sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT; mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", sbn.getId(), sbn.getNotification(), sbn.getUserId()); mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId()); waitForIdle(); assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); } @Test public void testFindGroupNotificationsLocked() throws Exception { // make sure the same notification can be found in both lists and returned Loading Loading @@ -449,7 +469,6 @@ public class NotificationManagerServiceTest { } } @Test public void testTvExtenderChannelOverride_onTv() throws Exception { mNotificationManagerService.setIsTelevision(true); Loading