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

Commit d5e1a8da authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Check permission when posting notification"

parents 6a914a39 4e968666
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));
    }
}