Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt +66 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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( Loading Loading @@ -311,6 +366,7 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() { kosmos.notificationRemoteInputManager, /* remoteInputManagerCallback = */ mock(), /* notificationListContainer = */ mock(), kosmos.deviceUnlockedInteractor, ) .also { initController.executePostInitTasks() } } Loading Loading @@ -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 = Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +21 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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)); Loading Loading @@ -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; Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt +66 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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( Loading Loading @@ -311,6 +366,7 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() { kosmos.notificationRemoteInputManager, /* remoteInputManagerCallback = */ mock(), /* notificationListContainer = */ mock(), kosmos.deviceUnlockedInteractor, ) .also { initController.executePostInitTasks() } } Loading Loading @@ -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 = Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +21 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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)); Loading Loading @@ -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; Loading