Filter notification APIs by user
Specifically getActiveNotifications and getHistoricalNotifications Test: atest NotificationManagerServiceTest Bug: 214999128 Change-Id: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258 Merged-In: I2eba0a592fa33ed25e1ac3919f1b2631e5db4258
This commit is contained in:
@@ -509,16 +509,27 @@ public class NotificationManagerService extends SystemService {
|
|||||||
return mBuffer.descendingIterator();
|
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;
|
if (count == 0) count = mBufferSize;
|
||||||
final StatusBarNotification[] a
|
List<StatusBarNotification> a = new ArrayList();
|
||||||
= new StatusBarNotification[Math.min(count, mBuffer.size())];
|
|
||||||
Iterator<StatusBarNotification> iter = descendingIterator();
|
Iterator<StatusBarNotification> iter = descendingIterator();
|
||||||
int i=0;
|
int i=0;
|
||||||
while (iter.hasNext() && i < count) {
|
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,
|
android.Manifest.permission.ACCESS_NOTIFICATIONS,
|
||||||
"NotificationManagerService.getActiveNotifications");
|
"NotificationManagerService.getActiveNotifications");
|
||||||
|
|
||||||
StatusBarNotification[] tmp = null;
|
ArrayList<StatusBarNotification> tmp = new ArrayList<>();
|
||||||
int uid = Binder.getCallingUid();
|
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
|
// noteOp will check to make sure the callingPkg matches the uid
|
||||||
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg)
|
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg)
|
||||||
== AppOpsManager.MODE_ALLOWED) {
|
== AppOpsManager.MODE_ALLOWED) {
|
||||||
synchronized (mNotificationLock) {
|
synchronized (mNotificationLock) {
|
||||||
tmp = new StatusBarNotification[mNotificationList.size()];
|
|
||||||
final int N = mNotificationList.size();
|
final int N = mNotificationList.size();
|
||||||
for (int i=0; i<N; i++) {
|
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)
|
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg)
|
||||||
== AppOpsManager.MODE_ALLOWED) {
|
== AppOpsManager.MODE_ALLOWED) {
|
||||||
synchronized (mArchive) {
|
synchronized (mArchive) {
|
||||||
tmp = mArchive.getArray(count);
|
tmp = mArchive.getArray(mUm, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
|
when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
|
||||||
when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
|
when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
|
||||||
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
|
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
|
// write to a test file; the system file isn't readable from tests
|
||||||
mFile = new File(mContext.getCacheDir(), "test.xml");
|
mFile = new File(mContext.getCacheDir(), "test.xml");
|
||||||
@@ -498,6 +499,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
return generateNotificationRecord(channel, extender, false /* isBubble */);
|
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,
|
private NotificationRecord generateNotificationRecord(NotificationChannel channel,
|
||||||
Notification.TvExtender extender, boolean isBubble) {
|
Notification.TvExtender extender, boolean isBubble) {
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
@@ -5342,4 +5355,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
assertEquals(1, notifsAfter.length);
|
assertEquals(1, notifsAfter.length);
|
||||||
assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user