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.dagger.SysUISingleton
19 import com.android.systemui.shade.shared.flag.DualShade
20 import com.android.systemui.shade.shared.model.ShadeMode
21 import javax.inject.Inject
22 import kotlinx.coroutines.flow.MutableStateFlow
23 import kotlinx.coroutines.flow.StateFlow
24 import kotlinx.coroutines.flow.asStateFlow
25 
26 /** Data for the shade, mostly related to expansion of the shade and quick settings. */
27 interface ShadeRepository {
28     /**
29      * Amount qs has expanded, [0-1]. 0 means fully collapsed, 1 means fully expanded. Quick
30      * Settings can be expanded without the full shade expansion.
31      */
32     @Deprecated("Use ShadeInteractor.qsExpansion instead") val qsExpansion: StateFlow<Float>
33 
34     /** Amount shade has expanded with regard to the UDFPS location */
35     val udfpsTransitionToFullShadeProgress: StateFlow<Float>
36 
37     /**
38      * Information about the currently running fling animation, or null if no fling animation is
39      * running.
40      */
41     val currentFling: StateFlow<FlingInfo?>
42 
43     /**
44      * The amount the lockscreen shade has dragged down by the user, [0-1]. 0 means fully collapsed,
45      * 1 means fully expanded. Value resets to 0 when the user finishes dragging.
46      */
47     val lockscreenShadeExpansion: StateFlow<Float>
48 
49     /**
50      * NotificationPanelViewController.mExpandedFraction as a StateFlow. This nominally represents
51      * the amount the shade has expanded 0-1 like many other flows in this repo, but there are cases
52      * where its value will be 1 and no shade will be rendered, e.g. whenever the keyguard is
53      * visible and when quick settings is expanded. The confusing nature and impending deletion of
54      * this makes it unsuitable for future development, so usage is discouraged.
55      */
56     @Deprecated("Use ShadeInteractor.shadeExpansion instead")
57     val legacyShadeExpansion: StateFlow<Float>
58 
59     /**
60      * NotificationPanelViewController.mTracking as a flow. "Tracking" means that the user is moving
61      * the shade up or down with a pointer. Going forward, this concept will be replaced by checks
62      * for whether a transition was driven by user input instead of whether a pointer is currently
63      * touching the screen, i.e. after the user has lifted their finger to fling the shade, these
64      * values would be different.
65      */
66     @Deprecated("Use ShadeInteractor instead") val legacyShadeTracking: StateFlow<Boolean>
67 
68     /** Specifically tracks the user expanding the shade on the lockscreen only */
69     @Deprecated("Use ShadeInteractor.isUserInteractingWithShade instead")
70     val legacyLockscreenShadeTracking: MutableStateFlow<Boolean>
71 
72     /**
73      * QuickSettingsController.mTracking as a flow. "Tracking" means that the user is moving quick
74      * settings up or down with a pointer. Going forward, this concept will be replaced by checks
75      * for whether a transition was driven by user input instead of whether a pointer is currently
76      * touching the screen, i.e. after the user has lifted their finger to fling the QS, these
77      * values would be different.
78      */
79     @Deprecated("Use ShadeInteractor instead") val legacyQsTracking: StateFlow<Boolean>
80 
81     /**
82      * NotificationPanelViewController.mPanelExpanded as a flow. This value is true whenever the
83      * expansion fraction is greater than zero or NPVC is about to accept an input transfer from the
84      * status bar, home screen, or trackpad.
85      */
86     @Deprecated("Use ShadeInteractor instead")
87     val legacyExpandedOrAwaitingInputTransfer: StateFlow<Boolean>
88 
89     /**
90      * QuickSettingsController.mExpanded as a flow. Indicates that QS is in expanded state:
91      * - single pane shade: expanding shade and then expanding QS
92      * - split shade: just expanding shade (QS are expanded automatically)
93      */
94     @Deprecated("Use ShadeInteractor instead") val legacyIsQsExpanded: StateFlow<Boolean>
95 
96     /**
97      * QuickSettingsController.mExpandImmediate as a flow. Indicates that Quick Settings is being
98      * expanded without first expanding the Shade or Quick Settings is being collapsed without first
99      * collapsing to shade, i.e. expanding with 2-finger swipe or collapsing by flinging from the
100      * bottom of the screen. Replaced by ShadeInteractor.isQsBypassingShade.
101      */
102     @Deprecated("Use ShadeInteractor.isQsBypassingShade instead")
103     val legacyExpandImmediate: StateFlow<Boolean>
104 
105     val shadeMode: StateFlow<ShadeMode>
106 
107     /** True when QS is taking up the entire screen, i.e. fully expanded on a non-unfolded phone. */
108     @Deprecated("Use ShadeInteractor instead") val legacyQsFullscreen: StateFlow<Boolean>
109 
110     /** NPVC.mClosing as a flow. */
111     @Deprecated("Use ShadeAnimationInteractor instead") val legacyIsClosing: StateFlow<Boolean>
112 
setShadeModenull113     fun setShadeMode(mode: ShadeMode)
114 
115     /** Sets whether a closing animation is happening. */
116     @Deprecated("Use ShadeAnimationInteractor instead") fun setLegacyIsClosing(isClosing: Boolean)
117 
118     /**  */
119     @Deprecated("Use ShadeInteractor instead")
120     fun setLegacyQsFullscreen(legacyQsFullscreen: Boolean)
121 
122     /**
123      * Sets whether Quick Settings is being expanded without first expanding the Shade or Quick
124      * Settings is being collapsed without first collapsing to shade.
125      */
126     @Deprecated("Use ShadeInteractor instead")
127     fun setLegacyExpandImmediate(legacyExpandImmediate: Boolean)
128 
129     /** Sets whether QS is expanded. */
130     @Deprecated("Use ShadeInteractor instead")
131     fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean)
132 
133     /**
134      * Sets whether the expansion fraction is greater than zero or NPVC is about to accept an input
135      * transfer from the status bar, home screen, or trackpad.
136      */
137     @Deprecated("Use ShadeInteractor instead")
138     fun setLegacyExpandedOrAwaitingInputTransfer(legacyExpandedOrAwaitingInputTransfer: Boolean)
139 
140     /** Sets whether the user is moving Quick Settings with a pointer */
141     @Deprecated("Use ShadeInteractor instead") fun setLegacyQsTracking(legacyQsTracking: Boolean)
142 
143     /** Sets whether the user is moving the shade with a pointer */
144     @Deprecated("Use ShadeInteractor instead") fun setLegacyShadeTracking(tracking: Boolean)
145 
146     /** Sets whether the user is moving the shade with a pointer, on lockscreen only */
147     @Deprecated("Use ShadeInteractor instead")
148     fun setLegacyLockscreenShadeTracking(tracking: Boolean)
149 
150     /** The amount QS has expanded without notifications */
151     fun setQsExpansion(qsExpansion: Float)
152 
153     fun setUdfpsTransitionToFullShadeProgress(progress: Float)
154 
155     /**
156      * Sets the [FlingInfo] of the currently animating fling. If [info] is null, no fling is
157      * animating.
158      */
159     fun setCurrentFling(info: FlingInfo?)
160 
161     /**
162      * Set the amount the shade has dragged down by the user, [0-1]. 0 means fully collapsed, 1
163      * means fully expanded.
164      */
165     fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float)
166 
167     /**
168      * Set the legacy expansion value. This should only be called whenever the value of
169      * NotificationPanelViewController.mExpandedFraction changes or in tests.
170      */
171     @Deprecated("Should only be called by NPVC and tests")
172     fun setLegacyShadeExpansion(expandedFraction: Float)
173 }
174 
175 /** Business logic for shade interactions */
176 @SysUISingleton
177 class ShadeRepositoryImpl @Inject constructor() : ShadeRepository {
178     private val _qsExpansion = MutableStateFlow(0f)
179     override val qsExpansion: StateFlow<Float> = _qsExpansion.asStateFlow()
180 
181     private val _lockscreenShadeExpansion = MutableStateFlow(0f)
182     override val lockscreenShadeExpansion: StateFlow<Float> =
183         _lockscreenShadeExpansion.asStateFlow()
184 
185     private var _udfpsTransitionToFullShadeProgress = MutableStateFlow(0f)
186     override val udfpsTransitionToFullShadeProgress: StateFlow<Float> =
187         _udfpsTransitionToFullShadeProgress.asStateFlow()
188 
189     private val _currentFling: MutableStateFlow<FlingInfo?> = MutableStateFlow(null)
190     override val currentFling: StateFlow<FlingInfo?> = _currentFling.asStateFlow()
191 
192     private val _legacyShadeExpansion = MutableStateFlow(0f)
193     @Deprecated("Use ShadeInteractor.shadeExpansion instead")
194     override val legacyShadeExpansion: StateFlow<Float> = _legacyShadeExpansion.asStateFlow()
195 
196     private val _legacyShadeTracking = MutableStateFlow(false)
197     @Deprecated("Use ShadeInteractor instead")
198     override val legacyShadeTracking: StateFlow<Boolean> = _legacyShadeTracking.asStateFlow()
199 
200     override val legacyLockscreenShadeTracking = MutableStateFlow(false)
201 
202     private val _legacyQsTracking = MutableStateFlow(false)
203     @Deprecated("Use ShadeInteractor instead")
204     override val legacyQsTracking: StateFlow<Boolean> = _legacyQsTracking.asStateFlow()
205 
206     private val _legacyExpandedOrAwaitingInputTransfer = MutableStateFlow(false)
207     @Deprecated("Use ShadeInteractor instead")
208     override val legacyExpandedOrAwaitingInputTransfer: StateFlow<Boolean> =
209         _legacyExpandedOrAwaitingInputTransfer.asStateFlow()
210 
211     private val _legacyIsQsExpanded = MutableStateFlow(false)
212     @Deprecated("Use ShadeInteractor instead")
213     override val legacyIsQsExpanded: StateFlow<Boolean> = _legacyIsQsExpanded.asStateFlow()
214 
215     private val _legacyExpandImmediate = MutableStateFlow(false)
216     @Deprecated("Use ShadeInteractor instead")
217     override val legacyExpandImmediate: StateFlow<Boolean> = _legacyExpandImmediate.asStateFlow()
218 
219     private val _legacyQsFullscreen = MutableStateFlow(false)
220     @Deprecated("Use ShadeInteractor instead")
221     override val legacyQsFullscreen: StateFlow<Boolean> = _legacyQsFullscreen.asStateFlow()
222 
223     val _shadeMode = MutableStateFlow(if (DualShade.isEnabled) ShadeMode.Dual else ShadeMode.Single)
224     override val shadeMode: StateFlow<ShadeMode> = _shadeMode.asStateFlow()
225 
226     override fun setShadeMode(shadeMode: ShadeMode) {
227         _shadeMode.value = shadeMode
228     }
229 
230     override fun setLegacyQsFullscreen(legacyQsFullscreen: Boolean) {
231         _legacyQsFullscreen.value = legacyQsFullscreen
232     }
233 
234     override fun setLegacyExpandImmediate(legacyExpandImmediate: Boolean) {
235         _legacyExpandImmediate.value = legacyExpandImmediate
236     }
237 
238     @Deprecated("Use ShadeInteractor instead")
239     override fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean) {
240         _legacyIsQsExpanded.value = legacyIsQsExpanded
241     }
242 
243     @Deprecated("Use ShadeInteractor instead")
244     override fun setLegacyExpandedOrAwaitingInputTransfer(
245         legacyExpandedOrAwaitingInputTransfer: Boolean
246     ) {
247         _legacyExpandedOrAwaitingInputTransfer.value = legacyExpandedOrAwaitingInputTransfer
248     }
249 
250     @Deprecated("Should only be called by NPVC and tests")
251     override fun setLegacyQsTracking(legacyQsTracking: Boolean) {
252         _legacyQsTracking.value = legacyQsTracking
253     }
254 
255     @Deprecated("Should only be called by NPVC and tests")
256     override fun setLegacyShadeTracking(tracking: Boolean) {
257         _legacyShadeTracking.value = tracking
258     }
259 
260     private val _legacyIsClosing = MutableStateFlow(false)
261     @Deprecated("Use ShadeInteractor instead")
262     override val legacyIsClosing: StateFlow<Boolean> = _legacyIsClosing.asStateFlow()
263 
264     @Deprecated("Use ShadeInteractor instead")
265     override fun setLegacyIsClosing(isClosing: Boolean) {
266         _legacyIsClosing.value = isClosing
267     }
268 
269     @Deprecated("Should only be called by NPVC and tests")
270     override fun setLegacyLockscreenShadeTracking(tracking: Boolean) {
271         legacyLockscreenShadeTracking.value = tracking
272     }
273 
274     override fun setQsExpansion(qsExpansion: Float) {
275         _qsExpansion.value = qsExpansion
276     }
277 
278     override fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float) {
279         _lockscreenShadeExpansion.value = lockscreenShadeExpansion
280     }
281 
282     override fun setUdfpsTransitionToFullShadeProgress(progress: Float) {
283         _udfpsTransitionToFullShadeProgress.value = progress
284     }
285 
286     override fun setCurrentFling(info: FlingInfo?) {
287         _currentFling.value = info
288     }
289 
290     @Deprecated("Should only be called by NPVC and tests")
291     override fun setLegacyShadeExpansion(expandedFraction: Float) {
292         _legacyShadeExpansion.value = expandedFraction
293     }
294 
295     companion object {
296         private const val TAG = "ShadeRepository"
297     }
298 }
299