From ee98de193f8a6cf6ca6882029d1d09542e472a94 Mon Sep 17 00:00:00 2001 From: Alejandro Nijamkin Date: Fri, 29 Mar 2024 14:27:44 -0700 Subject: [flexiglass] Fixes back/home navigation when occluded. Before this, back or home navigation when the lockscreen is occluded by another activity (for example, the camera app when locked) didn't work. This CL fixes that issue. The approach is one where SysUiState is hydrated with SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED when on lockscreen and occluded instead of SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING when on lockscreen but not occluded. For posterity, the command used to figure out the difference betwene SysUiState flags with Flexiglas on and off was: $ adb shell dumpsys activity service com.android.systemui/.SystemUIService SysUiState Fix: 308001302 Test: unit tests added Test: manually verified that back and home gesture both work when showing the camera app on top of the locked device Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT Change-Id: I707a46b502ad7697985794084b05f35493bcdf19 --- .../startable/SceneContainerStartableTest.kt | 46 +++++++++++++- .../android/systemui/model/SceneContainerPlugin.kt | 42 ++++++++++--- .../SceneContainerOcclusionInteractor.kt | 72 ++++++++++++++++++---- .../domain/startable/SceneContainerStartable.kt | 20 ++++-- .../systemui/model/SceneContainerPluginKosmos.kt | 8 ++- .../com/android/systemui/model/SysUiStateKosmos.kt | 28 +++++++++ .../SceneContainerOcclusionInteractorKosmos.kt | 2 + .../systemui/settings/DisplayTrackerKosmos.kt | 27 ++++++++ 8 files changed, 214 insertions(+), 31 deletions(-) create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/settings/DisplayTrackerKosmos.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index 605e5c067eab..36859e729daa 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -42,7 +42,7 @@ import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepo import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.kosmos.testScope -import com.android.systemui.model.SysUiState +import com.android.systemui.model.sysUiState import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.PowerInteractorFactory @@ -51,6 +51,7 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.shared.model.fakeSceneDataSource +import com.android.systemui.shared.system.QuickStepContract import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository @@ -78,6 +79,7 @@ import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never +import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -99,7 +101,7 @@ class SceneContainerStartableTest : SysuiTestCase() { private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository } private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor } private val keyguardInteractor by lazy { kosmos.keyguardInteractor } - private val sysUiState: SysUiState = mock() + private val sysUiState = spy(kosmos.sysUiState) private val falsingCollector: FalsingCollector = mock() private val powerInteractor = PowerInteractorFactory.create().powerInteractor private val fakeSceneDataSource = kosmos.fakeSceneDataSource @@ -397,6 +399,46 @@ class SceneContainerStartableTest : SysuiTestCase() { } } + @Test + fun hydrateSystemUiState_onLockscreen_basedOnOcclusion() = + testScope.runTest { + prepareState( + initialSceneKey = Scenes.Lockscreen, + ) + underTest.start() + runCurrent() + clearInvocations(sysUiState) + + kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( + true, + mock() + ) + runCurrent() + assertThat( + sysUiState.flags and + QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED != 0 + ) + .isTrue() + assertThat( + sysUiState.flags and + QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0 + ) + .isFalse() + + kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(false) + runCurrent() + assertThat( + sysUiState.flags and + QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED != 0 + ) + .isFalse() + assertThat( + sysUiState.flags and + QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0 + ) + .isTrue() + } + @Test fun switchToGoneWhenDeviceStartsToWakeUp_authMethodNone() = testScope.runTest { diff --git a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt index e7b6e6373f1c..170481233504 100644 --- a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt +++ b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt @@ -19,6 +19,7 @@ package com.android.systemui.model import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes @@ -27,6 +28,7 @@ import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICA import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING +import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED import dagger.Lazy import javax.inject.Inject @@ -38,8 +40,10 @@ import javax.inject.Inject class SceneContainerPlugin @Inject constructor( - private val interactor: Lazy, + private val sceneInteractor: Lazy, + private val occlusionInteractor: Lazy, ) { + /** * Returns an override value for the given [flag] or `null` if the scene framework isn't enabled * or if the flag value doesn't need to be overridden. @@ -49,10 +53,18 @@ constructor( return null } - val transitionState = interactor.get().transitionState.value + val transitionState = sceneInteractor.get().transitionState.value val idleTransitionStateOrNull = transitionState as? ObservableTransitionState.Idle val currentSceneOrNull = idleTransitionStateOrNull?.scene - return currentSceneOrNull?.let { sceneKey -> EvaluatorByFlag[flag]?.invoke(sceneKey) } + val invisibleDueToOcclusion = occlusionInteractor.get().invisibleDueToOcclusion.value + return currentSceneOrNull?.let { sceneKey -> + EvaluatorByFlag[flag]?.invoke( + SceneContainerPluginState( + scene = sceneKey, + invisibleDueToOcclusion = invisibleDueToOcclusion, + ) + ) + } } companion object { @@ -67,12 +79,24 @@ constructor( * to be overridden by the scene framework. */ val EvaluatorByFlag = - mapOf Boolean>( - SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to { it != Scenes.Gone }, - SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to { it == Scenes.Shade }, - SYSUI_STATE_QUICK_SETTINGS_EXPANDED to { it == Scenes.QuickSettings }, - SYSUI_STATE_BOUNCER_SHOWING to { it == Scenes.Bouncer }, - SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING to { it == Scenes.Lockscreen }, + mapOf Boolean>( + SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to { it.scene != Scenes.Gone }, + SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to { it.scene == Scenes.Shade }, + SYSUI_STATE_QUICK_SETTINGS_EXPANDED to { it.scene == Scenes.QuickSettings }, + SYSUI_STATE_BOUNCER_SHOWING to { it.scene == Scenes.Bouncer }, + SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING to + { + it.scene == Scenes.Lockscreen && !it.invisibleDueToOcclusion + }, + SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED to + { + it.scene == Scenes.Lockscreen && it.invisibleDueToOcclusion + }, ) } + + data class SceneContainerPluginState( + val scene: SceneKey, + val invisibleDueToOcclusion: Boolean, + ) } diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt index a82391643e11..5d60373c6e13 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt @@ -19,45 +19,91 @@ package com.android.systemui.scene.domain.interactor import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.domain.interactor.KeyguardOcclusionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.scene.shared.model.Scenes import javax.inject.Inject -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.stateIn /** Encapsulates logic regarding the occlusion state of the scene container. */ @SysUISingleton class SceneContainerOcclusionInteractor @Inject constructor( + @Application applicationScope: CoroutineScope, keyguardOcclusionInteractor: KeyguardOcclusionInteractor, sceneInteractor: SceneInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, ) { + /** Whether a show-when-locked activity is at the top of the current activity stack. */ + private val isOccludingActivityShown: StateFlow = + keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop.stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = false, + ) + + /** + * Whether AOD is fully shown (not transitioning) or partially shown during a transition to/from + * AOD. + */ + private val isAodFullyOrPartiallyShown: StateFlow = + keyguardTransitionInteractor + .transitionValue(KeyguardState.AOD) + .onStart { emit(0f) } + .map { it > 0 } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = false, + ) + /** * Whether the scene container should become invisible due to "occlusion" by an in-foreground * "show when locked" activity. */ - val invisibleDueToOcclusion: Flow = + val invisibleDueToOcclusion: StateFlow = combine( - keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop, + isOccludingActivityShown, sceneInteractor.transitionState, - keyguardTransitionInteractor - .transitionValue(KeyguardState.AOD) - .onStart { emit(0f) } - .map { it > 0 } - .distinctUntilChanged(), + isAodFullyOrPartiallyShown, ) { isOccludingActivityShown, sceneTransitionState, isAodFullyOrPartiallyShown -> - isOccludingActivityShown && - !isAodFullyOrPartiallyShown && - sceneTransitionState.canBeOccluded + invisibleDueToOcclusion( + isOccludingActivityShown = isOccludingActivityShown, + sceneTransitionState = sceneTransitionState, + isAodFullyOrPartiallyShown = isAodFullyOrPartiallyShown, + ) } - .distinctUntilChanged() + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = + invisibleDueToOcclusion( + isOccludingActivityShown = isOccludingActivityShown.value, + sceneTransitionState = sceneInteractor.transitionState.value, + isAodFullyOrPartiallyShown = isAodFullyOrPartiallyShown.value, + ), + ) + + private fun invisibleDueToOcclusion( + isOccludingActivityShown: Boolean, + sceneTransitionState: ObservableTransitionState, + isAodFullyOrPartiallyShown: Boolean, + ): Boolean { + return isOccludingActivityShown && + // Cannot be occluded in AOD. + !isAodFullyOrPartiallyShown && + // Only some scenes can be occluded. + sceneTransitionState.canBeOccluded + } private val ObservableTransitionState.canBeOccluded: Boolean get() = diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index 0e4049bbd21e..e911ce17b395 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -317,15 +317,23 @@ constructor( /** Keeps [SysUiState] up-to-date */ private fun hydrateSystemUiState() { applicationScope.launch { - sceneInteractor.transitionState - .mapNotNull { it as? ObservableTransitionState.Idle } - .map { it.scene } - .distinctUntilChanged() - .collect { sceneKey -> + combine( + sceneInteractor.transitionState + .mapNotNull { it as? ObservableTransitionState.Idle } + .map { it.scene } + .distinctUntilChanged(), + occlusionInteractor.invisibleDueToOcclusion, + ) { sceneKey, invisibleDueToOcclusion -> + SceneContainerPlugin.SceneContainerPluginState( + scene = sceneKey, + invisibleDueToOcclusion = invisibleDueToOcclusion, + ) + } + .collect { sceneContainerPluginState -> sysUiState.updateFlags( displayId, *SceneContainerPlugin.EvaluatorByFlag.map { (flag, evaluator) -> - flag to evaluator.invoke(sceneKey) + flag to evaluator.invoke(sceneContainerPluginState) } .toTypedArray(), ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt index b1027b923a26..d19dfe8d74fb 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt @@ -18,6 +18,12 @@ package com.android.systemui.model import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor -val Kosmos.sceneContainerPlugin by Fixture { SceneContainerPlugin { sceneInteractor } } +val Kosmos.sceneContainerPlugin by Fixture { + SceneContainerPlugin( + sceneInteractor = { sceneInteractor }, + occlusionInteractor = { sceneContainerOcclusionInteractor }, + ) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt new file mode 100644 index 000000000000..8faeb39d24b9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.model + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.settings.displayTracker + +val Kosmos.sysUiState by Fixture { + SysUiState( + displayTracker, + sceneContainerPlugin, + ) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt index b32960a73178..9bd55813a63d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt @@ -19,10 +19,12 @@ package com.android.systemui.scene.domain.interactor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor val Kosmos.sceneContainerOcclusionInteractor by Fixture { SceneContainerOcclusionInteractor( + applicationScope = applicationCoroutineScope, keyguardOcclusionInteractor = keyguardOcclusionInteractor, sceneInteractor = sceneInteractor, keyguardTransitionInteractor = keyguardTransitionInteractor, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/DisplayTrackerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/DisplayTrackerKosmos.kt new file mode 100644 index 000000000000..7ac9680c48c4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/DisplayTrackerKosmos.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.content.applicationContext +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture + +val Kosmos.displayTracker by Fixture { + FakeDisplayTracker( + context = applicationContext, + ) +} -- cgit v1.2.3-59-g8ed1b From 7212fb02d4960131fcd17d0787432788e46f5aba Mon Sep 17 00:00:00 2001 From: Alejandro Nijamkin Date: Sat, 30 Mar 2024 16:24:27 -0700 Subject: [flexiglass] Clicks on shade empty space go back to lockscreen. Instead of attempting to enter the device and/or show the bouncer. It doesn't quite fix b/330696389 yet because the clicks aren't being passed to the clickable in the shade scene composable yet. Bug: 330696389 Test: unit tests ammended Test: manually verified that clicking on the empty space in the shade below the notifications still doesn't do anything, so no damage done Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT Change-Id: Id4e6a2abf77d43818a172381751a0aebed9196cf --- .../systemui/scene/SceneFrameworkIntegrationTest.kt | 1 + .../shade/ui/viewmodel/ShadeSceneViewModelTest.kt | 20 +++----------------- .../shade/ui/viewmodel/ShadeSceneViewModel.kt | 12 ++++++++++-- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt index efbdb7d466d1..4d22383bd2a4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt @@ -261,6 +261,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { shadeInteractor = kosmos.shadeInteractor, footerActionsController = kosmos.footerActionsController, footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory, + sceneInteractor = sceneInteractor, ) kosmos.fakeDeviceEntryRepository.setUnlocked(false) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt index f90a3b14f968..1d6b22309579 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt @@ -129,6 +129,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() { shadeInteractor = kosmos.shadeInteractor, footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory, footerActionsController = kosmos.footerActionsController, + sceneInteractor = kosmos.sceneInteractor, ) } @@ -215,22 +216,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() { } @Test - fun onContentClicked_deviceUnlocked_switchesToGone() = - testScope.runTest { - val currentScene by collectLastValue(sceneInteractor.currentScene) - kosmos.fakeAuthenticationRepository.setAuthenticationMethod( - AuthenticationMethodModel.Pin - ) - kosmos.fakeDeviceEntryRepository.setUnlocked(true) - runCurrent() - - underTest.onContentClicked() - - assertThat(currentScene).isEqualTo(Scenes.Gone) - } - - @Test - fun onContentClicked_deviceLockedSecurely_switchesToBouncer() = + fun onContentClicked_deviceLockedSecurely_switchesToLockscreen() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( @@ -241,7 +227,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() { underTest.onContentClicked() - assertThat(currentScene).isEqualTo(Scenes.Bouncer) + assertThat(currentScene).isEqualTo(Scenes.Lockscreen) } @Test diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt index 24b7533d6c26..9362cd058929 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt @@ -31,6 +31,7 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDataManager import com.android.systemui.qs.FooterActionsController import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.ui.adapter.QSSceneAdapter +import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode @@ -52,7 +53,7 @@ class ShadeSceneViewModel @Inject constructor( @Application private val applicationScope: CoroutineScope, - private val deviceEntryInteractor: DeviceEntryInteractor, + deviceEntryInteractor: DeviceEntryInteractor, val qsSceneAdapter: QSSceneAdapter, val shadeHeaderViewModel: ShadeHeaderViewModel, val notifications: NotificationsPlaceholderViewModel, @@ -60,6 +61,7 @@ constructor( shadeInteractor: ShadeInteractor, private val footerActionsViewModelFactory: FooterActionsViewModel.Factory, private val footerActionsController: FooterActionsController, + private val sceneInteractor: SceneInteractor, ) { val destinationScenes: StateFlow> = combine( @@ -103,7 +105,13 @@ constructor( val shadeMode: StateFlow = shadeInteractor.shadeMode /** Notifies that some content in the shade was clicked. */ - fun onContentClicked() = deviceEntryInteractor.attemptDeviceEntry() + fun onContentClicked() { + if (!isClickable.value) { + return + } + + sceneInteractor.changeScene(Scenes.Lockscreen, "Shade empty content clicked") + } fun isMediaVisible(): Boolean { // TODO(b/296122467): handle updates to carousel visibility while scene is still visible -- cgit v1.2.3-59-g8ed1b