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

Commit 722ca990 authored by Jeff DeCew's avatar Jeff DeCew Committed by Automerger Merge Worker
Browse files

Merge "Block FullScreenIntent while device is in use if notification has a...

Merge "Block FullScreenIntent while device is in use if notification has a silencing GroupAlertBehavior." into rvc-dev am: e35bab3a am: f7b8f723

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19344104



Change-Id: I6ee71f28d447e32c565b5e60c558b558d965dc10
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 0ded155f f7b8f723
Loading
Loading
Loading
Loading
+81 −10
Original line number Diff line number Diff line
@@ -175,9 +175,86 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
     */
    @Override
    public boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry) {
        return entry.getSbn().getNotification().fullScreenIntent != null
                && (!shouldHeadsUp(entry)
                || mStatusBarStateController.getState() == StatusBarState.KEYGUARD);
        if (entry.getSbn().getNotification().fullScreenIntent == null) {
            return false;
        }

        // Never show FSI when suppressed by DND
        if (entry.shouldSuppressFullScreenIntent()) {
            if (DEBUG) {
                Log.d(TAG, "No FullScreenIntent: Suppressed by DND: " + entry.getKey());
            }
            return false;
        }

        // Never show FSI if importance is not HIGH
        if (entry.getImportance() < NotificationManager.IMPORTANCE_HIGH) {
            if (DEBUG) {
                Log.d(TAG, "No FullScreenIntent: Not important enough: " + entry.getKey());
            }
            return false;
        }

        // If the notification has suppressive GroupAlertBehavior, block FSI and warn.
        StatusBarNotification sbn = entry.getSbn();
        if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
            // b/231322873: Detect and report an event when a notification has both an FSI and a
            // suppressive groupAlertBehavior, and now correctly block the FSI from firing.
            final int uid = entry.getSbn().getUid();
            android.util.EventLog.writeEvent(0x534e4554, "231322873", uid, "groupAlertBehavior");
            if (DEBUG) {
                Log.w(TAG, "No FullScreenIntent: WARNING: GroupAlertBehavior will prevent HUN: "
                        + entry.getKey());
            }
            return false;
        }

        // If the screen is off, then launch the FullScreenIntent
        if (!mPowerManager.isInteractive()) {
            if (DEBUG) {
                Log.d(TAG, "FullScreenIntent: Device is not interactive: " + entry.getKey());
            }
            return true;
        }

        // If the device is currently dreaming, then launch the FullScreenIntent
        if (isDreaming()) {
            if (DEBUG) {
                Log.d(TAG, "FullScreenIntent: Device is dreaming: " + entry.getKey());
            }
            return true;
        }

        // If the keyguard is showing, then launch the FullScreenIntent
        if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
            if (DEBUG) {
                Log.d(TAG, "FullScreenIntent: Keyguard is showing: " + entry.getKey());
            }
            return true;
        }

        // If the notification should HUN, then we don't need FSI
        if (shouldHeadsUp(entry)) {
            if (DEBUG) {
                Log.d(TAG, "No FullScreenIntent: Expected to HUN: " + entry.getKey());
            }
            return false;
        }

        // If the notification won't HUN for some other reason (DND/snooze/etc), launch FSI.
        if (DEBUG) {
            Log.d(TAG, "FullScreenIntent: Expected not to HUN: " + entry.getKey());
        }
        return true;
    }

    private boolean isDreaming() {
        try {
            return mDreamManager.isDreaming();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to query dream manager.", e);
            return false;
        }
    }

    private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) {
@@ -228,13 +305,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
            return false;
        }

        boolean isDreaming = false;
        try {
            isDreaming = mDreamManager.isDreaming();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to query dream manager.", e);
        }
        boolean inUse = mPowerManager.isScreenOn() && !isDreaming;
        boolean inUse = mPowerManager.isScreenOn() && !isDreaming();

        if (!inUse) {
            if (DEBUG_HEADS_UP) {
+112 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;

import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE;

import static com.google.common.truth.Truth.assertThat;
@@ -84,6 +85,8 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
    BatteryController mBatteryController;
    @Mock
    Handler mMockHandler;
    @Mock
    PendingIntent mPendingIntent;

    private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;

@@ -399,6 +402,97 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
    }

    @Test
    public void testShouldNotFullScreen_notPendingIntent() throws RemoteException {
        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
        when(mPowerManager.isInteractive()).thenReturn(true);
        when(mDreamManager.isDreaming()).thenReturn(false);
        when(mStatusBarStateController.getState()).thenReturn(SHADE);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isFalse();
    }

    @Test
    public void testShouldNotFullScreen_notHighImportance() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_DEFAULT, /* silenced */ false);
        when(mPowerManager.isInteractive()).thenReturn(true);
        when(mDreamManager.isDreaming()).thenReturn(false);
        when(mStatusBarStateController.getState()).thenReturn(SHADE);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isFalse();
    }

    @Test
    public void testShouldNotFullScreen_isGroupAlertSilenced() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ true);
        when(mPowerManager.isInteractive()).thenReturn(false);
        when(mDreamManager.isDreaming()).thenReturn(true);
        when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isFalse();
    }

    @Test
    public void testShouldFullScreen_notInteractive() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        when(mPowerManager.isInteractive()).thenReturn(false);
        when(mDreamManager.isDreaming()).thenReturn(false);
        when(mStatusBarStateController.getState()).thenReturn(SHADE);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isTrue();
    }

    @Test
    public void testShouldFullScreen_isDreaming() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        when(mPowerManager.isInteractive()).thenReturn(true);
        when(mDreamManager.isDreaming()).thenReturn(true);
        when(mStatusBarStateController.getState()).thenReturn(SHADE);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isTrue();
    }

    @Test
    public void testShouldFullScreen_onKeyguard() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        when(mPowerManager.isInteractive()).thenReturn(true);
        when(mDreamManager.isDreaming()).thenReturn(false);
        when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isTrue();
    }

    @Test
    public void testShouldNotFullScreen_willHun() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        when(mPowerManager.isInteractive()).thenReturn(true);
        when(mPowerManager.isScreenOn()).thenReturn(true);
        when(mDreamManager.isDreaming()).thenReturn(false);
        when(mStatusBarStateController.getState()).thenReturn(SHADE);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isFalse();
    }

    @Test
    public void testShouldFullScreen_packageSnoozed() throws RemoteException {
        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
        when(mPowerManager.isInteractive()).thenReturn(true);
        when(mPowerManager.isScreenOn()).thenReturn(true);
        when(mDreamManager.isDreaming()).thenReturn(false);
        when(mStatusBarStateController.getState()).thenReturn(SHADE);
        when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);

        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                .isTrue();
    }

    /**
     * Bubbles can happen.
     */
@@ -503,6 +597,10 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
                .setContentText("content text")
                .build();

        return createNotification(importance, n);
    }

    private NotificationEntry createNotification(int importance, Notification n) {
        return new NotificationEntryBuilder()
                .setPkg("a")
                .setOpPkg("a")
@@ -512,6 +610,20 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
                .build();
    }

    private NotificationEntry createFsiNotification(int importance, boolean silent) {
        Notification n = new Notification.Builder(getContext(), "a")
                .setContentTitle("title")
                .setContentText("content text")
                .setFullScreenIntent(mPendingIntent, true)
                .setGroup("fsi")
                .setGroupAlertBehavior(silent
                        ? Notification.GROUP_ALERT_SUMMARY
                        : Notification.GROUP_ALERT_ALL)
                .build();

        return createNotification(importance, n);
    }

    private final NotificationInterruptSuppressor
            mSuppressAwakeHeadsUp =
            new NotificationInterruptSuppressor() {