1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 @file:OptIn(ExperimentalCoroutinesApi::class) 18 19 package com.android.systemui.scene.domain.resolver 20 21 import com.android.compose.animation.scene.SceneKey 22 import com.android.systemui.dagger.SysUISingleton 23 import com.android.systemui.dagger.qualifiers.Application 24 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor 25 import com.android.systemui.scene.shared.model.SceneFamilies 26 import com.android.systemui.scene.shared.model.Scenes 27 import dagger.Binds 28 import dagger.Module 29 import dagger.multibindings.IntoSet 30 import javax.inject.Inject 31 import kotlinx.coroutines.CoroutineScope 32 import kotlinx.coroutines.ExperimentalCoroutinesApi 33 import kotlinx.coroutines.flow.SharingStarted 34 import kotlinx.coroutines.flow.StateFlow 35 import kotlinx.coroutines.flow.combine 36 import kotlinx.coroutines.flow.stateIn 37 38 /** 39 * Resolver for [SceneFamilies.Home]. The "home" scene family resolves to the scene that is 40 * currently underneath any "overlay" scene, such as shades or bouncer. 41 */ 42 @SysUISingleton 43 class HomeSceneFamilyResolver 44 @Inject 45 constructor( 46 @Application private val applicationScope: CoroutineScope, 47 deviceEntryInteractor: DeviceEntryInteractor, 48 ) : SceneResolver { 49 override val targetFamily: SceneKey = SceneFamilies.Home 50 51 override val resolvedScene: StateFlow<SceneKey> = 52 combine( 53 deviceEntryInteractor.canSwipeToEnter, 54 deviceEntryInteractor.isDeviceEntered, 55 deviceEntryInteractor.isUnlocked, 56 transform = ::homeScene, 57 ) 58 .stateIn( 59 scope = applicationScope, 60 started = SharingStarted.Eagerly, 61 initialValue = 62 homeScene( 63 deviceEntryInteractor.canSwipeToEnter.value, 64 deviceEntryInteractor.isDeviceEntered.value, 65 deviceEntryInteractor.isUnlocked.value, 66 ) 67 ) 68 includesScenenull69 override fun includesScene(scene: SceneKey): Boolean = scene in homeScenes 70 71 private fun homeScene( 72 canSwipeToEnter: Boolean?, 73 isDeviceEntered: Boolean, 74 isUnlocked: Boolean, 75 ): SceneKey = 76 when { 77 canSwipeToEnter == true -> Scenes.Lockscreen 78 !isDeviceEntered -> Scenes.Lockscreen 79 !isUnlocked -> Scenes.Lockscreen 80 else -> Scenes.Gone 81 } 82 83 companion object { 84 val homeScenes = 85 setOf( 86 Scenes.Gone, 87 Scenes.Lockscreen, 88 ) 89 } 90 } 91 92 @Module 93 interface HomeSceneFamilyResolverModule { provideSceneResolvernull94 @Binds @IntoSet fun provideSceneResolver(interactor: HomeSceneFamilyResolver): SceneResolver 95 } 96