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

Commit 8a87c56f authored by Nate Myren's avatar Nate Myren
Browse files

Log sensitive notification adjustments

Fixes: 326651373
Test: atest NotificationManagerServiceTest
Change-Id: I24014560da9a5ed3d25b0b9fe01374e873360b9f
parent 0ba51e08
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -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()));
            }
        }
    }
+46 −0
Original line number Diff line number Diff line
@@ -6222,6 +6222,52 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertEquals(2, mNotificationRecordLogger.get(1).getInstanceId());
    }
    @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(
+25 −0
Original line number Diff line number Diff line
@@ -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);
    }