Loading services/core/java/com/android/server/notification/NotificationManagerService.java +10 −2 Original line number Diff line number Diff line Loading @@ -3323,7 +3323,8 @@ public class NotificationManagerService extends SystemService { final boolean isSystemToast = isCallerSystemOrPhone() || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg); boolean isAppRenderedToast = (callback != null); if (!checkCanEnqueueToast(pkg, callingUid, isAppRenderedToast, isSystemToast)) { if (!checkCanEnqueueToast(pkg, callingUid, displayId, isAppRenderedToast, isSystemToast)) { return; } Loading Loading @@ -3393,7 +3394,7 @@ public class NotificationManagerService extends SystemService { } } private boolean checkCanEnqueueToast(String pkg, int callingUid, private boolean checkCanEnqueueToast(String pkg, int callingUid, int displayId, boolean isAppRenderedToast, boolean isSystemToast) { final boolean isPackageSuspended = isPackagePaused(pkg); final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg, Loading Loading @@ -3423,6 +3424,13 @@ public class NotificationManagerService extends SystemService { return false; } int userId = UserHandle.getUserId(callingUid); if (!isSystemToast && !mUmInternal.isUserVisible(userId, displayId)) { Slog.e(TAG, "Suppressing toast from package " + pkg + "/" + callingUid + " as user " + userId + " is not visible on display " + displayId); return false; } return true; } Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -607,6 +607,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), anyString(), anyInt(), any())).thenReturn(true); when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true); mockIsUserVisible(DEFAULT_DISPLAY, true); mockIsVisibleBackgroundUsersSupported(false); // Set the testable bubble extractor Loading Loading @@ -6909,6 +6910,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testTextToastsCallStatusBar_nonUiContext_secondaryDisplay() throws Exception { allowTestPackageToToast(); mockIsUserVisible(SECONDARY_DISPLAY_ID, true); enqueueTextToast(TEST_PACKAGE, "Text", /* isUiContext= */ false, SECONDARY_DISPLAY_ID); Loading @@ -6932,6 +6934,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testTextToastsCallStatusBar_visibleBgUsers_uiContext_secondaryDisplay() throws Exception { mockIsVisibleBackgroundUsersSupported(true); mockIsUserVisible(SECONDARY_DISPLAY_ID, true); mockDisplayAssignedToUser(INVALID_DISPLAY); // make sure it's not used allowTestPackageToToast(); Loading @@ -6956,6 +6959,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testTextToastsCallStatusBar_visibleBgUsers_nonUiContext_secondaryDisplay() throws Exception { mockIsVisibleBackgroundUsersSupported(true); mockIsUserVisible(SECONDARY_DISPLAY_ID, true); mockDisplayAssignedToUser(INVALID_DISPLAY); // make sure it's not used allowTestPackageToToast(); Loading @@ -6964,6 +6968,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verifyToastShownForTestPackage("Text", SECONDARY_DISPLAY_ID); } @Test public void testTextToastsCallStatusBar_userNotVisibleOnDisplay() throws Exception { final String testPackage = "testPackageName"; assertEquals(0, mService.mToastQueue.size()); mService.isSystemUid = false; setToastRateIsWithinQuota(true); setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false); mockIsUserVisible(DEFAULT_DISPLAY, false); // package is not suspended when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid))) .thenReturn(false); // enqueue toast -> no toasts enqueued enqueueTextToast(testPackage, "Text"); verify(mStatusBar, never()).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); assertEquals(0, mService.mToastQueue.size()); } @Test public void testDisallowToastsFromSuspendedPackages() throws Exception { final String testPackage = "testPackageName"; Loading @@ -6981,6 +7005,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // enqueue toast -> no toasts enqueued enqueueToast(testPackage, new TestableToastCallback()); verify(mStatusBar, never()).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); assertEquals(0, mService.mToastQueue.size()); } Loading Loading @@ -10804,6 +10830,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mUm.isVisibleBackgroundUsersSupported()).thenReturn(supported); } private void mockIsUserVisible(int displayId, boolean visible) { when(mUmInternal.isUserVisible(mUserId, displayId)).thenReturn(visible); } private void mockDisplayAssignedToUser(int displayId) { when(mUmInternal.getMainDisplayAssignedToUser(mUserId)).thenReturn(displayId); } Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +10 −2 Original line number Diff line number Diff line Loading @@ -3323,7 +3323,8 @@ public class NotificationManagerService extends SystemService { final boolean isSystemToast = isCallerSystemOrPhone() || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg); boolean isAppRenderedToast = (callback != null); if (!checkCanEnqueueToast(pkg, callingUid, isAppRenderedToast, isSystemToast)) { if (!checkCanEnqueueToast(pkg, callingUid, displayId, isAppRenderedToast, isSystemToast)) { return; } Loading Loading @@ -3393,7 +3394,7 @@ public class NotificationManagerService extends SystemService { } } private boolean checkCanEnqueueToast(String pkg, int callingUid, private boolean checkCanEnqueueToast(String pkg, int callingUid, int displayId, boolean isAppRenderedToast, boolean isSystemToast) { final boolean isPackageSuspended = isPackagePaused(pkg); final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg, Loading Loading @@ -3423,6 +3424,13 @@ public class NotificationManagerService extends SystemService { return false; } int userId = UserHandle.getUserId(callingUid); if (!isSystemToast && !mUmInternal.isUserVisible(userId, displayId)) { Slog.e(TAG, "Suppressing toast from package " + pkg + "/" + callingUid + " as user " + userId + " is not visible on display " + displayId); return false; } return true; } Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -607,6 +607,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), anyString(), anyInt(), any())).thenReturn(true); when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true); mockIsUserVisible(DEFAULT_DISPLAY, true); mockIsVisibleBackgroundUsersSupported(false); // Set the testable bubble extractor Loading Loading @@ -6909,6 +6910,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testTextToastsCallStatusBar_nonUiContext_secondaryDisplay() throws Exception { allowTestPackageToToast(); mockIsUserVisible(SECONDARY_DISPLAY_ID, true); enqueueTextToast(TEST_PACKAGE, "Text", /* isUiContext= */ false, SECONDARY_DISPLAY_ID); Loading @@ -6932,6 +6934,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testTextToastsCallStatusBar_visibleBgUsers_uiContext_secondaryDisplay() throws Exception { mockIsVisibleBackgroundUsersSupported(true); mockIsUserVisible(SECONDARY_DISPLAY_ID, true); mockDisplayAssignedToUser(INVALID_DISPLAY); // make sure it's not used allowTestPackageToToast(); Loading @@ -6956,6 +6959,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testTextToastsCallStatusBar_visibleBgUsers_nonUiContext_secondaryDisplay() throws Exception { mockIsVisibleBackgroundUsersSupported(true); mockIsUserVisible(SECONDARY_DISPLAY_ID, true); mockDisplayAssignedToUser(INVALID_DISPLAY); // make sure it's not used allowTestPackageToToast(); Loading @@ -6964,6 +6968,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verifyToastShownForTestPackage("Text", SECONDARY_DISPLAY_ID); } @Test public void testTextToastsCallStatusBar_userNotVisibleOnDisplay() throws Exception { final String testPackage = "testPackageName"; assertEquals(0, mService.mToastQueue.size()); mService.isSystemUid = false; setToastRateIsWithinQuota(true); setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false); mockIsUserVisible(DEFAULT_DISPLAY, false); // package is not suspended when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid))) .thenReturn(false); // enqueue toast -> no toasts enqueued enqueueTextToast(testPackage, "Text"); verify(mStatusBar, never()).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); assertEquals(0, mService.mToastQueue.size()); } @Test public void testDisallowToastsFromSuspendedPackages() throws Exception { final String testPackage = "testPackageName"; Loading @@ -6981,6 +7005,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // enqueue toast -> no toasts enqueued enqueueToast(testPackage, new TestableToastCallback()); verify(mStatusBar, never()).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); assertEquals(0, mService.mToastQueue.size()); } Loading Loading @@ -10804,6 +10830,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mUm.isVisibleBackgroundUsersSupported()).thenReturn(supported); } private void mockIsUserVisible(int displayId, boolean visible) { when(mUmInternal.isUserVisible(mUserId, displayId)).thenReturn(visible); } private void mockDisplayAssignedToUser(int displayId) { when(mUmInternal.getMainDisplayAssignedToUser(mUserId)).thenReturn(displayId); } Loading