Loading services/core/java/com/android/server/notification/NotificationManagerService.java +24 −18 Original line number Diff line number Diff line Loading @@ -10754,6 +10754,14 @@ public class NotificationManagerService extends SystemService { final String key = record.getSbn().getKey(); final NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking(); ArrayList<Notification.Action> smartActions = record.getSystemGeneratedSmartActions(); ArrayList<CharSequence> smartReplies = record.getSmartReplies(); if (redactSensitiveNotificationsFromUntrustedListeners() && !mListeners.isUidTrusted(info.uid) && mListeners.hasSensitiveContent(record)) { smartActions = null; smartReplies = null; } ranking.populate( key, rankings.size(), Loading @@ -10771,8 +10779,8 @@ public class NotificationManagerService extends SystemService { record.isHidden(), record.getLastAudiblyAlertedMs(), record.getSound() != null || record.getVibration() != null, record.getSystemGeneratedSmartActions(), record.getSmartReplies(), smartActions, smartReplies, record.canBubble(), record.isTextChanged(), record.isConversation(), Loading Loading @@ -11522,21 +11530,17 @@ public class NotificationManagerService extends SystemService { super.setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled, userSet); String pkgName = getPackageName(pkgOrComponent); if (redactSensitiveNotificationsFromUntrustedListeners()) { try { int uid = mPackageManagerClient.getPackageUidAsUser(pkgName, userId); if (!enabled) { int uid = mPackageManagerInternal.getPackageUid(pkgName, 0, userId); if (!enabled && uid >= 0) { synchronized (mTrustedListenerUids) { mTrustedListenerUids.remove(uid); } } if (enabled && isAppTrustedNotificationListenerService(uid, pkgName)) { if (enabled && uid >= 0 && isAppTrustedNotificationListenerService(uid, pkgName)) { synchronized (mTrustedListenerUids) { mTrustedListenerUids.add(uid); } } } catch (NameNotFoundException e) { Slog.e(TAG, "PackageManager could not find package " + pkgName, e); } } mContext.sendBroadcastAsUser( Loading Loading @@ -11955,8 +11959,10 @@ public class NotificationManagerService extends SystemService { for (final ManagedServiceInfo info : getServices()) { boolean isTrusted = isUidTrusted(info.uid); boolean sendRedacted = isNewSensitive && !isTrusted; boolean sendOldRedacted = isOldSensitive && !isTrusted; boolean sendRedacted = redactSensitiveNotificationsFromUntrustedListeners() && isNewSensitive && !isTrusted; boolean sendOldRedacted = redactSensitiveNotificationsFromUntrustedListeners() && isOldSensitive && !isTrusted; boolean sbnVisible = isVisibleToListener(sbn, r.getNotificationType(), info); boolean oldSbnVisible = (oldSbn != null) && isVisibleToListener(oldSbn, old.getNotificationType(), info); Loading Loading @@ -12055,7 +12061,7 @@ public class NotificationManagerService extends SystemService { StatusBarNotification redactStatusBarNotification(StatusBarNotification sbn) { if (!redactSensitiveNotificationsFromUntrustedListeners()) { return sbn; throw new RuntimeException("redactStatusBarNotification called while flag is off"); } ApplicationInfo appInfo = sbn.getNotification().extras.getParcelable( Loading Loading @@ -12227,6 +12233,7 @@ public class NotificationManagerService extends SystemService { public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) { boolean isHiddenRankingUpdate = changedHiddenNotifications != null && changedHiddenNotifications.size() > 0; // TODO (b/73052211): if the ranking update changed the notification type, // cancel notifications for NLSes that can't see them anymore for (final ManagedServiceInfo serviceInfo : getServices()) { Loading @@ -12250,7 +12257,6 @@ public class NotificationManagerService extends SystemService { if (notifyThisListener || !isHiddenRankingUpdate) { final NotificationRankingUpdate update = makeRankingUpdateLocked( serviceInfo); mHandler.post(() -> notifyRankingUpdate(serviceInfo, update)); } } services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java +10 −15 Original line number Diff line number Diff line Loading @@ -68,10 +68,7 @@ import android.os.Bundle; import android.os.Parcel; import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.INotificationListener; import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerService; Loading Loading @@ -111,7 +108,7 @@ import java.util.concurrent.CountDownLatch; public class NotificationListenersTest extends UiServiceTestCase { @Rule public CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); public SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private PackageManager mPm; Loading Loading @@ -696,8 +693,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_withPermission() throws RemoteException { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mNm.mPackageManager.checkUidPermission(RECEIVE_SENSITIVE_NOTIFICATIONS, mUid1)) .thenReturn(PERMISSION_GRANTED); ManagedServices.ManagedServiceInfo info = getMockServiceInfo(); Loading @@ -706,8 +703,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_withSystemSignature() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mNm.mPackageManagerInternal.isPlatformSigned(mCn1.getPackageName())).thenReturn(true); ManagedServices.ManagedServiceInfo info = getMockServiceInfo(); mListeners.onServiceAdded(info); Loading @@ -715,8 +712,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_withCdmAssociation() throws Exception { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); mNm.mCompanionManager = mock(ICompanionDeviceManager.class); AssociationInfo assocInfo = mock(AssociationInfo.class); when(assocInfo.isRevoked()).thenReturn(false); Loading @@ -731,16 +728,16 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsDisabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_ifFlagDisabled() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ManagedServices.ManagedServiceInfo info = getMockServiceInfo(); mListeners.onServiceAdded(info); assertTrue(mListeners.isUidTrusted(mUid1)); } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_whenPosted() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); infos.add(getMockServiceInfo()); doReturn(infos).when(mListeners).getServices(); Loading @@ -762,13 +759,11 @@ public class NotificationListenersTest extends UiServiceTestCase { mListeners.notifyPostedLocked(r, old); verify(mListeners, atLeast(1)).redactStatusBarNotification(eq(sbn)); verify(mListeners, never()).redactStatusBarNotification(eq(oldSbn)); } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_whenPosted_oldRemoved() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); infos.add(getMockServiceInfo()); doReturn(infos).when(mListeners).getServices(); Loading @@ -795,8 +790,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_whenRemoved() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); doReturn(mock(StatusBarNotification.class)) .when(mListeners).redactStatusBarNotification(any()); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); Loading @@ -816,8 +811,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsDisabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_noneIfFlagDisabled() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); infos.add(getMockServiceInfo()); doReturn(infos).when(mListeners).getServices(); Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +96 −10 Original line number Diff line number Diff line Loading @@ -77,7 +77,9 @@ import static android.os.UserManager.USER_TYPE_PROFILE_CLONE; import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; import static android.service.notification.Adjustment.KEY_CONTEXTUAL_ACTIONS; import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.KEY_TEXT_REPLIES; import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS; import static android.service.notification.Condition.SOURCE_CONTEXT; Loading Loading @@ -216,9 +218,6 @@ import android.os.UserManager; import android.os.WorkSource; import android.permission.PermissionManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.rule.DeniedDevices; import android.platform.test.rule.DeviceProduct; Loading Loading @@ -361,9 +360,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @Rule public CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); private TestableNotificationManagerService mService; private INotificationManager mBinderService; private NotificationManagerInternal mInternalService; Loading Loading @@ -11778,8 +11774,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testGetActiveNotificationsFromListener_redactNotification() throws Exception { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, 0); mService.addNotification(r); Loading Loading @@ -11808,12 +11804,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testGetSnoozedNotificationsFromListener_redactNotification() throws Exception { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, 0); mService.addNotification(r); mService.snoozeNotificationInt(r.getKey(), 1000, null, mListener); when(mSnoozeHelper.getSnoozed()).thenReturn(List.of(r)); when(mListeners.isUidTrusted(anyInt())).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(true); StatusBarNotification redacted = generateRedactedSbn(mTestNotificationChannel, 1, 1); Loading Loading @@ -11992,6 +11987,97 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(2, nru.getRankingMap().getOrderedKeys().length); } @Test public void testMakeRankingUpdate_redactsIfRecordSensitiveAndServiceUntrusted() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mListeners.isUidTrusted(anyInt())).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(true); NotificationRecord pkgA = new NotificationRecord(mContext, generateSbn("a", 1000, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgA); mService.addNotification(pkgA); NotificationRecord pkgB = new NotificationRecord(mContext, generateSbn("b", 1001, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgB); mService.addNotification(pkgB); ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); when(info.enabledAndUserMatches(anyInt())).thenReturn(true); when(info.isSameUser(anyInt())).thenReturn(true); NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); NotificationListenerService.Ranking ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(0, ranking.getSmartActions().size()); assertEquals(0, ranking.getSmartReplies().size()); NotificationListenerService.Ranking ranking2 = nru.getRankingMap().getRawRankingObject(pkgB.getSbn().getKey()); assertEquals(0, ranking2.getSmartActions().size()); assertEquals(0, ranking2.getSmartReplies().size()); } @Test public void testMakeRankingUpdate_doestntRedactIfFlagDisabled() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mListeners.isUidTrusted(anyInt())).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(true); NotificationRecord pkgA = new NotificationRecord(mContext, generateSbn("a", 1000, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgA); mService.addNotification(pkgA); ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); when(info.enabledAndUserMatches(anyInt())).thenReturn(true); when(info.isSameUser(anyInt())).thenReturn(true); NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); NotificationListenerService.Ranking ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(1, ranking.getSmartActions().size()); assertEquals(1, ranking.getSmartReplies().size()); } @Test public void testMakeRankingUpdate_doesntRedactIfNotSensitiveOrServiceTrusted() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); NotificationRecord pkgA = new NotificationRecord(mContext, generateSbn("a", 1000, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgA); mService.addNotification(pkgA); ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); when(info.enabledAndUserMatches(anyInt())).thenReturn(true); when(info.isSameUser(anyInt())).thenReturn(true); // No sensitive content, no redaction when(mListeners.isUidTrusted(eq(1000))).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(false); NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); NotificationListenerService.Ranking ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(1, ranking.getSmartActions().size()); assertEquals(1, ranking.getSmartReplies().size()); // trusted listener, no redaction when(mListeners.isUidTrusted(eq(1000))).thenReturn(true); when(mListeners.hasSensitiveContent(any())).thenReturn(true); nru = mService.makeRankingUpdateLocked(info); ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(1, ranking.getSmartActions().size()); assertEquals(1, ranking.getSmartReplies().size()); } private void addSmartActionsAndReplies(NotificationRecord record) { Bundle b = new Bundle(); ArrayList<Notification.Action> actions = new ArrayList<>(); actions.add(new Notification.Action(0, "", null)); b.putParcelableArrayList(KEY_CONTEXTUAL_ACTIONS, actions); ArrayList<CharSequence> replies = new ArrayList<>(List.of("test")); b.putCharSequenceArrayList(KEY_TEXT_REPLIES, replies); Adjustment a = new Adjustment(record.getSbn().getPackageName(), record.getSbn().getKey(), b, "", record.getUserId()); record.addAdjustment(a); record.applyAdjustments(); } @Test public void testMaybeShowReviewPermissionsNotification_flagOff() { mService.setShowReviewPermissionsNotification(false); Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +24 −18 Original line number Diff line number Diff line Loading @@ -10754,6 +10754,14 @@ public class NotificationManagerService extends SystemService { final String key = record.getSbn().getKey(); final NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking(); ArrayList<Notification.Action> smartActions = record.getSystemGeneratedSmartActions(); ArrayList<CharSequence> smartReplies = record.getSmartReplies(); if (redactSensitiveNotificationsFromUntrustedListeners() && !mListeners.isUidTrusted(info.uid) && mListeners.hasSensitiveContent(record)) { smartActions = null; smartReplies = null; } ranking.populate( key, rankings.size(), Loading @@ -10771,8 +10779,8 @@ public class NotificationManagerService extends SystemService { record.isHidden(), record.getLastAudiblyAlertedMs(), record.getSound() != null || record.getVibration() != null, record.getSystemGeneratedSmartActions(), record.getSmartReplies(), smartActions, smartReplies, record.canBubble(), record.isTextChanged(), record.isConversation(), Loading Loading @@ -11522,21 +11530,17 @@ public class NotificationManagerService extends SystemService { super.setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled, userSet); String pkgName = getPackageName(pkgOrComponent); if (redactSensitiveNotificationsFromUntrustedListeners()) { try { int uid = mPackageManagerClient.getPackageUidAsUser(pkgName, userId); if (!enabled) { int uid = mPackageManagerInternal.getPackageUid(pkgName, 0, userId); if (!enabled && uid >= 0) { synchronized (mTrustedListenerUids) { mTrustedListenerUids.remove(uid); } } if (enabled && isAppTrustedNotificationListenerService(uid, pkgName)) { if (enabled && uid >= 0 && isAppTrustedNotificationListenerService(uid, pkgName)) { synchronized (mTrustedListenerUids) { mTrustedListenerUids.add(uid); } } } catch (NameNotFoundException e) { Slog.e(TAG, "PackageManager could not find package " + pkgName, e); } } mContext.sendBroadcastAsUser( Loading Loading @@ -11955,8 +11959,10 @@ public class NotificationManagerService extends SystemService { for (final ManagedServiceInfo info : getServices()) { boolean isTrusted = isUidTrusted(info.uid); boolean sendRedacted = isNewSensitive && !isTrusted; boolean sendOldRedacted = isOldSensitive && !isTrusted; boolean sendRedacted = redactSensitiveNotificationsFromUntrustedListeners() && isNewSensitive && !isTrusted; boolean sendOldRedacted = redactSensitiveNotificationsFromUntrustedListeners() && isOldSensitive && !isTrusted; boolean sbnVisible = isVisibleToListener(sbn, r.getNotificationType(), info); boolean oldSbnVisible = (oldSbn != null) && isVisibleToListener(oldSbn, old.getNotificationType(), info); Loading Loading @@ -12055,7 +12061,7 @@ public class NotificationManagerService extends SystemService { StatusBarNotification redactStatusBarNotification(StatusBarNotification sbn) { if (!redactSensitiveNotificationsFromUntrustedListeners()) { return sbn; throw new RuntimeException("redactStatusBarNotification called while flag is off"); } ApplicationInfo appInfo = sbn.getNotification().extras.getParcelable( Loading Loading @@ -12227,6 +12233,7 @@ public class NotificationManagerService extends SystemService { public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) { boolean isHiddenRankingUpdate = changedHiddenNotifications != null && changedHiddenNotifications.size() > 0; // TODO (b/73052211): if the ranking update changed the notification type, // cancel notifications for NLSes that can't see them anymore for (final ManagedServiceInfo serviceInfo : getServices()) { Loading @@ -12250,7 +12257,6 @@ public class NotificationManagerService extends SystemService { if (notifyThisListener || !isHiddenRankingUpdate) { final NotificationRankingUpdate update = makeRankingUpdateLocked( serviceInfo); mHandler.post(() -> notifyRankingUpdate(serviceInfo, update)); } }
services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java +10 −15 Original line number Diff line number Diff line Loading @@ -68,10 +68,7 @@ import android.os.Bundle; import android.os.Parcel; import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.INotificationListener; import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerService; Loading Loading @@ -111,7 +108,7 @@ import java.util.concurrent.CountDownLatch; public class NotificationListenersTest extends UiServiceTestCase { @Rule public CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); public SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private PackageManager mPm; Loading Loading @@ -696,8 +693,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_withPermission() throws RemoteException { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mNm.mPackageManager.checkUidPermission(RECEIVE_SENSITIVE_NOTIFICATIONS, mUid1)) .thenReturn(PERMISSION_GRANTED); ManagedServices.ManagedServiceInfo info = getMockServiceInfo(); Loading @@ -706,8 +703,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_withSystemSignature() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mNm.mPackageManagerInternal.isPlatformSigned(mCn1.getPackageName())).thenReturn(true); ManagedServices.ManagedServiceInfo info = getMockServiceInfo(); mListeners.onServiceAdded(info); Loading @@ -715,8 +712,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_withCdmAssociation() throws Exception { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); mNm.mCompanionManager = mock(ICompanionDeviceManager.class); AssociationInfo assocInfo = mock(AssociationInfo.class); when(assocInfo.isRevoked()).thenReturn(false); Loading @@ -731,16 +728,16 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsDisabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testListenerTrusted_ifFlagDisabled() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ManagedServices.ManagedServiceInfo info = getMockServiceInfo(); mListeners.onServiceAdded(info); assertTrue(mListeners.isUidTrusted(mUid1)); } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_whenPosted() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); infos.add(getMockServiceInfo()); doReturn(infos).when(mListeners).getServices(); Loading @@ -762,13 +759,11 @@ public class NotificationListenersTest extends UiServiceTestCase { mListeners.notifyPostedLocked(r, old); verify(mListeners, atLeast(1)).redactStatusBarNotification(eq(sbn)); verify(mListeners, never()).redactStatusBarNotification(eq(oldSbn)); } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_whenPosted_oldRemoved() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); infos.add(getMockServiceInfo()); doReturn(infos).when(mListeners).getServices(); Loading @@ -795,8 +790,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_whenRemoved() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); doReturn(mock(StatusBarNotification.class)) .when(mListeners).redactStatusBarNotification(any()); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); Loading @@ -816,8 +811,8 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test @RequiresFlagsDisabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testRedaction_noneIfFlagDisabled() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); ArrayList<ManagedServices.ManagedServiceInfo> infos = new ArrayList<>(); infos.add(getMockServiceInfo()); doReturn(infos).when(mListeners).getServices(); Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +96 −10 Original line number Diff line number Diff line Loading @@ -77,7 +77,9 @@ import static android.os.UserManager.USER_TYPE_PROFILE_CLONE; import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; import static android.service.notification.Adjustment.KEY_CONTEXTUAL_ACTIONS; import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.KEY_TEXT_REPLIES; import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS; import static android.service.notification.Condition.SOURCE_CONTEXT; Loading Loading @@ -216,9 +218,6 @@ import android.os.UserManager; import android.os.WorkSource; import android.permission.PermissionManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.rule.DeniedDevices; import android.platform.test.rule.DeviceProduct; Loading Loading @@ -361,9 +360,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @Rule public CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); private TestableNotificationManagerService mService; private INotificationManager mBinderService; private NotificationManagerInternal mInternalService; Loading Loading @@ -11778,8 +11774,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testGetActiveNotificationsFromListener_redactNotification() throws Exception { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, 0); mService.addNotification(r); Loading Loading @@ -11808,12 +11804,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test @RequiresFlagsEnabled(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) public void testGetSnoozedNotificationsFromListener_redactNotification() throws Exception { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, 0); mService.addNotification(r); mService.snoozeNotificationInt(r.getKey(), 1000, null, mListener); when(mSnoozeHelper.getSnoozed()).thenReturn(List.of(r)); when(mListeners.isUidTrusted(anyInt())).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(true); StatusBarNotification redacted = generateRedactedSbn(mTestNotificationChannel, 1, 1); Loading Loading @@ -11992,6 +11987,97 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(2, nru.getRankingMap().getOrderedKeys().length); } @Test public void testMakeRankingUpdate_redactsIfRecordSensitiveAndServiceUntrusted() { mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mListeners.isUidTrusted(anyInt())).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(true); NotificationRecord pkgA = new NotificationRecord(mContext, generateSbn("a", 1000, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgA); mService.addNotification(pkgA); NotificationRecord pkgB = new NotificationRecord(mContext, generateSbn("b", 1001, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgB); mService.addNotification(pkgB); ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); when(info.enabledAndUserMatches(anyInt())).thenReturn(true); when(info.isSameUser(anyInt())).thenReturn(true); NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); NotificationListenerService.Ranking ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(0, ranking.getSmartActions().size()); assertEquals(0, ranking.getSmartReplies().size()); NotificationListenerService.Ranking ranking2 = nru.getRankingMap().getRawRankingObject(pkgB.getSbn().getKey()); assertEquals(0, ranking2.getSmartActions().size()); assertEquals(0, ranking2.getSmartReplies().size()); } @Test public void testMakeRankingUpdate_doestntRedactIfFlagDisabled() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mListeners.isUidTrusted(anyInt())).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(true); NotificationRecord pkgA = new NotificationRecord(mContext, generateSbn("a", 1000, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgA); mService.addNotification(pkgA); ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); when(info.enabledAndUserMatches(anyInt())).thenReturn(true); when(info.isSameUser(anyInt())).thenReturn(true); NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); NotificationListenerService.Ranking ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(1, ranking.getSmartActions().size()); assertEquals(1, ranking.getSmartReplies().size()); } @Test public void testMakeRankingUpdate_doesntRedactIfNotSensitiveOrServiceTrusted() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); NotificationRecord pkgA = new NotificationRecord(mContext, generateSbn("a", 1000, 9, 0), mTestNotificationChannel); addSmartActionsAndReplies(pkgA); mService.addNotification(pkgA); ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); when(info.enabledAndUserMatches(anyInt())).thenReturn(true); when(info.isSameUser(anyInt())).thenReturn(true); // No sensitive content, no redaction when(mListeners.isUidTrusted(eq(1000))).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(false); NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); NotificationListenerService.Ranking ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(1, ranking.getSmartActions().size()); assertEquals(1, ranking.getSmartReplies().size()); // trusted listener, no redaction when(mListeners.isUidTrusted(eq(1000))).thenReturn(true); when(mListeners.hasSensitiveContent(any())).thenReturn(true); nru = mService.makeRankingUpdateLocked(info); ranking = nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); assertEquals(1, ranking.getSmartActions().size()); assertEquals(1, ranking.getSmartReplies().size()); } private void addSmartActionsAndReplies(NotificationRecord record) { Bundle b = new Bundle(); ArrayList<Notification.Action> actions = new ArrayList<>(); actions.add(new Notification.Action(0, "", null)); b.putParcelableArrayList(KEY_CONTEXTUAL_ACTIONS, actions); ArrayList<CharSequence> replies = new ArrayList<>(List.of("test")); b.putCharSequenceArrayList(KEY_TEXT_REPLIES, replies); Adjustment a = new Adjustment(record.getSbn().getPackageName(), record.getSbn().getKey(), b, "", record.getUserId()); record.addAdjustment(a); record.applyAdjustments(); } @Test public void testMaybeShowReviewPermissionsNotification_flagOff() { mService.setShowReviewPermissionsNotification(false);