diff options
| author | 2024-02-21 16:48:29 -0800 | |
|---|---|---|
| committer | 2024-03-11 11:16:10 -0700 | |
| commit | 8a87c56fb4246174d0b4e70cf50c819e2dcd046d (patch) | |
| tree | fa86775ad3d31163985b357261147c7d8988aa24 | |
| parent | 0ba51e0896ac86f5faea3cd779155d1ed2188cba (diff) | |
Log sensitive notification adjustments
Fixes: 326651373
Test: atest NotificationManagerServiceTest
Change-Id: I24014560da9a5ed3d25b0b9fe01374e873360b9f
3 files changed, 89 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b98424cfade4..f4cb1035e045 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -338,6 +338,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.internal.util.function.TriPredicate; @@ -1825,6 +1826,12 @@ public class NotificationManagerService extends SystemService { } } + protected void logSensitiveAdjustmentReceived(boolean hasPosted, + boolean hasSensitiveContent, int lifespanMs) { + FrameworkStatsLog.write(FrameworkStatsLog.SENSITIVE_NOTIFICATION_REDACTION, hasPosted, + hasSensitiveContent, lifespanMs); + } + @GuardedBy("mNotificationLock") void clearSoundLocked() { mSoundNotificationKey = null; @@ -6384,7 +6391,7 @@ public class NotificationManagerService extends SystemService { if (Objects.equals(adjustment.getKey(), r.getKey()) && Objects.equals(adjustment.getUser(), r.getUserId()) && mAssistants.isSameUser(token, r.getUserId())) { - applyAdjustment(r, adjustment); + applyAdjustmentLocked(r, adjustment, false); r.applyAdjustments(); // importance is checked at the beginning of the // PostNotificationRunnable, before the signal extractors are run, so @@ -6394,7 +6401,7 @@ public class NotificationManagerService extends SystemService { } } if (!foundEnqueued) { - applyAdjustmentFromAssistant(token, adjustment); + applyAdjustmentsFromAssistant(token, List.of(adjustment)); } } } finally { @@ -6422,7 +6429,7 @@ public class NotificationManagerService extends SystemService { for (Adjustment adjustment : adjustments) { NotificationRecord r = mNotificationsByKey.get(adjustment.getKey()); if (r != null && mAssistants.isSameUser(token, r.getUserId())) { - applyAdjustment(r, adjustment); + applyAdjustmentLocked(r, adjustment, true); // If the assistant has blocked the notification, cancel it // This will trigger a sort, so we don't have to explicitly ask for // one here. @@ -6706,7 +6713,9 @@ public class NotificationManagerService extends SystemService { } } - private void applyAdjustment(NotificationRecord r, Adjustment adjustment) { + @GuardedBy("mNotificationLock") + private void applyAdjustmentLocked(NotificationRecord r, Adjustment adjustment, + boolean isPosted) { if (r == null) { return; } @@ -6723,6 +6732,11 @@ public class NotificationManagerService extends SystemService { adjustments.remove(removeKey); } r.addAdjustment(adjustment); + if (adjustment.getSignals().containsKey(Adjustment.KEY_SENSITIVE_CONTENT)) { + logSensitiveAdjustmentReceived(isPosted, + adjustment.getSignals().getBoolean(Adjustment.KEY_SENSITIVE_CONTENT), + r.getLifespanMs(System.currentTimeMillis())); + } } } 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 03f27493c3c7..d983dc87a3ca 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -6223,6 +6223,52 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testSensitiveAdjustmentsLogged() throws Exception { + NotificationManagerService.WorkerHandler handler = mock( + NotificationManagerService.WorkerHandler.class); + mService.setHandler(handler); + when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); + when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); + + // Set up notifications that will be adjusted + final NotificationRecord r1 = spy(generateNotificationRecord( + mTestNotificationChannel, 1, null, true)); + when(r1.getLifespanMs(anyLong())).thenReturn(1); + + r1.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId()); + mService.addEnqueuedNotification(r1); + + // Test an adjustment for an enqueued notification + Bundle signals = new Bundle(); + signals.putBoolean(Adjustment.KEY_SENSITIVE_CONTENT, true); + Adjustment adjustment1 = new Adjustment( + r1.getSbn().getPackageName(), r1.getKey(), signals, "", + r1.getUser().getIdentifier()); + mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment1); + assertTrue(mService.checkLastSensitiveLog(false, true, 1)); + + // Set up notifications that will be adjusted + final NotificationRecord r2 = spy(generateNotificationRecord( + mTestNotificationChannel, 1, null, true)); + when(r2.getLifespanMs(anyLong())).thenReturn(2); + + r2.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId()); + mService.addNotification(r2); + Adjustment adjustment2 = new Adjustment( + r2.getSbn().getPackageName(), r2.getKey(), signals, "", + r2.getUser().getIdentifier()); + mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment2); + assertTrue(mService.checkLastSensitiveLog(true, true, 2)); + + signals.putBoolean(Adjustment.KEY_SENSITIVE_CONTENT, false); + Adjustment adjustment3 = new Adjustment( + r2.getSbn().getPackageName(), r2.getKey(), signals, "", + r2.getUser().getIdentifier()); + mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment3); + assertTrue(mService.checkLastSensitiveLog(true, false, 2)); + } + + @Test public void testAdjustmentToImportanceNone_cancelsNotification() throws Exception { NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java index 6976ec3b0465..07d25dfd814e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java @@ -45,6 +45,13 @@ public class TestableNotificationManagerService extends NotificationManagerServi ComponentPermissionChecker permissionChecker; + private static class SensitiveLog { + public boolean hasPosted; + public boolean hasSensitiveContent; + public long lifetime; + } + public SensitiveLog lastSensitiveLog = null; + TestableNotificationManagerService(Context context, NotificationRecordLogger logger, InstanceIdSequence notificationInstanceIdSequence) { super(context, logger, notificationInstanceIdSequence); @@ -167,6 +174,15 @@ public class TestableNotificationManagerService extends NotificationManagerServi return permissionChecker.check(permission, uid, owningUid, exported); } + @Override + protected void logSensitiveAdjustmentReceived(boolean hasPosted, boolean hasSensitiveContent, + int lifetimeMs) { + lastSensitiveLog = new SensitiveLog(); + lastSensitiveLog.hasPosted = hasPosted; + lastSensitiveLog.hasSensitiveContent = hasSensitiveContent; + lastSensitiveLog.lifetime = lifetimeMs; + } + public class StrongAuthTrackerFake extends NotificationManagerService.StrongAuthTracker { private int mGetStrongAuthForUserReturnValue = 0; StrongAuthTrackerFake(Context context) { @@ -183,6 +199,15 @@ public class TestableNotificationManagerService extends NotificationManagerServi } } + public boolean checkLastSensitiveLog(boolean hasPosted, boolean hasSensitive, int lifetime) { + if (lastSensitiveLog == null) { + return false; + } + return hasPosted == lastSensitiveLog.hasPosted + && hasSensitive == lastSensitiveLog.hasSensitiveContent + && lifetime == lastSensitiveLog.lifetime; + } + public interface ComponentPermissionChecker { int check(String permission, int uid, int owningUid, boolean exported); } |