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

Commit 4e968666 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Check permission when posting notification

Test: atest FrameworksUiServicesTests, core tests
Bug: 194833441
Change-Id: I77816addeec483f645ac4bb8d8552e8853aaf633
parent 84c44400
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -139,6 +139,33 @@ public class StatusBarNotification implements Parcelable {
        this.groupKey = groupKey();
    }

    /**
     * @hide
     */
    public static int getUidFromKey(@NonNull String key) {
        String[] parts = key.split("\\|");
        if (parts.length >= 5) {
            try {
                int uid = Integer.parseInt(parts[4]);
                return uid;
            } catch (NumberFormatException e) {
                return -1;
            }
        }
        return -1;
    }

    /**
     * @hide
     */
    public static String getPkgFromKey(@NonNull String key) {
        String[] parts = key.split("\\|");
        if (parts.length >= 2) {
            return parts[1];
        }
        return null;
    }

    private String key() {
        String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
        if (overrideGroupKey != null && getNotification().isGroupSummary()) {
+23 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static junit.framework.Assert.assertNull;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@@ -54,6 +55,7 @@ public class StatusBarNotificationTest {
    private final Context mMockContext = mock(Context.class);
    @Mock
    private Context mRealContext;
    @Mock
    private PackageManager mPm;

    private static final String PKG = "com.example.o";
@@ -78,6 +80,7 @@ public class StatusBarNotificationTest {
                InstrumentationRegistry.getContext().getResources());
        when(mMockContext.getPackageManager()).thenReturn(mPm);
        when(mMockContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
        when(mPm.getApplicationLabel(any())).thenReturn("");

        mRealContext = InstrumentationRegistry.getContext();
    }
@@ -217,6 +220,26 @@ public class StatusBarNotificationTest {
        assertEquals(pkg, resultContext.getPackageName());
    }

    @Test
    public void testGetUidFromKey() {
        StatusBarNotification sbn = getNotification("pkg", null, "channel");

        assertEquals(UID, StatusBarNotification.getUidFromKey(sbn.getKey()));

        sbn.setOverrideGroupKey("addsToKey");
        assertEquals(UID, StatusBarNotification.getUidFromKey(sbn.getKey()));
    }

    @Test
    public void testGetPkgFromKey() {
        StatusBarNotification sbn = getNotification("pkg", null, "channel");

        assertEquals("pkg", StatusBarNotification.getPkgFromKey(sbn.getKey()));

        sbn.setOverrideGroupKey("addsToKey");
        assertEquals("pkg", StatusBarNotification.getPkgFromKey(sbn.getKey()));
    }

    private StatusBarNotification getNotification(String pkg, String group, String channelId) {
        return getNotification(pkg, getNotificationBuilder(group, channelId));
    }
+33 −23
Original line number Diff line number Diff line
@@ -3544,11 +3544,7 @@ public class NotificationManagerService extends SystemService {
                        "canNotifyAsPackage for uid " + uid);
            }

            if (mEnableAppSettingMigration) {
                return mPermissionHelper.hasPermission(uid);
            } else {
                return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
            }
            return areNotificationsEnabledForPackageInt(pkg, uid);
        }

        /**
@@ -6732,13 +6728,30 @@ public class NotificationManagerService extends SystemService {


        // blocked apps
        if (isBlocked(r, mUsageStats)) {
        boolean isBlocked = !areNotificationsEnabledForPackageInt(pkg, uid);
        synchronized (mNotificationLock) {
            isBlocked |= isRecordBlockedLocked(r);
        }
        if (isBlocked) {
            if (DBG) {
                Slog.e(TAG, "Suppressing notification from package " + r.getSbn().getPackageName()
                        + " by user request.");
            }
            mUsageStats.registerBlocked(r);
            return false;
        }

        return true;
    }

    private boolean areNotificationsEnabledForPackageInt(String pkg, int uid) {
        if (mEnableAppSettingMigration) {
            return mPermissionHelper.hasPermission(uid);
        } else {
            return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
        }
    }

    protected int getNotificationCount(String pkg, int userId, int excludedId,
            String excludedTag) {
        int count = 0;
@@ -6767,24 +6780,15 @@ public class NotificationManagerService extends SystemService {
        return count;
    }

    protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
        if (isBlocked(r)) {
            if (DBG) {
                Slog.e(TAG, "Suppressing notification from package " + r.getSbn().getPackageName()
                        + " by user request.");
            }
            usageStats.registerBlocked(r);
            return true;
        }
        return false;
    }

    private boolean isBlocked(NotificationRecord r) {
    /**
     * Checks whether a notification is banned at a group or channel level or if the NAS or system
     * has blocked the notification.
     */
    @GuardedBy("mNotificationLock")
    boolean isRecordBlockedLocked(NotificationRecord r) {
        final String pkg = r.getSbn().getPackageName();
        final int callingUid = r.getSbn().getUid();
        return mPreferencesHelper.isGroupBlocked(pkg, callingUid, r.getChannel().getGroup())
                || mPreferencesHelper.getImportance(pkg, callingUid)
                == NotificationManager.IMPORTANCE_NONE
                || r.getImportance() == NotificationManager.IMPORTANCE_NONE;
    }

@@ -7095,6 +7099,9 @@ public class NotificationManagerService extends SystemService {

        @Override
        public void run() {
            String pkg = StatusBarNotification.getPkgFromKey(key);
            int uid = StatusBarNotification.getUidFromKey(key);
            boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
            synchronized (mNotificationLock) {
                try {
                    NotificationRecord r = null;
@@ -7111,8 +7118,11 @@ public class NotificationManagerService extends SystemService {
                        return;
                    }

                    if (isBlocked(r)) {
                        Slog.i(TAG, "notification blocked by assistant request");
                    if (appBanned || isRecordBlockedLocked(r)) {
                        mUsageStats.registerBlocked(r);
                        if (DBG) {
                            Slog.e(TAG, "Suppressing notification from package " + pkg);
                        }
                        return;
                    }

+37 −6
Original line number Diff line number Diff line
@@ -182,7 +182,6 @@ import android.util.TypedXmlSerializer;
import android.util.Xml;
import android.widget.RemoteViews;

import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;

import com.android.internal.app.IAppOpsService;
@@ -1040,7 +1039,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        NotificationRecord r = generateNotificationRecord(channel);

        // isBlocked is only used for user blocking, not app suspension
        assertFalse(mService.isBlocked(r, mUsageStats));
        assertFalse(mService.isRecordBlockedLocked(r));
    }

    @Test
@@ -1050,8 +1049,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        NotificationChannel channel = new NotificationChannel("id", "name",
                NotificationManager.IMPORTANCE_NONE);
        NotificationRecord r = generateNotificationRecord(channel);
        assertTrue(mService.isBlocked(r, mUsageStats));
        verify(mUsageStats, times(1)).registerBlocked(eq(r));
        assertTrue(mService.isRecordBlockedLocked(r));

        mBinderService.createNotificationChannels(
                PKG, new ParceledListSlice(Arrays.asList(channel)));
@@ -1148,8 +1146,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                NotificationManager.IMPORTANCE_HIGH);
        channel.setGroup("something");
        NotificationRecord r = generateNotificationRecord(channel);
        assertTrue(mService.isBlocked(r, mUsageStats));
        verify(mUsageStats, times(1)).registerBlocked(eq(r));
        assertTrue(mService.isRecordBlockedLocked(r));
    }

    @Test
@@ -1286,6 +1283,40 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        verify(mUsageStats, never()).registerPostedByApp(any());
    }

    @Test
    public void testBlockedNotifications_blockedByUser() throws Exception {
        mService.setPreferencesHelper(mPreferencesHelper);
        when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);

        NotificationChannel channel = new NotificationChannel("id", "name",
                NotificationManager.IMPORTANCE_HIGH);
        NotificationRecord r = generateNotificationRecord(channel);
        mService.addEnqueuedNotification(r);

        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE);

        NotificationManagerService.PostNotificationRunnable runnable =
                mService.new PostNotificationRunnable(r.getKey());
        runnable.run();
        waitForIdle();

        verify(mUsageStats).registerBlocked(any());
        verify(mUsageStats, never()).registerPostedByApp(any());
    }

    @Test
    public void testEnqueueNotification_appBlocked() throws Exception {
        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);

        mBinderService.enqueueNotificationWithTag(PKG, PKG,
                "testEnqueueNotification_appBlocked", 0,
                generateNotificationRecord(null).getNotification(), 0);
        waitForIdle();
        verify(mWorkerHandler, never()).post(
                any(NotificationManagerService.EnqueueNotificationRunnable.class));
    }

    @Test
    public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+33 −0
Original line number Diff line number Diff line
@@ -630,4 +630,37 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase {
        verify(mPreferencesHelper, never()).getImportance(anyString(), anyInt());
        verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid);
    }

    @Test
    public void testBlockedNotifications_blockedByUser() throws Exception {
        when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);

        NotificationChannel channel = new NotificationChannel("id", "name",
                NotificationManager.IMPORTANCE_HIGH);
        NotificationRecord r = generateNotificationRecord(channel);
        mService.addEnqueuedNotification(r);

        when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);

        NotificationManagerService.PostNotificationRunnable runnable =
                mService.new PostNotificationRunnable(r.getKey());
        runnable.run();
        waitForIdle();

        verify(mUsageStats).registerBlocked(any());
        verify(mUsageStats, never()).registerPostedByApp(any());
    }

    @Test
    public void testEnqueueNotification_appBlocked() throws Exception {
        when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);

        mBinderService.enqueueNotificationWithTag(PKG, PKG,
                "testEnqueueNotification_appBlocked", 0,
                generateNotificationRecord(null).getNotification(), 0);
        waitForIdle();
        verify(mWorkerHandler, never()).post(
                any(NotificationManagerService.EnqueueNotificationRunnable.class));
    }
}