• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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