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

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

Filter notification APIs by user

Specifically getActiveNotifications and
getHistoricalNotifications

Test: atest NotificationManagerServiceTest
Bug: 214999128
Change-Id: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
Merged-In: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
parent 6a4864ee
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -509,16 +509,27 @@ public class NotificationManagerService extends SystemService {
            return mBuffer.descendingIterator();
        }

        public StatusBarNotification[] getArray(int count) {

        public StatusBarNotification[] getArray(UserManager um, int count) {
            ArrayList<Integer> currentUsers = new ArrayList<>();
            currentUsers.add(UserHandle.USER_ALL);
            Binder.withCleanCallingIdentity(() -> {
                for (int user : um.getProfileIds(ActivityManager.getCurrentUser(), false)) {
                    currentUsers.add(user);
                }
            });
            if (count == 0) count = mBufferSize;
            final StatusBarNotification[] a
                    = new StatusBarNotification[Math.min(count, mBuffer.size())];
            List<StatusBarNotification> a = new ArrayList();
            Iterator<StatusBarNotification> iter = descendingIterator();
            int i=0;
            while (iter.hasNext() && i < count) {
                a[i++] = iter.next();
                StatusBarNotification sbn = iter.next();
                if (currentUsers.contains(sbn.getUserId())) {
                    i++;
                    a.add(sbn);
                }
            }
            return a;
            return a.toArray(new StatusBarNotification[a.size()]);
        }

    }
@@ -3001,21 +3012,31 @@ public class NotificationManagerService extends SystemService {
                    android.Manifest.permission.ACCESS_NOTIFICATIONS,
                    "NotificationManagerService.getActiveNotifications");

            StatusBarNotification[] tmp = null;
            ArrayList<StatusBarNotification> tmp = new ArrayList<>();
            int uid = Binder.getCallingUid();

            ArrayList<Integer> currentUsers = new ArrayList<>();
            currentUsers.add(UserHandle.USER_ALL);
            Binder.withCleanCallingIdentity(() -> {
                for (int user : mUm.getProfileIds(ActivityManager.getCurrentUser(), false)) {
                    currentUsers.add(user);
                }
            });

            // noteOp will check to make sure the callingPkg matches the uid
            if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg)
                    == AppOpsManager.MODE_ALLOWED) {
                synchronized (mNotificationLock) {
                    tmp = new StatusBarNotification[mNotificationList.size()];
                    final int N = mNotificationList.size();
                    for (int i = 0; i < N; i++) {
                        tmp[i] = mNotificationList.get(i).sbn;
                        final StatusBarNotification sbn = mNotificationList.get(i).sbn;
                        if (currentUsers.contains(sbn.getUserId())) {
                            tmp.add(sbn);
                        }
                    }
                }
            return tmp;
            }
            return tmp.toArray(new StatusBarNotification[tmp.size()]);
        }

        /**
@@ -3111,7 +3132,7 @@ public class NotificationManagerService extends SystemService {
            if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg)
                    == AppOpsManager.MODE_ALLOWED) {
                synchronized (mArchive) {
                    tmp = mArchive.getArray(count);
                    tmp = mArchive.getArray(mUm, count);
                }
            }
            return tmp;
+42 −0
Original line number Diff line number Diff line
@@ -394,6 +394,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
        when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
        mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
        when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});

        // write to a test file; the system file isn't readable from tests
        mFile = new File(mContext.getCacheDir(), "test.xml");
@@ -498,6 +499,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        return generateNotificationRecord(channel, extender, false /* isBubble */);
    }

    private NotificationRecord generateNotificationRecord(NotificationChannel channel, int userId) {
        if (channel == null) {
            channel = mTestNotificationChannel;
        }
        Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
                .setContentTitle("foo")
                .setSmallIcon(android.R.drawable.sym_def_app_icon);
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
                nb.build(), new UserHandle(userId), null, 0);
        return new NotificationRecord(mContext, sbn, channel);
    }

    private NotificationRecord generateNotificationRecord(NotificationChannel channel,
            Notification.TvExtender extender, boolean isBubble) {
        if (channel == null) {
@@ -5342,4 +5355,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertEquals(1, notifsAfter.length);
        assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
    }

    @Test
    public void testGetActiveNotification_filtersUsers() throws Exception {
        when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0, 10});

        NotificationRecord nr0 =
                generateNotificationRecord(mTestNotificationChannel, 0);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
                nr0.sbn.getId(), nr0.sbn.getNotification(), nr0.sbn.getUserId());

        NotificationRecord nr10 =
                generateNotificationRecord(mTestNotificationChannel, 10);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag10",
                nr10.sbn.getId(), nr10.sbn.getNotification(), nr10.sbn.getUserId());

        NotificationRecord nr11 =
                generateNotificationRecord(mTestNotificationChannel, 11);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag11",
                nr11.sbn.getId(), nr11.sbn.getNotification(), nr11.sbn.getUserId());
        waitForIdle();

        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
        assertEquals(2, notifs.length);
        for (StatusBarNotification sbn : notifs) {
            if (sbn.getUserId() == 11) {
                fail("leaked data across users");
            }
        }
    }
}