1 /*
2  * Copyright (C) 2022 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 package com.android.systemui.shade.data.repository
17 
18 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
19 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
20 import com.android.systemui.dagger.SysUISingleton
21 import com.android.systemui.shade.ShadeExpansionChangeEvent
22 import com.android.systemui.shade.ShadeExpansionListener
23 import com.android.systemui.shade.ShadeExpansionStateManager
24 import com.android.systemui.shade.domain.model.ShadeModel
25 import javax.inject.Inject
26 import kotlinx.coroutines.channels.awaitClose
27 import kotlinx.coroutines.flow.Flow
28 import kotlinx.coroutines.flow.MutableStateFlow
29 import kotlinx.coroutines.flow.StateFlow
30 import kotlinx.coroutines.flow.asStateFlow
31 import kotlinx.coroutines.flow.distinctUntilChanged
32 
33 interface ShadeRepository {
34     /** ShadeModel information regarding shade expansion events */
35     val shadeModel: Flow<ShadeModel>
36 
37     /** Amount qs has expanded. Quick Settings can be expanded without the full shade expansion. */
38     val qsExpansion: StateFlow<Float>
39 
40     /** Amount shade has expanded with regard to the UDFPS location */
41     val udfpsTransitionToFullShadeProgress: StateFlow<Float>
42 
43     fun setQsExpansion(qsExpansion: Float)
44     fun setUdfpsTransitionToFullShadeProgress(progress: Float)
45 }
46 
47 /** Business logic for shade interactions */
48 @SysUISingleton
49 class ShadeRepositoryImpl
50 @Inject
51 constructor(shadeExpansionStateManager: ShadeExpansionStateManager) : ShadeRepository {
52     override val shadeModel: Flow<ShadeModel> =
53         conflatedCallbackFlow {
54                 val callback =
55                     object : ShadeExpansionListener {
56                         override fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
57                             // Don't propagate ShadeExpansionChangeEvent.dragDownPxAmount field.
58                             // It is too noisy and produces extra events that consumers won't care
59                             // about
60                             val info =
61                                 ShadeModel(
62                                     expansionAmount = event.fraction,
63                                     isExpanded = event.expanded,
64                                     isUserDragging = event.tracking
65                                 )
66                             trySendWithFailureLogging(info, TAG, "updated shade expansion info")
67                         }
68                     }
69 
70                 val currentState = shadeExpansionStateManager.addExpansionListener(callback)
71                 callback.onPanelExpansionChanged(currentState)
72                 trySendWithFailureLogging(ShadeModel(), TAG, "initial shade expansion info")
73 
74                 awaitClose { shadeExpansionStateManager.removeExpansionListener(callback) }
75             }
76             .distinctUntilChanged()
77 
78     private val _qsExpansion = MutableStateFlow(0f)
79     override val qsExpansion: StateFlow<Float> = _qsExpansion.asStateFlow()
80 
81     private var _udfpsTransitionToFullShadeProgress = MutableStateFlow(0f)
82     override val udfpsTransitionToFullShadeProgress: StateFlow<Float> =
83         _udfpsTransitionToFullShadeProgress.asStateFlow()
84     override fun setQsExpansion(qsExpansion: Float) {
85         _qsExpansion.value = qsExpansion
86     }
87 
88     override fun setUdfpsTransitionToFullShadeProgress(progress: Float) {
89         _udfpsTransitionToFullShadeProgress.value = progress
90     }
91 
92     companion object {
93         private const val TAG = "ShadeRepository"
94     }
95 }
96