• 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.shade.domain.interactor
18 
19 import com.android.systemui.shade.shared.model.ShadeMode
20 import kotlinx.coroutines.CoroutineScope
21 import kotlinx.coroutines.flow.Flow
22 import kotlinx.coroutines.flow.SharingStarted
23 import kotlinx.coroutines.flow.StateFlow
24 import kotlinx.coroutines.flow.combine
25 import kotlinx.coroutines.flow.stateIn
26 
27 /** Business logic for shade interactions. */
28 interface ShadeInteractor : BaseShadeInteractor {
29     /** Emits true if the shade is currently allowed and false otherwise. */
30     val isShadeEnabled: StateFlow<Boolean>
31 
32     /** Emits true if QS is currently allowed and false otherwise. */
33     val isQsEnabled: StateFlow<Boolean>
34 
35     /** Whether either the shade or QS is fully expanded. */
36     val isAnyFullyExpanded: StateFlow<Boolean>
37 
38     /** Whether the Shade is fully expanded. */
39     val isShadeFullyExpanded: Flow<Boolean>
40 
41     /** Whether the Shade is fully collapsed. */
42     val isShadeFullyCollapsed: Flow<Boolean>
43 
44     /**
45      * Whether the user is expanding or collapsing either the shade or quick settings with user
46      * input (i.e. dragging a pointer). This will be true even if the user's input gesture had ended
47      * but a transition they initiated is still animating.
48      */
49     val isUserInteracting: StateFlow<Boolean>
50 
51     /** Are touches allowed on the notification panel? */
52     val isShadeTouchable: Flow<Boolean>
53 
54     /** Emits true if the shade can be expanded from QQS to QS and false otherwise. */
55     val isExpandToQsEnabled: Flow<Boolean>
56 }
57 
58 /** ShadeInteractor methods with implementations that differ between non-empty impls. */
59 interface BaseShadeInteractor {
60     /** The amount [0-1] either QS or the shade has been opened. */
61     val anyExpansion: StateFlow<Float>
62 
63     /**
64      * Whether either the shade or QS is partially or fully expanded, i.e. not fully collapsed. At
65      * this time, this is not simply a matter of checking if either value in shadeExpansion and
66      * qsExpansion is greater than zero, because it includes the legacy concept of whether input
67      * transfer is about to occur. If the scene container flag is enabled, it just checks whether
68      * either expansion value is positive.
69      *
70      * TODO(b/300258424) remove all but the first sentence of this comment
71      */
72     val isAnyExpanded: StateFlow<Boolean>
73 
74     /** The amount [0-1] that the shade has been opened. */
75     val shadeExpansion: StateFlow<Float>
76 
77     /**
78      * The amount [0-1] QS has been opened. Normal shade with notifications (QQS) visible will
79      * report 0f. If split shade is enabled, value matches shadeExpansion.
80      */
81     val qsExpansion: StateFlow<Float>
82 
83     /** Whether Quick Settings is expanded a non-zero amount. */
84     val isQsExpanded: StateFlow<Boolean>
85 
86     /**
87      * Emits true whenever Quick Settings is being expanded without first expanding the Shade or if
88      * if Quick Settings is being collapsed without first collapsing to shade, i.e. expanding with
89      * 2-finger swipe or collapsing by flinging from the bottom of the screen. This concept was
90      * previously called "expand immediate" in the legacy codebase.
91      */
92     val isQsBypassingShade: Flow<Boolean>
93 
94     /**
95      * Emits true when QS is displayed over the entire screen of the device. Currently, this only
96      * happens on phones that are not unfolded when QS expansion is equal to 1.
97      */
98     val isQsFullscreen: Flow<Boolean>
99 
100     /**
101      * Whether the user is expanding or collapsing the shade with user input. This will be true even
102      * if the user's input gesture has ended but a transition they initiated is animating.
103      */
104     val isUserInteractingWithShade: Flow<Boolean>
105 
106     /**
107      * Whether the user is expanding or collapsing quick settings with user input. This will be true
108      * even if the user's input gesture has ended but a transition they initiated is still
109      * animating.
110      */
111     val isUserInteractingWithQs: Flow<Boolean>
112 
113     val shadeMode: StateFlow<ShadeMode>
114 }
115 
createAnyExpansionFlownull116 fun createAnyExpansionFlow(
117     scope: CoroutineScope,
118     shadeExpansion: Flow<Float>,
119     qsExpansion: Flow<Float>
120 ): StateFlow<Float> {
121     return combine(shadeExpansion, qsExpansion) { shadeExp, qsExp -> maxOf(shadeExp, qsExp) }
122         .stateIn(scope, SharingStarted.Eagerly, 0f)
123 }
124