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 package com.android.systemui.communal.data.repository 18 19 import android.content.res.Configuration 20 import com.android.app.tracing.coroutines.launchTraced as launch 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.communal.dagger.Communal 25 import com.android.systemui.communal.shared.model.CommunalScenes 26 import com.android.systemui.dagger.SysUISingleton 27 import com.android.systemui.dagger.qualifiers.Background 28 import com.android.systemui.scene.shared.model.SceneDataSource 29 import javax.inject.Inject 30 import kotlinx.coroutines.CoroutineScope 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 /** Encapsulates the state of communal mode. */ 41 interface CommunalSceneRepository { 42 /** 43 * Target scene as requested by the underlying [SceneTransitionLayout] or through [changeScene]. 44 */ 45 val currentScene: StateFlow<SceneKey> 46 47 /** Exposes the transition state of the communal [SceneTransitionLayout]. */ 48 val transitionState: StateFlow<ObservableTransitionState> 49 50 /** Current orientation of the communal container. */ 51 val communalContainerOrientation: StateFlow<Int> 52 53 /** Updates the requested scene. */ 54 fun changeScene(toScene: SceneKey, transitionKey: TransitionKey? = null) 55 56 /** Immediately snaps to the desired scene. */ 57 fun snapToScene(toScene: SceneKey) 58 59 /** 60 * Updates the transition state of the hub [SceneTransitionLayout]. 61 * 62 * Note that you must call is with `null` when the UI is done or risk a memory leak. 63 */ 64 fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) 65 66 /** Set the current orientation of the communal container. */ 67 fun setCommunalContainerOrientation(orientation: Int) 68 } 69 70 @SysUISingleton 71 class CommunalSceneRepositoryImpl 72 @Inject 73 constructor( 74 @Background backgroundScope: CoroutineScope, 75 @Communal private val sceneDataSource: SceneDataSource, 76 ) : CommunalSceneRepository { 77 78 override val currentScene: StateFlow<SceneKey> = sceneDataSource.currentScene 79 80 private val defaultTransitionState = ObservableTransitionState.Idle(CommunalScenes.Default) 81 private val _transitionState = MutableStateFlow<Flow<ObservableTransitionState>?>(null) 82 override val transitionState: StateFlow<ObservableTransitionState> = 83 _transitionState innerFlowOrNullnull84 .flatMapLatest { innerFlowOrNull -> innerFlowOrNull ?: flowOf(defaultTransitionState) } 85 .stateIn( 86 scope = backgroundScope, 87 started = SharingStarted.Lazily, 88 initialValue = defaultTransitionState, 89 ) 90 91 private val _communalContainerOrientation = 92 MutableStateFlow(Configuration.ORIENTATION_UNDEFINED) 93 override val communalContainerOrientation: StateFlow<Int> = 94 _communalContainerOrientation.asStateFlow() 95 changeScenenull96 override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) { 97 sceneDataSource.changeScene(toScene, transitionKey) 98 } 99 snapToScenenull100 override fun snapToScene(toScene: SceneKey) { 101 sceneDataSource.snapToScene(toScene) 102 } 103 setCommunalContainerOrientationnull104 override fun setCommunalContainerOrientation(orientation: Int) { 105 _communalContainerOrientation.value = orientation 106 } 107 108 /** 109 * Updates the transition state of the hub [SceneTransitionLayout]. 110 * 111 * Note that you must call is with `null` when the UI is done or risk a memory leak. 112 */ setTransitionStatenull113 override fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) { 114 _transitionState.value = transitionState 115 } 116 } 117