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

Commit 8bb45f23 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 am: 722ca990 am: f4b38cba

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



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

        // 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) {
    private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) {
@@ -228,13 +305,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
            return false;
            return false;
        }
        }


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


        if (!inUse) {
        if (!inUse) {
            if (DEBUG_HEADS_UP) {
            if (DEBUG_HEADS_UP) {
+112 −0
Original line number Original line 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 android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;


import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
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.android.systemui.statusbar.StatusBarState.SHADE;


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


    private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;
    private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;


@@ -399,6 +402,97 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
        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.
     * Bubbles can happen.
     */
     */
@@ -503,6 +597,10 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
                .setContentText("content text")
                .setContentText("content text")
                .build();
                .build();


        return createNotification(importance, n);
    }

    private NotificationEntry createNotification(int importance, Notification n) {
        return new NotificationEntryBuilder()
        return new NotificationEntryBuilder()
                .setPkg("a")
                .setPkg("a")
                .setOpPkg("a")
                .setOpPkg("a")
@@ -512,6 +610,20 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
                .build();
                .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
    private final NotificationInterruptSuppressor
            mSuppressAwakeHeadsUp =
            mSuppressAwakeHeadsUp =
            new NotificationInterruptSuppressor() {
            new NotificationInterruptSuppressor() {