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

Commit 27684159 authored by Geoffrey Pitsch's avatar Geoffrey Pitsch
Browse files

Fix cancel when the same notification is enqueued twice.

Change-Id: I6563c70ac441ff1c1951d5220c2e6a7c5f210d49
Fixes: 37706685
Test: runtest systemui-notification
parent 030107f0
Loading
Loading
Loading
Loading
+21 −16
Original line number Diff line number Diff line
@@ -1477,7 +1477,7 @@ public class NotificationManagerService extends SystemService {
                return ;
            }

            final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg));
            final boolean isSystemToast = isCallerSystemOrPhone() || ("android".equals(pkg));
            final boolean isPackageSuspended =
                    isPackageSuspendedForUser(pkg, Binder.getCallingUid());

@@ -1581,12 +1581,10 @@ public class NotificationManagerService extends SystemService {
                    Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
            // Don't allow client applications to cancel foreground service notis or autobundled
            // summaries.
            final int mustNotHaveFlags = isCallingUidSystem() ? 0 :
                    (Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTOGROUP_SUMMARY);
            cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
                    (Binder.getCallingUid() == Process.SYSTEM_UID
                            ? 0 : Notification.FLAG_FOREGROUND_SERVICE)
                            | (Binder.getCallingUid() == Process.SYSTEM_UID
                            ? 0 : Notification.FLAG_AUTOGROUP_SUMMARY), false, userId,
                    REASON_APP_CANCEL, null);
                    mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null);
        }

        @Override
@@ -2452,7 +2450,7 @@ public class NotificationManagerService extends SystemService {
        }

        private void enforceSystemOrSystemUI(String message) {
            if (isCallerSystem()) return;
            if (isCallerSystemOrPhone()) return;
            getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
                    message);
        }
@@ -3276,7 +3274,7 @@ public class NotificationManagerService extends SystemService {

    private int resolveNotificationUid(String opPackageName, int callingUid, int userId) {
        // The system can post notifications on behalf of any package it wants
        if (isCallerSystem() && opPackageName != null && !"android".equals(opPackageName)) {
        if (isCallerSystemOrPhone() && opPackageName != null && !"android".equals(opPackageName)) {
            try {
                return getContext().getPackageManager()
                        .getPackageUidAsUser(opPackageName, userId);
@@ -3295,7 +3293,8 @@ public class NotificationManagerService extends SystemService {
    private boolean checkDisqualifyingFeatures(int userId, int callingUid, int id, String tag,
            NotificationRecord r) {
        final String pkg = r.sbn.getPackageName();
        final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
        final boolean isSystemNotification =
                isUidSystemOrPhone(callingUid) || ("android".equals(pkg));
        final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);

        // Limit the number of notifications that any given package except the android
@@ -4192,7 +4191,7 @@ public class NotificationManagerService extends SystemService {
            mNotificationsByKey.remove(recordInList.sbn.getKey());
            wasPosted = true;
        }
        if ((recordInList = findNotificationByListLocked(mEnqueuedNotifications, r.getKey()))
        while ((recordInList = findNotificationByListLocked(mEnqueuedNotifications, r.getKey()))
                != null) {
            mEnqueuedNotifications.remove(recordInList);
        }
@@ -4686,24 +4685,30 @@ public class NotificationManagerService extends SystemService {
        }
    }

    protected boolean isUidSystem(int uid) {
    protected boolean isCallingUidSystem() {
        final int uid = Binder.getCallingUid();
        return uid == Process.SYSTEM_UID;
    }

    protected boolean isUidSystemOrPhone(int uid) {
        final int appid = UserHandle.getAppId(uid);
        return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0);
    }

    protected boolean isCallerSystem() {
        return isUidSystem(Binder.getCallingUid());
    // TODO: Most calls should probably move to isCallerSystem.
    protected boolean isCallerSystemOrPhone() {
        return isUidSystemOrPhone(Binder.getCallingUid());
    }

    private void checkCallerIsSystem() {
        if (isCallerSystem()) {
        if (isCallerSystemOrPhone()) {
            return;
        }
        throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid());
    }

    private void checkCallerIsSystemOrSameApp(String pkg) {
        if (isCallerSystem()) {
        if (isCallerSystemOrPhone()) {
            return;
        }
        checkCallerIsSameApp(pkg);
@@ -4711,7 +4716,7 @@ public class NotificationManagerService extends SystemService {

    private boolean isCallerInstantApp(String pkg) {
        // System is always allowed to act for ephemeral apps.
        if (isCallerSystem()) {
        if (isCallerSystemOrPhone()) {
            return false;
        }

+21 −2
Original line number Diff line number Diff line
@@ -104,7 +104,12 @@ public class NotificationManagerServiceTest {
        public TestableNotificationManagerService(Context context) { super(context); }

        @Override
        protected boolean isCallerSystem() {
        protected boolean isCallingUidSystem() {
            return true;
        }

        @Override
        protected boolean isCallerSystemOrPhone() {
            return true;
        }

@@ -410,6 +415,21 @@ public class NotificationManagerServiceTest {
        assertEquals(0, notifs[0].getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE);
    }

    @Test
    public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
        sbn.getNotification().flags =
                Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;
        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                sbn.getId(), sbn.getNotification(), sbn.getUserId());
        sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                sbn.getId(), sbn.getNotification(), sbn.getUserId());
        mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
        waitForIdle();
        assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    }

    @Test
    public void testFindGroupNotificationsLocked() throws Exception {
        // make sure the same notification can be found in both lists and returned
@@ -449,7 +469,6 @@ public class NotificationManagerServiceTest {
        }
    }


    @Test
    public void testTvExtenderChannelOverride_onTv() throws Exception {
        mNotificationManagerService.setIsTelevision(true);