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

Commit 874ef0d1 authored by Jan Tomljanovic's avatar Jan Tomljanovic
Browse files

Prevent process state uplift when toast is rendered by the systemUI.

Test: NotificationManagerServiceTest

Bug: b/128597705

Change-Id: I40272c54862e5c4524a4a4492b7144d2ac15e8b7
parent ba437e8a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -7280,12 +7280,12 @@ public class NotificationManagerService extends SystemService {

    @GuardedBy("mToastQueue")
    private void keepProcessAliveForToastIfNeededLocked(int pid) {
        int toastCount = 0; // toasts from this pid
        int toastCount = 0; // toasts from this pid, rendered by the app
        ArrayList<ToastRecord> list = mToastQueue;
        int n = list.size();
        for (int i = 0; i < n; i++) {
            ToastRecord r = list.get(i);
            if (r.pid == pid) {
            if (r.pid == pid && r.keepProcessAlive()) {
                toastCount++;
            }
        }
+7 −0
Original line number Diff line number Diff line
@@ -70,6 +70,13 @@ public class CustomToastRecord extends ToastRecord {
        }
    }

    @Override
    public boolean keepProcessAlive() {
        // As custom toasts are rendered by the app, we need to keep the app alive for it to show
        // the toast.
        return true;
    }

    @Override
    public String toString() {
        return "CustomToastRecord{"
+10 −0
Original line number Diff line number Diff line
@@ -85,4 +85,14 @@ public abstract class ToastRecord {
        }
        pw.println(prefix + this);
    }

    /**
     * Returns whether it's necessary to bump the process state to keep it alive in order to show
     * the toast.
     */
    public boolean keepProcessAlive() {
        // By default we assume the toast is rendered by the systemUI. Any toast rendered by the app
        // should override this method.
        return false;
    }
}
+64 −1
Original line number Diff line number Diff line
@@ -178,7 +178,6 @@ import com.android.server.wm.WindowManagerInternal;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -4834,6 +4833,70 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertEquals(1, mService.mToastQueue.size());
    }

    @Test
    public void backgroundSystemCustomToast_callsSetProcessImportantAsForegroundForToast() throws
            Exception {
        final String testPackage = "testPackageName";
        assertEquals(0, mService.mToastQueue.size());
        mService.isSystemUid = true;

        // package is not suspended
        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
                .thenReturn(false);

        // notifications from this package are blocked by the user
        mService.setPreferencesHelper(mPreferencesHelper);
        when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);

        setAppInForegroundForToasts(mUid, false);

        // enqueue toast -> toast should still enqueue
        ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(),
                new TestableToastCallback(), 2000, 0);
        assertEquals(1, mService.mToastQueue.size());
        verify(mAm).setProcessImportant(any(), anyInt(), eq(true), any());
    }

    @Test
    public void foregroundTextToast_callsSetProcessImportantAsNotForegroundForToast() throws
            Exception {
        final String testPackage = "testPackageName";
        assertEquals(0, mService.mToastQueue.size());
        mService.isSystemUid = false;

        // package is not suspended
        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
                .thenReturn(false);

        setAppInForegroundForToasts(mUid, true);

        // enqueue toast -> toast should still enqueue
        ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(),
                "Text", 2000, 0, null);
        assertEquals(1, mService.mToastQueue.size());
        verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any());
    }

    @Test
    public void backgroundTextToast_callsSetProcessImportantAsNotForegroundForToast() throws
            Exception {
        final String testPackage = "testPackageName";
        assertEquals(0, mService.mToastQueue.size());
        mService.isSystemUid = false;

        // package is not suspended
        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
                .thenReturn(false);

        setAppInForegroundForToasts(mUid, false);

        // enqueue toast -> toast should still enqueue
        ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(),
                "Text", 2000, 0, null);
        assertEquals(1, mService.mToastQueue.size());
        verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any());
    }

    @Test
    public void testTextToastsCallStatusBar() throws Exception {
        final String testPackage = "testPackageName";