Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af5fcacd authored by Valentin Iftime's avatar Valentin Iftime
Browse files

Prioritize system toasts

 Insert toasts from system packages at the front of the queue
  to ensure that apps can't spam with toast to delay system toasts from showing.
 Also increase Clipboard paste warning toasts length to LENGTH_LONG.

Test: atest NotificationManagerServiceTest
Bug: 293301736

Change-Id: I13547f853476bc88d12026c545aba9f857ce8724
parent 15c2cf07
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1474,11 +1474,11 @@ public class ClipboardService extends SystemService {
                                .getDrawable(R.drawable.ic_safety_protection);
                        toastToShow = Toast.makeCustomToastWithIcon(toastContext,
                                UiThread.get().getLooper(), message,
                                Toast.LENGTH_SHORT, safetyProtectionIcon);
                                Toast.LENGTH_LONG, safetyProtectionIcon);
                    } else {
                        toastToShow = Toast.makeText(
                                toastContext, UiThread.get().getLooper(), message,
                                Toast.LENGTH_SHORT);
                                Toast.LENGTH_LONG);
                    }
                    toastToShow.show();
                }
+30 −2
Original line number Diff line number Diff line
@@ -3500,8 +3500,19 @@ public class NotificationManagerService extends SystemService {
                                null /* options */);
                        record = getToastRecord(callingUid, callingPid, pkg, isSystemToast, token,
                                text, callback, duration, windowToken, displayId, textCallback);
                        // Insert system toasts at the front of the queue
                        int systemToastInsertIdx = mToastQueue.size();
                        if (isSystemToast) {
                            systemToastInsertIdx = getInsertIndexForSystemToastLocked();
                        }
                        if (systemToastInsertIdx < mToastQueue.size()) {
                            index = systemToastInsertIdx;
                            mToastQueue.add(index, record);
                        } else {
                            mToastQueue.add(record);
                            index = mToastQueue.size() - 1;
                        }
                        keepProcessAliveForToastIfNeededLocked(callingPid);
                    }
                    // If it's at index 0, it's the current toast.  It doesn't matter if it's
@@ -3517,6 +3528,23 @@ public class NotificationManagerService extends SystemService {
            }
        }
        @GuardedBy("mToastQueue")
        private int getInsertIndexForSystemToastLocked() {
            // If there are other system toasts: insert after the last one
            int idx = 0;
            for (ToastRecord r : mToastQueue) {
                if (idx == 0 && mIsCurrentToastShown) {
                    idx++;
                    continue;
                }
                if (!r.isSystemToast) {
                    return idx;
                }
                idx++;
            }
            return idx;
        }
        private boolean checkCanEnqueueToast(String pkg, int callingUid, int displayId,
                boolean isAppRenderedToast, boolean isSystemToast) {
            final boolean isPackageSuspended = isPackagePaused(pkg);
+68 −0
Original line number Diff line number Diff line
@@ -7769,6 +7769,74 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size());
    }
    @Test
    public void testPrioritizeSystemToasts() throws Exception {
        // Insert non-system toasts
        final String testPackage = "testPackageName";
        assertEquals(0, mService.mToastQueue.size());
        mService.isSystemUid = false;
        mService.isSystemAppId = false;
        setToastRateIsWithinQuota(true);
        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
        // package is not suspended
        when(mPackageManager.isPackageSuspendedForUser(testPackage, mUserId))
                .thenReturn(false);
        INotificationManager nmService = (INotificationManager) mService.mService;
        // Enqueue maximum number of toasts for test package
        for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS; i++) {
            enqueueTextToast(testPackage, "Text");
        }
        // Enqueue system toast
        final String testPackageSystem = "testPackageNameSystem";
        mService.isSystemUid = true;
        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem, false);
        when(mPackageManager.isPackageSuspendedForUser(testPackageSystem, mUserId))
                .thenReturn(false);
        enqueueToast(testPackageSystem, new TestableToastCallback());
        // System toast is inserted at the front of the queue, behind current showing toast
        assertEquals(testPackageSystem, mService.mToastQueue.get(1).pkg);
    }
    @Test
    public void testPrioritizeSystemToasts_enqueueAfterExistingSystemToast() throws Exception {
        // Insert system toasts
        final String testPackageSystem1 = "testPackageNameSystem1";
        assertEquals(0, mService.mToastQueue.size());
        mService.isSystemUid = true;
        setToastRateIsWithinQuota(true);
        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem1, false);
        // package is not suspended
        when(mPackageManager.isPackageSuspendedForUser(testPackageSystem1, mUserId))
                .thenReturn(false);
        INotificationManager nmService = (INotificationManager) mService.mService;
        // Enqueue maximum number of toasts for test package
        for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS; i++) {
            enqueueTextToast(testPackageSystem1, "Text");
        }
        // Enqueue another system toast
        final String testPackageSystem2 = "testPackageNameSystem2";
        mService.isSystemUid = true;
        setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem2, false);
        when(mPackageManager.isPackageSuspendedForUser(testPackageSystem2, mUserId))
                .thenReturn(false);
        enqueueToast(testPackageSystem2, new TestableToastCallback());
        // System toast is inserted at the back of the queue, after the other system toasts
        assertEquals(testPackageSystem2,
                mService.mToastQueue.get(mService.mToastQueue.size() - 1).pkg);
    }
    private void setAppInForegroundForToasts(int uid, boolean inForeground) {
        int importance = (inForeground) ? IMPORTANCE_FOREGROUND : IMPORTANCE_NONE;
        when(mActivityManager.getUidImportance(mUid)).thenReturn(importance);