Loading services/core/java/com/android/server/notification/NotificationManagerService.java +10 −4 Original line number Diff line number Diff line Loading @@ -3291,6 +3291,11 @@ public class NotificationManagerService extends SystemService { return new MultiRateLimiter.Builder(getContext()).addRateLimits(TOAST_RATE_LIMITS).build(); } protected int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) { return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); } @VisibleForTesting final IBinder mService = new INotificationManager.Stub() { // Toasts Loading Loading @@ -5244,10 +5249,11 @@ public class NotificationManagerService extends SystemService { } private boolean checkPolicyAccess(String pkg) { final int uid; try { int uid = getContext().getPackageManager().getPackageUidAsUser(pkg, uid = getContext().getPackageManager().getPackageUidAsUser(pkg, UserHandle.getCallingUserId()); if (PackageManager.PERMISSION_GRANTED == ActivityManager.checkComponentPermission( if (PackageManager.PERMISSION_GRANTED == checkComponentPermission( android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true)) { return true; Loading @@ -5258,8 +5264,8 @@ public class NotificationManagerService extends SystemService { //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode. return checkPackagePolicyAccess(pkg) || mListeners.isComponentEnabledForPackage(pkg) || (mDpm != null && (mDpm.isActiveProfileOwner(Binder.getCallingUid()) || mDpm.isActiveDeviceOwner(Binder.getCallingUid()))); || (mDpm != null && (mDpm.isActiveProfileOwner(uid) || mDpm.isActiveDeviceOwner(uid))); } @Override Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +129 −0 Original line number Diff line number Diff line Loading @@ -705,6 +705,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mTestFlagResolver.setFlagOverride(FSI_FORCE_DEMOTE, false); mTestFlagResolver.setFlagOverride(SHOW_STICKY_HUN_FOR_DENIED_FSI, false); var checker = mock(TestableNotificationManagerService.ComponentPermissionChecker.class); mService.permissionChecker = checker; when(checker.check(anyString(), anyInt(), anyInt(), anyBoolean())) .thenReturn(PackageManager.PERMISSION_DENIED); } @After Loading Loading @@ -12284,6 +12289,130 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { inOrder.verifyNoMoreInteractions(); } @Test public void isNotificationPolicyAccessGranted_invalidPackage() throws Exception { final String notReal = "NOT REAL"; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(notReal), anyInt())).thenThrow( PackageManager.NameNotFoundException.class); assertThat(mBinderService.isNotificationPolicyAccessGranted(notReal)).isFalse(); verify(mPackageManagerClient).getPackageUidAsUser(eq(notReal), anyInt()); verify(checker, never()).check(any(), anyInt(), anyInt(), anyBoolean()); verify(mConditionProviders, never()).isPackageOrComponentAllowed(eq(notReal), anyInt()); verify(mListeners, never()).isComponentEnabledForPackage(any()); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_hasPermission() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(checker.check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true)) .thenReturn(PackageManager.PERMISSION_GRANTED); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders, never()).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners, never()).isComponentEnabledForPackage(any()); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_isPackageAllowed() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mConditionProviders.isPackageOrComponentAllowed(eq(packageName), anyInt())) .thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners, never()).isComponentEnabledForPackage(any()); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_isComponentEnabled() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mListeners.isComponentEnabledForPackage(packageName)).thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_isDeviceOwner() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mDevicePolicyManager.isActiveDeviceOwner(uid)).thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager).isActiveDeviceOwner(uid); } /** * b/292163859 */ @Test public void isNotificationPolicyAccessGranted_callerIsDeviceOwner() throws Exception { final String packageName = "target"; final int uid = 123; final int callingUid = Binder.getCallingUid(); final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mDevicePolicyManager.isActiveDeviceOwner(callingUid)).thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isFalse(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager).isActiveDeviceOwner(uid); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(callingUid); } @Test public void isNotificationPolicyAccessGranted_notGranted() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isFalse(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager).isActiveDeviceOwner(uid); } private static <T extends Parcelable> T parcelAndUnparcel(T source, Parcelable.Creator<T> creator) { Parcel parcel = Parcel.obtain(); services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ public class TestableNotificationManagerService extends NotificationManagerServi @Nullable Boolean mIsVisibleToListenerReturnValue = null; ComponentPermissionChecker permissionChecker; TestableNotificationManagerService(Context context, NotificationRecordLogger logger, InstanceIdSequence notificationInstanceIdSequence) { super(context, logger, notificationInstanceIdSequence); Loading Loading @@ -150,6 +152,12 @@ public class TestableNotificationManagerService extends NotificationManagerServi return super.isVisibleToListener(sbn, notificationType, listener); } @Override protected int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) { return permissionChecker.check(permission, uid, owningUid, exported); } public class StrongAuthTrackerFake extends NotificationManagerService.StrongAuthTracker { private int mGetStrongAuthForUserReturnValue = 0; StrongAuthTrackerFake(Context context) { Loading @@ -165,4 +173,8 @@ public class TestableNotificationManagerService extends NotificationManagerServi return mGetStrongAuthForUserReturnValue; } } public interface ComponentPermissionChecker { int check(String permission, int uid, int owningUid, boolean exported); } } Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +10 −4 Original line number Diff line number Diff line Loading @@ -3291,6 +3291,11 @@ public class NotificationManagerService extends SystemService { return new MultiRateLimiter.Builder(getContext()).addRateLimits(TOAST_RATE_LIMITS).build(); } protected int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) { return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); } @VisibleForTesting final IBinder mService = new INotificationManager.Stub() { // Toasts Loading Loading @@ -5244,10 +5249,11 @@ public class NotificationManagerService extends SystemService { } private boolean checkPolicyAccess(String pkg) { final int uid; try { int uid = getContext().getPackageManager().getPackageUidAsUser(pkg, uid = getContext().getPackageManager().getPackageUidAsUser(pkg, UserHandle.getCallingUserId()); if (PackageManager.PERMISSION_GRANTED == ActivityManager.checkComponentPermission( if (PackageManager.PERMISSION_GRANTED == checkComponentPermission( android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true)) { return true; Loading @@ -5258,8 +5264,8 @@ public class NotificationManagerService extends SystemService { //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode. return checkPackagePolicyAccess(pkg) || mListeners.isComponentEnabledForPackage(pkg) || (mDpm != null && (mDpm.isActiveProfileOwner(Binder.getCallingUid()) || mDpm.isActiveDeviceOwner(Binder.getCallingUid()))); || (mDpm != null && (mDpm.isActiveProfileOwner(uid) || mDpm.isActiveDeviceOwner(uid))); } @Override Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +129 −0 Original line number Diff line number Diff line Loading @@ -705,6 +705,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mTestFlagResolver.setFlagOverride(FSI_FORCE_DEMOTE, false); mTestFlagResolver.setFlagOverride(SHOW_STICKY_HUN_FOR_DENIED_FSI, false); var checker = mock(TestableNotificationManagerService.ComponentPermissionChecker.class); mService.permissionChecker = checker; when(checker.check(anyString(), anyInt(), anyInt(), anyBoolean())) .thenReturn(PackageManager.PERMISSION_DENIED); } @After Loading Loading @@ -12284,6 +12289,130 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { inOrder.verifyNoMoreInteractions(); } @Test public void isNotificationPolicyAccessGranted_invalidPackage() throws Exception { final String notReal = "NOT REAL"; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(notReal), anyInt())).thenThrow( PackageManager.NameNotFoundException.class); assertThat(mBinderService.isNotificationPolicyAccessGranted(notReal)).isFalse(); verify(mPackageManagerClient).getPackageUidAsUser(eq(notReal), anyInt()); verify(checker, never()).check(any(), anyInt(), anyInt(), anyBoolean()); verify(mConditionProviders, never()).isPackageOrComponentAllowed(eq(notReal), anyInt()); verify(mListeners, never()).isComponentEnabledForPackage(any()); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_hasPermission() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(checker.check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true)) .thenReturn(PackageManager.PERMISSION_GRANTED); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders, never()).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners, never()).isComponentEnabledForPackage(any()); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_isPackageAllowed() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mConditionProviders.isPackageOrComponentAllowed(eq(packageName), anyInt())) .thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners, never()).isComponentEnabledForPackage(any()); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_isComponentEnabled() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mListeners.isComponentEnabledForPackage(packageName)).thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(anyInt()); } @Test public void isNotificationPolicyAccessGranted_isDeviceOwner() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mDevicePolicyManager.isActiveDeviceOwner(uid)).thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isTrue(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager).isActiveDeviceOwner(uid); } /** * b/292163859 */ @Test public void isNotificationPolicyAccessGranted_callerIsDeviceOwner() throws Exception { final String packageName = "target"; final int uid = 123; final int callingUid = Binder.getCallingUid(); final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); when(mDevicePolicyManager.isActiveDeviceOwner(callingUid)).thenReturn(true); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isFalse(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager).isActiveDeviceOwner(uid); verify(mDevicePolicyManager, never()).isActiveDeviceOwner(callingUid); } @Test public void isNotificationPolicyAccessGranted_notGranted() throws Exception { final String packageName = "target"; final int uid = 123; final var checker = mService.permissionChecker; when(mPackageManagerClient.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid); assertThat(mBinderService.isNotificationPolicyAccessGranted(packageName)).isFalse(); verify(mPackageManagerClient).getPackageUidAsUser(eq(packageName), anyInt()); verify(checker).check(android.Manifest.permission.MANAGE_NOTIFICATIONS, uid, -1, true); verify(mConditionProviders).isPackageOrComponentAllowed(eq(packageName), anyInt()); verify(mListeners).isComponentEnabledForPackage(packageName); verify(mDevicePolicyManager).isActiveDeviceOwner(uid); } private static <T extends Parcelable> T parcelAndUnparcel(T source, Parcelable.Creator<T> creator) { Parcel parcel = Parcel.obtain();
services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ public class TestableNotificationManagerService extends NotificationManagerServi @Nullable Boolean mIsVisibleToListenerReturnValue = null; ComponentPermissionChecker permissionChecker; TestableNotificationManagerService(Context context, NotificationRecordLogger logger, InstanceIdSequence notificationInstanceIdSequence) { super(context, logger, notificationInstanceIdSequence); Loading Loading @@ -150,6 +152,12 @@ public class TestableNotificationManagerService extends NotificationManagerServi return super.isVisibleToListener(sbn, notificationType, listener); } @Override protected int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) { return permissionChecker.check(permission, uid, owningUid, exported); } public class StrongAuthTrackerFake extends NotificationManagerService.StrongAuthTracker { private int mGetStrongAuthForUserReturnValue = 0; StrongAuthTrackerFake(Context context) { Loading @@ -165,4 +173,8 @@ public class TestableNotificationManagerService extends NotificationManagerServi return mGetStrongAuthForUserReturnValue; } } public interface ComponentPermissionChecker { int check(String permission, int uid, int owningUid, boolean exported); } }