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

Commit 7a34ad9d authored by Julia Reynolds's avatar Julia Reynolds Committed by Android Build Coastguard Worker
Browse files

Filter notification APIs by user

Specifically getActiveNotifications and
getHistoricalNotifications

Test: atest NotificationManagerServiceTest
Bug: 214999128
Change-Id: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
Merged-In: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
(cherry picked from commit 4d7ca1db)
Merged-In: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
parent 3cb82491
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -504,16 +504,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()]);
        }

    }
@@ -2983,21 +2994,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()]);
        }

        /**
@@ -3093,7 +3114,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
@@ -372,6 +372,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");
@@ -476,6 +477,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) {
@@ -5177,4 +5190,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");
            }
        }
    }
}