diff options
5 files changed, 81 insertions, 2 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt index 887e3494b49e..25e91bed5808 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt @@ -16,6 +16,7 @@ package com.android.systemui.keyguard.ui.composable +import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue @@ -48,6 +49,16 @@ class LockscreenContent( fun SceneScope.Content( modifier: Modifier = Modifier, ) { + val isContentVisible: Boolean by viewModel.isContentVisible.collectAsStateWithLifecycle() + if (!isContentVisible) { + // If the content isn't supposed to be visible, show a large empty box as it's needed + // for scene transition animations (can't just skip rendering everything or shared + // elements won't have correct final/initial bounds from animating in and out of the + // lockscreen scene). + Box(modifier) + return + } + val coroutineScope = rememberCoroutineScope() val blueprintId by viewModel.blueprintId(coroutineScope).collectAsStateWithLifecycle() val view = LocalView.current diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt index de4b999b3899..875e9e0210fb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.android.systemui.keyguard.ui.viewmodel import android.platform.test.flag.junit.FlagsParameterization @@ -27,10 +29,13 @@ import com.android.systemui.flags.Flags import com.android.systemui.flags.andSceneContainer import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository +import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.res.R +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.testKosmos @@ -38,6 +43,8 @@ import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import java.util.Locale +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -201,6 +208,44 @@ class LockscreenContentViewModelTest(flags: FlagsParameterization) : SysuiTestCa } } + @Test + fun isContentVisible_whenNotOccluded_visible() = + with(kosmos) { + testScope.runTest { + val isContentVisible by collectLastValue(underTest.isContentVisible) + + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, null) + runCurrent() + assertThat(isContentVisible).isTrue() + } + } + + @Test + fun isContentVisible_whenOccluded_notVisible() = + with(kosmos) { + testScope.runTest { + val isContentVisible by collectLastValue(underTest.isContentVisible) + + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null) + runCurrent() + assertThat(isContentVisible).isFalse() + } + } + + @Test + fun isContentVisible_whenOccluded_notVisible_evenIfShadeShown() = + with(kosmos) { + testScope.runTest { + val isContentVisible by collectLastValue(underTest.isContentVisible) + keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null) + runCurrent() + + sceneInteractor.snapToScene(Scenes.Shade, "") + runCurrent() + assertThat(isContentVisible).isFalse() + } + } + private fun prepareConfiguration(): Int { val configuration = context.resources.configuration configuration.setLayoutDirection(Locale.US) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt index 1de0abeb931b..8a29f96d3fcd 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt @@ -25,6 +25,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteract import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.res.R +import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor @@ -48,6 +49,7 @@ constructor( val shadeInteractor: ShadeInteractor, @Application private val applicationScope: CoroutineScope, unfoldTransitionInteractor: UnfoldTransitionInteractor, + occlusionInteractor: SceneContainerOcclusionInteractor, ) { @VisibleForTesting val clockSize = clockInteractor.clockSize @@ -93,6 +95,16 @@ constructor( initialValue = UnfoldTranslations(), ) + /** Whether the content of the scene UI should be shown. */ + val isContentVisible: StateFlow<Boolean> = + occlusionInteractor.isOccludingActivityShown + .map { !it } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = true, + ) + fun getSmartSpacePaddingTop(resources: Resources): Int { return if (clockSize.value == ClockSize.LARGE) { resources.getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) + 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 233e9b5bf818..2d510e1cb659 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 @@ -43,8 +43,14 @@ constructor( sceneInteractor: SceneInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, ) { - /** Whether a show-when-locked activity is at the top of the current activity stack. */ - private val isOccludingActivityShown: StateFlow<Boolean> = + /** + * Whether a show-when-locked activity is at the top of the current activity stack. + * + * Note: this isn't enough to figure out whether the scene container UI should be invisible as + * that also depends on the things like the state of AOD and the current scene. If the code + * needs that, [invisibleDueToOcclusion] should be collected instead. + */ + val isOccludingActivityShown: StateFlow<Boolean> = keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop.stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), @@ -69,6 +75,9 @@ constructor( /** * Whether the scene container should become invisible due to "occlusion" by an in-foreground * "show when locked" activity. + * + * Note: this returns `false` when an overlaid scene (like shade or QS) is shown above the + * occluding activity. */ val invisibleDueToOcclusion: StateFlow<Boolean> = combine( diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt index 24e47b0af3fa..550ecb3ea7af 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt @@ -21,6 +21,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardBlueprintInteract import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor @@ -34,5 +35,6 @@ val Kosmos.lockscreenContentViewModel by shadeInteractor = shadeInteractor, applicationScope = applicationCoroutineScope, unfoldTransitionInteractor = unfoldTransitionInteractor, + occlusionInteractor = sceneContainerOcclusionInteractor, ) } |