1 /* <lambda>null2 * Copyright (C) 2023 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.data.repository 20 21 import com.android.compose.animation.scene.ObservableTransitionState 22 import com.android.compose.animation.scene.SceneKey 23 import com.android.compose.animation.scene.TransitionKey 24 import com.android.systemui.dagger.SysUISingleton 25 import com.android.systemui.dagger.qualifiers.Application 26 import com.android.systemui.scene.shared.model.SceneContainerConfig 27 import com.android.systemui.scene.shared.model.SceneDataSource 28 import javax.inject.Inject 29 import kotlinx.coroutines.CoroutineScope 30 import kotlinx.coroutines.ExperimentalCoroutinesApi 31 import kotlinx.coroutines.flow.Flow 32 import kotlinx.coroutines.flow.MutableStateFlow 33 import kotlinx.coroutines.flow.SharingStarted 34 import kotlinx.coroutines.flow.StateFlow 35 import kotlinx.coroutines.flow.asStateFlow 36 import kotlinx.coroutines.flow.flatMapLatest 37 import kotlinx.coroutines.flow.flowOf 38 import kotlinx.coroutines.flow.stateIn 39 40 @SysUISingleton 41 /** Source of truth for scene framework application state. */ 42 class SceneContainerRepository 43 @Inject 44 constructor( 45 @Application applicationScope: CoroutineScope, 46 private val config: SceneContainerConfig, 47 private val dataSource: SceneDataSource, 48 ) { 49 val currentScene: StateFlow<SceneKey> = dataSource.currentScene 50 51 private val _isVisible = MutableStateFlow(true) 52 val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow() 53 54 /** 55 * Whether there's an ongoing remotely-initiated user interaction. 56 * 57 * For more information see the logic in `SceneInteractor` that mutates this. 58 */ 59 val isRemoteUserInteractionOngoing = MutableStateFlow(false) 60 61 private val defaultTransitionState = ObservableTransitionState.Idle(config.initialSceneKey) 62 private val _transitionState = MutableStateFlow<Flow<ObservableTransitionState>?>(null) 63 val transitionState: StateFlow<ObservableTransitionState> = 64 _transitionState 65 .flatMapLatest { innerFlowOrNull -> innerFlowOrNull ?: flowOf(defaultTransitionState) } 66 .stateIn( 67 scope = applicationScope, 68 started = SharingStarted.Eagerly, 69 initialValue = defaultTransitionState, 70 ) 71 72 /** 73 * Returns the keys to all scenes in the container. 74 * 75 * The scenes will be sorted in z-order such that the last one is the one that should be 76 * rendered on top of all previous ones. 77 */ 78 fun allSceneKeys(): List<SceneKey> { 79 return config.sceneKeys 80 } 81 82 fun changeScene( 83 toScene: SceneKey, 84 transitionKey: TransitionKey? = null, 85 ) { 86 dataSource.changeScene( 87 toScene = toScene, 88 transitionKey = transitionKey, 89 ) 90 } 91 92 fun snapToScene( 93 toScene: SceneKey, 94 ) { 95 dataSource.snapToScene( 96 toScene = toScene, 97 ) 98 } 99 100 /** Sets whether the container is visible. */ 101 fun setVisible(isVisible: Boolean) { 102 _isVisible.value = isVisible 103 } 104 105 /** 106 * Binds the given flow so the system remembers it. 107 * 108 * Note that you must call is with `null` when the UI is done or risk a memory leak. 109 */ 110 fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) { 111 _transitionState.value = transitionState 112 } 113 } 114