Merge "Add permission for avoiding toast rate limiting." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2eb7e4f948
@@ -3443,6 +3443,14 @@
|
||||
<permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- Allows an application to avoid all toast rate limiting restrictions.
|
||||
<p>Not for use by third-party applications.
|
||||
@hide
|
||||
-->
|
||||
<permission android:name="android.permission.UNLIMITED_TOASTS"
|
||||
android:protectionLevel="signature" />
|
||||
<uses-permission android:name="android.permission.UNLIMITED_TOASTS" />
|
||||
|
||||
<!-- @SystemApi Allows an application to use
|
||||
{@link android.view.WindowManager.LayoutsParams#SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS}
|
||||
to hide non-system-overlay windows.
|
||||
|
||||
@@ -437,6 +437,9 @@
|
||||
<!-- Permission required for CTS test - ResourceObserverNativeTest -->
|
||||
<uses-permission android:name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" />
|
||||
|
||||
<!-- Permission required for CTS test - android.widget.cts.ToastTest -->
|
||||
<uses-permission android:name="android.permission.UNLIMITED_TOASTS" />
|
||||
|
||||
<application android:label="@string/app_label"
|
||||
android:theme="@android:style/Theme.DeviceDefault.DayNight"
|
||||
android:defaultToDeviceProtectedStorage="true"
|
||||
|
||||
@@ -7490,9 +7490,11 @@ public class NotificationManagerService extends SystemService {
|
||||
boolean rateLimitingEnabled =
|
||||
!mToastRateLimitingDisabledUids.contains(record.uid);
|
||||
boolean isWithinQuota =
|
||||
mToastRateLimiter.isWithinQuota(userId, record.pkg, TOAST_QUOTA_TAG);
|
||||
mToastRateLimiter.isWithinQuota(userId, record.pkg, TOAST_QUOTA_TAG)
|
||||
|| isExemptFromRateLimiting(record.pkg, userId);
|
||||
|
||||
if (tryShowToast(record, rateLimitingEnabled, isWithinQuota)) {
|
||||
if (tryShowToast(
|
||||
record, rateLimitingEnabled, isWithinQuota)) {
|
||||
scheduleDurationReachedLocked(record, lastToastWasTextRecord);
|
||||
mIsCurrentToastShown = true;
|
||||
if (rateLimitingEnabled) {
|
||||
@@ -7526,6 +7528,18 @@ public class NotificationManagerService extends SystemService {
|
||||
return record.show();
|
||||
}
|
||||
|
||||
private boolean isExemptFromRateLimiting(String pkg, int userId) {
|
||||
boolean isExemptFromRateLimiting = false;
|
||||
try {
|
||||
isExemptFromRateLimiting = mPackageManager.checkPermission(
|
||||
android.Manifest.permission.UNLIMITED_TOASTS, pkg, userId)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to connect with package manager");
|
||||
}
|
||||
return isExemptFromRateLimiting;
|
||||
}
|
||||
|
||||
/** Reports rate limiting toasts compat change (used when the toast was blocked). */
|
||||
private void reportCompatRateLimitingToastsChange(int uid) {
|
||||
final long id = Binder.clearCallingIdentity();
|
||||
|
||||
@@ -4910,6 +4910,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -4933,6 +4934,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -4952,6 +4954,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -4974,11 +4977,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToastRateLimiterCanPreventsShowCallForCustomToast() throws Exception {
|
||||
public void testToastRateLimiterCanPreventShowCallForCustomToast() throws Exception {
|
||||
final String testPackage = "testPackageName";
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(false); // rate limit reached
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -4994,6 +4998,29 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomToastPostedWhileInForeground_blockedIfAppGoesToBackground()
|
||||
throws Exception {
|
||||
@@ -5001,6 +5028,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5034,6 +5062,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5053,6 +5082,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5072,6 +5102,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5095,11 +5126,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToastRateLimiterCanPreventsShowCallForTextToast() throws Exception {
|
||||
public void testToastRateLimiterCanPreventShowCallForTextToast() throws Exception {
|
||||
final String testPackage = "testPackageName";
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(false); // rate limit reached
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5113,6 +5145,25 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
.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);
|
||||
|
||||
// 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).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void backgroundSystemCustomToast_callsSetProcessImportantAsForegroundForToast() throws
|
||||
Exception {
|
||||
@@ -5120,6 +5171,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = true;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5145,6 +5197,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5166,6 +5219,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5186,6 +5240,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5203,6 +5258,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5224,6 +5280,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5247,6 +5304,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = true;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5270,6 +5328,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(0, mService.mToastQueue.size());
|
||||
mService.isSystemUid = false;
|
||||
setToastRateIsWithinQuota(true);
|
||||
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
|
||||
|
||||
// package is not suspended
|
||||
when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
|
||||
@@ -5305,6 +5364,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
.thenReturn(isWithinQuota);
|
||||
}
|
||||
|
||||
private void setIfPackageHasPermissionToAvoidToastRateLimiting(
|
||||
String pkg, boolean hasPermission) throws Exception {
|
||||
when(mPackageManager.checkPermission(android.Manifest.permission.UNLIMITED_TOASTS,
|
||||
pkg, UserHandle.getUserId(mUid)))
|
||||
.thenReturn(hasPermission ? PERMISSION_GRANTED : PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPanelRevealedAndHidden() {
|
||||
int items = 5;
|
||||
|
||||
Reference in New Issue
Block a user