diff options
11 files changed, 228 insertions, 50 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/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 @@ -398,6 +400,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 { val currentSceneKey by collectLastValue(sceneInteractor.currentScene) 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/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<SceneInteractor>, + private val sceneInteractor: Lazy<SceneInteractor>, + private val occlusionInteractor: Lazy<SceneContainerOcclusionInteractor>, ) { + /** * 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<Int, (SceneKey) -> 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<Int, (SceneContainerPluginState) -> 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<Boolean> = + 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<Boolean> = + 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<Boolean> = + val invisibleDueToOcclusion: StateFlow<Boolean> = 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/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<Map<UserAction, UserActionResult>> = combine( @@ -103,7 +105,13 @@ constructor( val shadeMode: StateFlow<ShadeMode> = 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 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, + ) +} |