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

Commit 9c36887a authored by András Kurucz's avatar András Kurucz Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Show the bouncer over the locked shade from notifications" into main

parents 50e857a9 d50e0d81
Loading
Loading
Loading
Loading
+66 −3
Original line number Diff line number Diff line
@@ -28,13 +28,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.InitController
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.runTest
import com.android.systemui.plugins.activityStarter
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.settings.FakeDisplayTracker
import com.android.systemui.shade.domain.interactor.panelExpansionInteractor
import com.android.systemui.shade.notificationShadeWindowView
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.commandQueue
import com.android.systemui.statusbar.lockscreenShadeTransitionController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -47,6 +53,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionFilter
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.visualInterruptionDecisionProvider
import com.android.systemui.statusbar.notificationLockscreenUserManager
@@ -61,7 +68,9 @@ import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@@ -282,6 +291,52 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() {
        assertThat(types).contains(VisualInterruptionType.BUBBLE)
    }

    @Test
    @EnableSceneContainer
    fun testExpandSensitiveNotification_onLockScreen_opensShade() =
        kosmos.runTest {
            // Given we are on the keyguard
            kosmos.sysuiStatusBarStateController.state = StatusBarState.KEYGUARD
            // And the device is locked
            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.Pin
            )

            // When the user expands a sensitive Notification
            val row = createRow()
            val entry =
                row.entry.apply { setSensitive(/* sensitive= */ true, /* deviceSensitive= */ true) }

            underTest.onExpandClicked(entry, mock(), /* nowExpanded= */ true)

            // Then we open the locked shade
            verify(kosmos.lockscreenShadeTransitionController)
                // Explicit parameters to avoid issues with Kotlin default arguments in Mockito
                .goToLockedShade(row, true)
        }

    @Test
    @EnableSceneContainer
    fun testExpandSensitiveNotification_onLockedShade_showsBouncer() =
        kosmos.runTest {
            // Given we are on the locked shade
            kosmos.sysuiStatusBarStateController.state = StatusBarState.SHADE_LOCKED
            // And the device is locked
            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.Pin
            )

            // When the user expands a sensitive Notification
            val entry =
                createRow().entry.apply {
                    setSensitive(/* sensitive= */ true, /* deviceSensitive= */ true)
                }
            underTest.onExpandClicked(entry, mock(), /* nowExpanded= */ true)

            // Then we show the bouncer
            verify(kosmos.activityStarter).dismissKeyguardThenExecute(any(), eq(null), eq(false))
        }

    private fun createPresenter(): StatusBarNotificationPresenter {
        val initController: InitController = InitController()
        return StatusBarNotificationPresenter(
@@ -311,6 +366,7 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() {
                kosmos.notificationRemoteInputManager,
                /* remoteInputManagerCallback = */ mock(),
                /* notificationListContainer = */ mock(),
                kosmos.deviceUnlockedInteractor,
            )
            .also { initController.executePostInitTasks() }
    }
@@ -342,14 +398,21 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() {
        interruptSuppressor = suppressorCaptor.lastValue
    }

    private fun createNotificationEntry(): NotificationEntry {
        return NotificationEntryBuilder()
    private fun createRow(): ExpandableNotificationRow {
        val row: ExpandableNotificationRow = mock()
        val entry: NotificationEntry = createNotificationEntry()
        whenever(row.entry).thenReturn(entry)
        entry.row = row
        return row
    }

    private fun createNotificationEntry(): NotificationEntry =
        NotificationEntryBuilder()
            .setPkg("a")
            .setOpPkg("a")
            .setTag("a")
            .setNotification(Builder(mContext, "a").build())
            .build()
    }

    private fun createFsiNotificationEntry(): NotificationEntry {
        val notification: Notification =
+21 −5
Original line number Diff line number Diff line
@@ -37,10 +37,12 @@ import androidx.annotation.NonNull;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.InitController;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeViewController;
@@ -59,6 +61,7 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.domain.interactor.NotificationAlertsInteractor;
import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionCondition;
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider;
@@ -69,7 +72,6 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import java.util.Set;
@@ -102,6 +104,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu
    private final IStatusBarService mBarService;
    private final DynamicPrivacyController mDynamicPrivacyController;
    private final NotificationListContainer mNotifListContainer;
    private final DeviceUnlockedInteractor mDeviceUnlockedInteractor;
    private final QuickSettingsController mQsController;

    protected boolean mVrMode;
@@ -133,7 +136,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu
            VisualInterruptionDecisionProvider visualInterruptionDecisionProvider,
            NotificationRemoteInputManager remoteInputManager,
            NotificationRemoteInputManager.Callback remoteInputManagerCallback,
            NotificationListContainer notificationListContainer) {
            NotificationListContainer notificationListContainer,
            DeviceUnlockedInteractor deviceUnlockedInteractor) {
        mActivityStarter = activityStarter;
        mKeyguardStateController = keyguardStateController;
        mNotificationPanel = panel;
@@ -160,6 +164,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu
        mBarService = IStatusBarService.Stub.asInterface(
                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
        mNotifListContainer = notificationListContainer;
        mDeviceUnlockedInteractor = deviceUnlockedInteractor;

        IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
                Context.VR_SERVICE));
@@ -246,16 +251,27 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu
        mPowerInteractor.wakeUpIfDozing("NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
        if (nowExpanded) {
            if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
                mShadeTransitionController.goToLockedShade(clickedEntry.getRow());
            } else if (clickedEntry.isSensitive().getValue()
                    && mDynamicPrivacyController.isInLockedDownShade()) {
                mShadeTransitionController.goToLockedShade(
                        clickedEntry.getRow(), /* needsQSAnimation = */ true);
            } else if (clickedEntry.isSensitive().getValue() && isInLockedDownShade()) {
                mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
                // launch the bouncer if the device is locked
                mActivityStarter.dismissKeyguardThenExecute(() -> false /* dismissAction */
                        , null /* cancelRunnable */, false /* afterKeyguardGone */);
            }
        }
    }

    /** @return true if the Shade is shown over the Lockscreen, and the device is locked */
    private boolean isInLockedDownShade() {
        if (SceneContainerFlag.isEnabled()) {
            return mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
                    && !mDeviceUnlockedInteractor.getDeviceUnlockStatus().getValue().isUnlocked();
        } else {
            return mDynamicPrivacyController.isInLockedDownShade();
        }
    }

    @Override
    public boolean isDeviceInVrMode() {
        return mVrMode;