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

Commit 852795c3 authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge "Add BubbleMetadata detection to block FSI" into udc-dev

parents 4f9b44a2 7d6152a0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -60,6 +60,12 @@ public interface NotificationInterruptStateProvider {
         * FSI even while the device was unlocked.
         */
        NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR(false),
        /**
         * Notification should not FSI due to having suppressive BubbleMetadata. This blocks a
         * potentially malicious use of flags that previously allowed apps to escalate a HUN to an
         * FSI even while the device was unlocked.
         */
        NO_FSI_SUPPRESSIVE_BUBBLE_METADATA(false),
        /**
         * Device screen is off, so the FSI should launch.
         */
+22 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.interruption;

import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD;
import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA;
import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR;
import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.HUN_SNOOZE_BYPASSED_POTENTIALLY_SUPPRESSED_FSI;

@@ -82,6 +83,9 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
        @UiEvent(doc = "FSI suppressed for suppressive GroupAlertBehavior")
        FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR(1235),

        @UiEvent(doc = "FSI suppressed for suppressive BubbleMetadata")
        FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA(1353),

        @UiEvent(doc = "FSI suppressed for requiring neither HUN nor keyguard")
        FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD(1236),

@@ -273,6 +277,16 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
                    suppressedByDND);
        }

        // If the notification has suppressive BubbleMetadata, block FSI and warn.
        Notification.BubbleMetadata bubbleMetadata = sbn.getNotification().getBubbleMetadata();
        if (bubbleMetadata != null && bubbleMetadata.isNotificationSuppressed()) {
            // b/274759612: Detect and report an event when a notification has both an FSI and a
            // suppressive BubbleMetadata, and now correctly block the FSI from firing.
            return getDecisionGivenSuppression(
                    FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_BUBBLE_METADATA,
                    suppressedByDND);
        }

        // Notification is coming from a suspended package, block FSI
        if (entry.getRanking().isSuspended()) {
            return getDecisionGivenSuppression(FullScreenIntentDecision.NO_FSI_SUSPENDED,
@@ -351,6 +365,14 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
                mLogger.logNoFullscreenWarning(entry,
                        decision + ": GroupAlertBehavior will prevent HUN");
                return;
            case NO_FSI_SUPPRESSIVE_BUBBLE_METADATA:
                android.util.EventLog.writeEvent(0x534e4554, "274759612", uid,
                        "bubbleMetadata");
                mUiEventLogger.log(FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA, uid,
                        packageName);
                mLogger.logNoFullscreenWarning(entry,
                        decision + ": BubbleMetadata may prevent HUN");
                return;
            case NO_FSI_NO_HUN_OR_KEYGUARD:
                android.util.EventLog.writeEvent(0x534e4554, "231322873", uid,
                        "no hun or keyguard");
+37 −0
Original line number Diff line number Diff line
@@ -655,6 +655,39 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
        assertThat(fakeUiEvent.packageName).isEqualTo(entry.getSbn().getPackageName());
    }

    @Test
    public void testShouldNotFullScreen_isSuppressedByBubbleMetadata_withStrictFlag() {
        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
        testShouldNotFullScreen_isSuppressedByBubbleMetadata();
    }

    @Test
    public void testShouldNotFullScreen_isSuppressedByBubbleMetadata() {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        Notification.BubbleMetadata bubbleMetadata = new Notification.BubbleMetadata.Builder("foo")
                .setSuppressNotification(true).build();
        entry.getSbn().getNotification().setBubbleMetadata(bubbleMetadata);
        when(mPowerManager.isInteractive()).thenReturn(false);
        when(mStatusBarStateController.isDreaming()).thenReturn(true);
        when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);

        assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
                .isEqualTo(FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_BUBBLE_METADATA);
        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isFalse();
        verify(mLogger, never()).logNoFullscreen(any(), any());
        verify(mLogger).logNoFullscreenWarning(entry,
                "NO_FSI_SUPPRESSIVE_BUBBLE_METADATA: BubbleMetadata may prevent HUN");
        verify(mLogger, never()).logFullscreen(any(), any());

        assertThat(mUiEventLoggerFake.numLogs()).isEqualTo(1);
        UiEventLoggerFake.FakeUiEvent fakeUiEvent = mUiEventLoggerFake.get(0);
        assertThat(fakeUiEvent.eventId).isEqualTo(
                NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA.getId());
        assertThat(fakeUiEvent.uid).isEqualTo(entry.getSbn().getUid());
        assertThat(fakeUiEvent.packageName).isEqualTo(entry.getSbn().getPackageName());
    }

    @Test
    public void testShouldFullScreen_notInteractive_withStrictFlag() throws Exception {
        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
@@ -664,6 +697,9 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
    @Test
    public void testShouldFullScreen_notInteractive() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        Notification.BubbleMetadata bubbleMetadata = new Notification.BubbleMetadata.Builder("foo")
                .setSuppressNotification(false).build();
        entry.getSbn().getNotification().setBubbleMetadata(bubbleMetadata);
        when(mPowerManager.isInteractive()).thenReturn(false);
        when(mStatusBarStateController.isDreaming()).thenReturn(false);
        when(mStatusBarStateController.getState()).thenReturn(SHADE);
@@ -897,6 +933,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        Set<FullScreenIntentDecision> warnings = new HashSet<>(Arrays.asList(
                FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR,
                FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_BUBBLE_METADATA,
                FullScreenIntentDecision.NO_FSI_NO_HUN_OR_KEYGUARD
        ));
        for (FullScreenIntentDecision decision : FullScreenIntentDecision.values()) {