1 /*
<lambda>null2  * Copyright (C) 2024 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.shade.domain.interactor
20 
21 import com.android.compose.animation.scene.ObservableTransitionState
22 import com.android.compose.animation.scene.SceneKey
23 import com.android.systemui.dagger.SysUISingleton
24 import com.android.systemui.scene.domain.interactor.SceneInteractor
25 import com.android.systemui.scene.shared.model.Scenes
26 import com.android.systemui.statusbar.SysuiStatusBarStateController
27 import javax.inject.Inject
28 import kotlinx.coroutines.ExperimentalCoroutinesApi
29 import kotlinx.coroutines.flow.Flow
30 import kotlinx.coroutines.flow.flatMapLatest
31 import kotlinx.coroutines.flow.flowOf
32 import kotlinx.coroutines.flow.map
33 
34 @SysUISingleton
35 class PanelExpansionInteractorImpl
36 @Inject
37 constructor(
38     private val sceneInteractor: SceneInteractor,
39     private val shadeInteractor: ShadeInteractor,
40     private val shadeAnimationInteractor: ShadeAnimationInteractor,
41     private val statusBarStateController: SysuiStatusBarStateController,
42 ) : PanelExpansionInteractor {
43 
44     /**
45      * The amount by which the "panel" has been expanded (`0` when fully collapsed, `1` when fully
46      * expanded).
47      *
48      * This is a legacy concept from the time when the "panel" included the notification/QS shades
49      * as well as the keyguard (lockscreen and bouncer). This value is meant only for
50      * backwards-compatibility and should not be consumed by newer code.
51      */
52     @Deprecated("Use SceneInteractor.currentScene instead.")
53     override val legacyPanelExpansion: Flow<Float> =
54         sceneInteractor.transitionState.flatMapLatest { state ->
55             when (state) {
56                 is ObservableTransitionState.Idle ->
57                     flowOf(
58                         if (state.currentScene != Scenes.Gone) {
59                             // When resting on a non-Gone scene, the panel is fully expanded.
60                             1f
61                         } else {
62                             // When resting on the Gone scene, the panel is considered fully
63                             // collapsed.
64                             0f
65                         }
66                     )
67                 is ObservableTransitionState.Transition ->
68                     when {
69                         state.fromScene == Scenes.Gone ->
70                             if (state.toScene.isExpandable()) {
71                                 // Moving from Gone to a scene that can animate-expand has a
72                                 // panel expansion that tracks with the transition.
73                                 state.progress
74                             } else {
75                                 // Moving from Gone to a scene that doesn't animate-expand
76                                 // immediately makes the panel fully expanded.
77                                 flowOf(1f)
78                             }
79                         state.toScene == Scenes.Gone ->
80                             if (state.fromScene.isExpandable()) {
81                                 // Moving to Gone from a scene that can animate-expand has a
82                                 // panel expansion that tracks with the transition.
83                                 state.progress.map { 1 - it }
84                             } else {
85                                 // Moving to Gone from a scene that doesn't animate-expand
86                                 // immediately makes the panel fully collapsed.
87                                 flowOf(0f)
88                             }
89                         else -> flowOf(1f)
90                     }
91             }
92         }
93 
94     @Deprecated(
95         "depends on the state you check, use {@link #isShadeFullyExpanded()},\n" +
96             "{@link #isOnAod()}, {@link #isOnKeyguard()} instead."
97     )
98     override val isFullyExpanded
99         get() = shadeInteractor.isAnyFullyExpanded.value
100 
101     @Deprecated("Use !ShadeInteractor.isAnyExpanded instead")
102     override val isFullyCollapsed
103         get() = !shadeInteractor.isAnyExpanded.value
104 
105     @Deprecated("Use ShadeAnimationInteractor instead")
106     override val isCollapsing
107         get() =
108             shadeAnimationInteractor.isAnyCloseAnimationRunning.value ||
109                 shadeAnimationInteractor.isLaunchingActivity.value
110 
111     @Deprecated("Use sceneInteractor.isTransitionUserInputOngoing instead")
112     override val isTracking
113         get() = sceneInteractor.isTransitionUserInputOngoing.value
114 
115     @Deprecated("Use ShadeInteractor.isAnyExpanded instead.")
116     override val isPanelExpanded
117         get() = shadeInteractor.isAnyExpanded.value
118 
119     @Deprecated("Use SceneInteractor or ShadeInteractor instead")
120     override val barState
121         get() = statusBarStateController.state
122 
123     @Deprecated("No longer supported. Do not add new calls to this.")
124     override fun shouldHideStatusBarIconsWhenExpanded(): Boolean {
125         if (shadeAnimationInteractor.isLaunchingActivity.value) {
126             return false
127         }
128         // TODO(b/325936094) if a HUN is showing, return false
129         return sceneInteractor.currentScene.value == Scenes.Lockscreen
130     }
131 
132     private fun SceneKey.isExpandable(): Boolean {
133         return this == Scenes.Shade || this == Scenes.QuickSettings
134     }
135 }
136