diff options
author | Julia Reynolds <juliacr@google.com> | 2022-02-11 17:08:58 -0500 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-07-07 01:46:04 +0000 |
commit | e8b88942a262672a0222b42f5e4205b99ff45b9c (patch) | |
tree | 95d3b8b26ea15b41cb71e4206207f8c679e66763 | |
parent | 8b4997b6d5b96d70ca129842cb303efe20b5761e (diff) | |
download | base-e8b88942a262672a0222b42f5e4205b99ff45b9c.tar.gz |
Filter notification APIs by user
Specifically getActiveNotifications and
getHistoricalNotifications
Test: atest NotificationManagerServiceTest
Bug: 214999128
Change-Id: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
Merged-In: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
(cherry picked from commit 73745b16e89b51dfe4328faa817ba50024382050)
Merged-In: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
3 files changed, 96 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 7590527bbf31..f3562d6cd87d 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -658,7 +658,14 @@ public class NotificationManagerService extends SystemService { return mBuffer.descendingIterator(); } - public StatusBarNotification[] getArray(int count, boolean includeSnoozed) { + public StatusBarNotification[] getArray(UserManager um, int count, boolean includeSnoozed) { + ArrayList<Integer> currentUsers = new ArrayList<>(); + currentUsers.add(UserHandle.USER_ALL); + Binder.withCleanCallingIdentity(() -> { + for (int user : um.getProfileIds(ActivityManager.getCurrentUser(), false)) { + currentUsers.add(user); + } + }); synchronized (mBufferLock) { if (count == 0) count = mBufferSize; List<StatusBarNotification> a = new ArrayList(); @@ -667,8 +674,10 @@ public class NotificationManagerService extends SystemService { while (iter.hasNext() && i < count) { Pair<StatusBarNotification, Integer> pair = iter.next(); if (pair.second != REASON_SNOOZED || includeSnoozed) { - i++; - a.add(pair.first); + if (currentUsers.contains(pair.first.getUserId())) { + i++; + a.add(pair.first); + } } } return a.toArray(new StatusBarNotification[a.size()]); @@ -4042,22 +4051,32 @@ 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, callingAttributionTag, null) == 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).getSbn(); + for (int i = 0; i < N; i++) { + final StatusBarNotification sbn = mNotificationList.get(i).getSbn(); + if (currentUsers.contains(sbn.getUserId())) { + tmp.add(sbn); + } } } } - return tmp; + return tmp.toArray(new StatusBarNotification[tmp.size()]); } /** @@ -4166,7 +4185,7 @@ public class NotificationManagerService extends SystemService { callingAttributionTag, null) == AppOpsManager.MODE_ALLOWED) { synchronized (mArchive) { - tmp = mArchive.getArray(count, includeSnoozed); + tmp = mArchive.getArray(mUm, count, includeSnoozed); } } return tmp; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java index 1126e1ece452..4b6183dc9ffa 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java @@ -15,16 +15,22 @@ */ package com.android.server.notification; +import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_CURRENT; +import static android.os.UserHandle.USER_NULL; import static android.os.UserHandle.USER_SYSTEM; import static android.service.notification.NotificationListenerService.REASON_CANCEL; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.when; import android.app.Notification; import android.os.UserHandle; +import android.os.UserManager; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; @@ -35,6 +41,7 @@ import com.android.server.UiServiceTestCase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; @@ -51,6 +58,8 @@ public class ArchiveTest extends UiServiceTestCase { private static final int SIZE = 5; private NotificationManagerService.Archive mArchive; + @Mock + private UserManager mUm; @Before public void setUp() { @@ -59,6 +68,9 @@ public class ArchiveTest extends UiServiceTestCase { mArchive = new NotificationManagerService.Archive(SIZE); mArchive.updateHistoryEnabled(USER_SYSTEM, true); mArchive.updateHistoryEnabled(USER_CURRENT, true); + + when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn( + new int[] {USER_CURRENT, USER_SYSTEM}); } private StatusBarNotification getNotification(String pkg, int id, UserHandle user) { @@ -70,7 +82,6 @@ public class ArchiveTest extends UiServiceTestCase { pkg, pkg, id, null, 0, 0, n, user, null, System.currentTimeMillis()); } - @Test public void testRecordAndRead() { List<String> expected = new ArrayList<>(); @@ -81,7 +92,7 @@ public class ArchiveTest extends UiServiceTestCase { mArchive.record(sbn, REASON_CANCEL); } - List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true)); assertThat(actual).hasSize(expected.size()); for (StatusBarNotification sbn : actual) { assertThat(expected).contains(sbn.getKey()); @@ -89,6 +100,22 @@ public class ArchiveTest extends UiServiceTestCase { } @Test + public void testCrossUser() { + mArchive.record(getNotification("pkg", 1, UserHandle.of(USER_SYSTEM)), REASON_CANCEL); + mArchive.record(getNotification("pkg", 2, UserHandle.of(USER_CURRENT)), REASON_CANCEL); + mArchive.record(getNotification("pkg", 3, UserHandle.of(USER_ALL)), REASON_CANCEL); + mArchive.record(getNotification("pkg", 4, UserHandle.of(USER_NULL)), REASON_CANCEL); + + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true)); + assertThat(actual).hasSize(3); + for (StatusBarNotification sbn : actual) { + if (sbn.getUserId() == USER_NULL) { + fail("leaked notification from wrong user"); + } + } + } + + @Test public void testRecordAndRead_overLimit() { List<String> expected = new ArrayList<>(); for (int i = 0; i < (SIZE * 2); i++) { @@ -99,7 +126,8 @@ public class ArchiveTest extends UiServiceTestCase { } } - List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray((SIZE * 2), true)); + List<StatusBarNotification> actual = Arrays.asList( + mArchive.getArray(mUm, (SIZE * 2), true)); assertThat(actual).hasSize(expected.size()); for (StatusBarNotification sbn : actual) { assertThat(expected).contains(sbn.getKey()); @@ -119,7 +147,7 @@ public class ArchiveTest extends UiServiceTestCase { } } - List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true)); assertThat(actual).hasSize(expected.size()); for (StatusBarNotification sbn : actual) { assertThat(expected).contains(sbn.getKey()); @@ -140,7 +168,7 @@ public class ArchiveTest extends UiServiceTestCase { } mArchive.updateHistoryEnabled(USER_CURRENT, false); - List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true)); assertThat(actual).hasSize(expected.size()); for (StatusBarNotification sbn : actual) { assertThat(expected).contains(sbn.getKey()); @@ -165,7 +193,7 @@ public class ArchiveTest extends UiServiceTestCase { } mArchive.removeChannelNotifications("pkg", USER_CURRENT, "test0"); mArchive.removeChannelNotifications("pkg", USER_CURRENT, "test" + (SIZE - 2)); - List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true)); assertThat(actual).hasSize(expected.size()); for (StatusBarNotification sbn : actual) { assertThat(expected).contains(sbn.getKey()); @@ -215,7 +243,7 @@ public class ArchiveTest extends UiServiceTestCase { fail("Concurrent modification exception"); } - List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true)); assertThat(actual).hasSize(expected.size()); for (StatusBarNotification sbn : actual) { assertThat(expected).contains(sbn.getKey()); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index f7121537c52c..b98401e76cc2 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -476,6 +476,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"); @@ -7004,8 +7005,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { waitForIdle(); // A notification exists for the given record - StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG); - assertEquals(1, notifsBefore.length); + List<StatusBarNotification> notifsBefore = + mBinderService.getAppActiveNotifications(PKG, nr.getSbn().getUserId()).getList(); + assertEquals(1, notifsBefore.size()); reset(mPackageManager); @@ -8323,4 +8325,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertTrue(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 1001))); assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("test", 1002))); } + + @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.getSbn().getId(), nr0.getSbn().getNotification(), nr0.getSbn().getUserId()); + + NotificationRecord nr10 = + generateNotificationRecord(mTestNotificationChannel, 10); + mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag10", + nr10.getSbn().getId(), nr10.getSbn().getNotification(), nr10.getSbn().getUserId()); + + NotificationRecord nr11 = + generateNotificationRecord(mTestNotificationChannel, 11); + mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag11", + nr11.getSbn().getId(), nr11.getSbn().getNotification(), nr11.getSbn().getUserId()); + waitForIdle(); + + StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); + assertEquals(2, notifs.length); + for (StatusBarNotification sbn : notifs) { + if (sbn.getUserId() == 11) { + fail("leaked data across users"); + } + } + } } |