summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java79
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java56
2 files changed, 74 insertions, 61 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2f4cbd558fb9..e7db3f09578e 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -378,8 +378,6 @@ public class NotificationManagerService extends SystemService {
static final int INVALID_UID = -1;
static final String ROOT_PKG = "root";
- static final boolean ENABLE_BLOCKED_TOASTS = true;
-
static final String[] DEFAULT_ALLOWED_ADJUSTMENTS = new String[] {
Adjustment.KEY_CONTEXTUAL_ACTIONS,
Adjustment.KEY_TEXT_REPLIES,
@@ -3035,34 +3033,11 @@ public class NotificationManagerService extends SystemService {
}
final int callingUid = Binder.getCallingUid();
- final UserHandle callingUser = Binder.getCallingUserHandle();
+ checkCallerIsSameApp(pkg);
final boolean isSystemToast = isCallerSystemOrPhone()
|| PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg);
- final boolean isPackageSuspended = isPackagePaused(pkg);
- final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg,
- callingUid);
-
- final boolean appIsForeground;
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- appIsForeground = mActivityManager.getUidImportance(callingUid)
- == IMPORTANCE_FOREGROUND;
- } finally {
- Binder.restoreCallingIdentity(callingIdentity);
- }
-
- if (ENABLE_BLOCKED_TOASTS && !isSystemToast && ((notificationsDisabledForPackage
- && !appIsForeground) || isPackageSuspended)) {
- Slog.e(TAG, "Suppressing toast from package " + pkg
- + (isPackageSuspended ? " due to package suspended."
- : " by user request."));
- return;
- }
-
boolean isAppRenderedToast = (callback != null);
- if (blockToast(callingUid, isSystemToast, isAppRenderedToast)) {
- Slog.w(TAG, "Blocking custom toast from package " + pkg
- + " due to package not in the foreground at time the toast was posted");
+ if (!checkCanEnqueueToast(pkg, callingUid, isAppRenderedToast, isSystemToast)) {
return;
}
@@ -3116,6 +3091,39 @@ public class NotificationManagerService extends SystemService {
}
}
+ private boolean checkCanEnqueueToast(String pkg, int callingUid,
+ boolean isAppRenderedToast, boolean isSystemToast) {
+ final boolean isPackageSuspended = isPackagePaused(pkg);
+ final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg,
+ callingUid);
+
+ final boolean appIsForeground;
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ appIsForeground = mActivityManager.getUidImportance(callingUid)
+ == IMPORTANCE_FOREGROUND;
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+
+ if (!isSystemToast && ((notificationsDisabledForPackage && !appIsForeground)
+ || isPackageSuspended)) {
+ Slog.e(TAG, "Suppressing toast from package " + pkg
+ + (isPackageSuspended ? " due to package suspended."
+ : " by user request."));
+ return false;
+ }
+
+ if (blockToast(callingUid, isSystemToast, isAppRenderedToast,
+ isPackageInForegroundForToast(callingUid))) {
+ Slog.w(TAG, "Blocking custom toast from package " + pkg
+ + " due to package not in the foreground at time the toast was posted");
+ return false;
+ }
+
+ return true;
+ }
+
@Override
public void cancelToast(String pkg, IBinder token) {
Slog.i(TAG, "cancelToast pkg=" + pkg + " token=" + token);
@@ -7540,12 +7548,13 @@ public class NotificationManagerService extends SystemService {
boolean isWithinQuota =
mToastRateLimiter.isWithinQuota(userId, record.pkg, TOAST_QUOTA_TAG)
|| isExemptFromRateLimiting(record.pkg, userId);
+ boolean isPackageInForeground = isPackageInForegroundForToast(record.uid);
if (tryShowToast(
- record, rateLimitingEnabled, isWithinQuota)) {
+ record, rateLimitingEnabled, isWithinQuota, isPackageInForeground)) {
scheduleDurationReachedLocked(record, lastToastWasTextRecord);
mIsCurrentToastShown = true;
- if (rateLimitingEnabled) {
+ if (rateLimitingEnabled && !isPackageInForeground) {
mToastRateLimiter.noteEvent(userId, record.pkg, TOAST_QUOTA_TAG);
}
return;
@@ -7561,14 +7570,15 @@ public class NotificationManagerService extends SystemService {
/** Returns true if it successfully showed the toast. */
private boolean tryShowToast(ToastRecord record, boolean rateLimitingEnabled,
- boolean isWithinQuota) {
- if (rateLimitingEnabled && !isWithinQuota) {
+ boolean isWithinQuota, boolean isPackageInForeground) {
+ if (rateLimitingEnabled && !isWithinQuota && !isPackageInForeground) {
reportCompatRateLimitingToastsChange(record.uid);
Slog.w(TAG, "Package " + record.pkg + " is above allowed toast quota, the "
+ "following toast was blocked and discarded: " + record);
return false;
}
- if (blockToast(record.uid, record.isSystemToast, record.isAppRendered())) {
+ if (blockToast(record.uid, record.isSystemToast, record.isAppRendered(),
+ isPackageInForeground)) {
Slog.w(TAG, "Blocking custom toast from package " + record.pkg
+ " due to package not in the foreground at the time of showing the toast");
return false;
@@ -7759,10 +7769,11 @@ public class NotificationManagerService extends SystemService {
* with targetSdk < R. For apps with targetSdk R+, text toasts are not app-rendered, so
* isAppRenderedToast == true means it's a custom toast.
*/
- private boolean blockToast(int uid, boolean isSystemToast, boolean isAppRenderedToast) {
+ private boolean blockToast(int uid, boolean isSystemToast, boolean isAppRenderedToast,
+ boolean isPackageInForeground) {
return isAppRenderedToast
&& !isSystemToast
- && !isPackageInForegroundForToast(uid)
+ && !isPackageInForeground
&& CompatChanges.isChangeEnabled(CHANGE_BACKGROUND_CUSTOM_TOAST_BLOCK, uid);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 8be19f002fa5..91d7430a7077 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -58,7 +58,6 @@ import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
-import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
@@ -5037,7 +5036,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testToastRateLimiterCanPreventShowCallForCustomToast() throws Exception {
+ public void testToastRateLimiterWontPreventShowCallForCustomToastWhenInForeground()
+ throws Exception {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
@@ -5055,30 +5055,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
INotificationManager nmService = (INotificationManager) mService.mService;
nmService.enqueueToast(testPackage, token, callback, 2000, 0);
- verify(callback, times(0)).show(any());
- }
-
- @Test
- public void testCustomToastRateLimiterAllowsLimitAvoidanceWithPermission() throws Exception {
- final String testPackage = "testPackageName";
- assertEquals(0, mService.mToastQueue.size());
- mService.isSystemUid = false;
- setToastRateIsWithinQuota(false); // rate limit reached
- // Avoids rate limiting.
- setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, true);
-
- // package is not suspended
- when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
- .thenReturn(false);
-
- setAppInForegroundForToasts(mUid, true);
-
- Binder token = new Binder();
- ITransientNotification callback = mock(ITransientNotification.class);
- INotificationManager nmService = (INotificationManager) mService.mService;
-
- nmService.enqueueToast(testPackage, token, callback, 2000, 0);
- verify(callback).show(any());
+ verify(callback, times(1)).show(any());
}
@Test
@@ -5186,12 +5163,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testToastRateLimiterCanPreventShowCallForTextToast() throws Exception {
+ public void testToastRateLimiterCanPreventShowCallForTextToast_whenInBackground()
+ throws Exception {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
setToastRateIsWithinQuota(false); // rate limit reached
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
+ setAppInForegroundForToasts(mUid, false);
// package is not suspended
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5206,12 +5185,35 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testToastRateLimiterWontPreventShowCallForTextToast_whenInForeground()
+ throws Exception {
+ final String testPackage = "testPackageName";
+ assertEquals(0, mService.mToastQueue.size());
+ mService.isSystemUid = false;
+ setToastRateIsWithinQuota(false); // rate limit reached
+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
+ setAppInForegroundForToasts(mUid, true);
+
+ // package is not suspended
+ when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+ .thenReturn(false);
+
+ Binder token = new Binder();
+ INotificationManager nmService = (INotificationManager) mService.mService;
+
+ nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null);
+ verify(mStatusBar, times(1))
+ .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any());
+ }
+
+ @Test
public void testTextToastRateLimiterAllowsLimitAvoidanceWithPermission() throws Exception {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
setToastRateIsWithinQuota(false); // rate limit reached
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, true);
+ setAppInForegroundForToasts(mUid, false);
// package is not suspended
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))