<lambda>null1 package com.android.systemui.statusbar.phone
2
3 import android.app.StatusBarManager
4 import com.android.systemui.Dumpable
5 import com.android.systemui.dagger.SysUISingleton
6 import com.android.systemui.dagger.qualifiers.Main
7 import com.android.systemui.dump.DumpManager
8 import com.android.systemui.shade.ShadeExpansionStateManager
9 import com.android.systemui.statusbar.CommandQueue
10 import com.android.systemui.statusbar.window.StatusBarWindowStateController
11 import com.android.systemui.util.concurrency.DelayableExecutor
12 import java.io.PrintWriter
13 import javax.inject.Inject
14
15 /**
16 * A class that manages if the status bar (clock + notifications + signal cluster) should be visible
17 * or not when showing the bouncer.
18 *
19 * We want to hide it when:
20 * • User swipes up on the keyguard
21 * • Locked activity that doesn't show a status bar requests the bouncer.
22 *
23 * [getShouldHideStatusBarIconsForBouncer] is the main exported method for this class. The other
24 * methods set state variables that are used in the calculation or manually trigger an update.
25 */
26 @SysUISingleton
27 class StatusBarHideIconsForBouncerManager @Inject constructor(
28 private val commandQueue: CommandQueue,
29 @Main private val mainExecutor: DelayableExecutor,
30 statusBarWindowStateController: StatusBarWindowStateController,
31 shadeExpansionStateManager: ShadeExpansionStateManager,
32 dumpManager: DumpManager
33 ) : Dumpable {
34 // State variables set by external classes.
35 private var panelExpanded: Boolean = false
36 private var isOccluded: Boolean = false
37 private var bouncerShowing: Boolean = false
38 private var topAppHidesStatusBar: Boolean = false
39 private var statusBarWindowHidden: Boolean = false
40 private var displayId: Int = 0
41
42 // State variables calculated internally.
43 private var hideIconsForBouncer: Boolean = false
44 private var bouncerWasShowingWhenHidden: Boolean = false
45 private var wereIconsJustHidden: Boolean = false
46
47 init {
48 dumpManager.registerDumpable(this)
49 statusBarWindowStateController.addListener {
50 state -> setStatusBarStateAndTriggerUpdate(state)
51 }
52 shadeExpansionStateManager.addFullExpansionListener { isExpanded ->
53 if (panelExpanded != isExpanded) {
54 panelExpanded = isExpanded
55 updateHideIconsForBouncer(animate = false)
56 }
57 }
58 }
59
60 /** Returns true if the status bar icons should be hidden in the bouncer. */
61 fun getShouldHideStatusBarIconsForBouncer(): Boolean {
62 return hideIconsForBouncer || wereIconsJustHidden
63 }
64
65 private fun setStatusBarStateAndTriggerUpdate(@StatusBarManager.WindowVisibleState state: Int) {
66 statusBarWindowHidden = state == StatusBarManager.WINDOW_STATE_HIDDEN
67 updateHideIconsForBouncer(animate = false)
68 }
69
70 fun setDisplayId(displayId: Int) {
71 this.displayId = displayId
72 }
73
74 fun setIsOccludedAndTriggerUpdate(isOccluded: Boolean) {
75 this.isOccluded = isOccluded
76 updateHideIconsForBouncer(animate = false)
77 }
78
79 fun setBouncerShowingAndTriggerUpdate(bouncerShowing: Boolean) {
80 this.bouncerShowing = bouncerShowing
81 updateHideIconsForBouncer(animate = true)
82 }
83
84 fun setTopAppHidesStatusBarAndTriggerUpdate(topAppHidesStatusBar: Boolean) {
85 this.topAppHidesStatusBar = topAppHidesStatusBar
86 if (!topAppHidesStatusBar && wereIconsJustHidden) {
87 // Immediately update the icon hidden state, since that should only apply if we're
88 // staying fullscreen.
89 wereIconsJustHidden = false
90 commandQueue.recomputeDisableFlags(displayId, /* animate= */ true)
91 }
92 updateHideIconsForBouncer(animate = true)
93 }
94
95 /**
96 * Updates whether the status bar icons should be hidden in the bouncer. May trigger
97 * [commandQueue.recomputeDisableFlags] if the icon visibility status changes.
98 */
99 private fun updateHideIconsForBouncer(animate: Boolean) {
100 val hideBecauseApp =
101 topAppHidesStatusBar &&
102 isOccluded &&
103 (statusBarWindowHidden || bouncerShowing)
104 val hideBecauseKeyguard = !panelExpanded && !isOccluded && bouncerShowing
105 val shouldHideIconsForBouncer = hideBecauseApp || hideBecauseKeyguard
106 if (hideIconsForBouncer != shouldHideIconsForBouncer) {
107 hideIconsForBouncer = shouldHideIconsForBouncer
108 if (!shouldHideIconsForBouncer && bouncerWasShowingWhenHidden) {
109 // We're delaying the showing, since most of the time the fullscreen app will
110 // hide the icons again and we don't want them to fade in and out immediately again.
111 wereIconsJustHidden = true
112 mainExecutor.executeDelayed(
113 {
114 wereIconsJustHidden = false
115 commandQueue.recomputeDisableFlags(displayId, true)
116 },
117 500
118 )
119 } else {
120 commandQueue.recomputeDisableFlags(displayId, animate)
121 }
122 }
123 if (shouldHideIconsForBouncer) {
124 bouncerWasShowingWhenHidden = bouncerShowing
125 }
126 }
127
128 override fun dump(pw: PrintWriter, args: Array<out String>) {
129 pw.println("---- State variables set externally ----")
130 pw.println("panelExpanded=$panelExpanded")
131 pw.println("isOccluded=$isOccluded")
132 pw.println("bouncerShowing=$bouncerShowing")
133 pw.println("topAppHideStatusBar=$topAppHidesStatusBar")
134 pw.println("statusBarWindowHidden=$statusBarWindowHidden")
135 pw.println("displayId=$displayId")
136
137 pw.println("---- State variables calculated internally ----")
138 pw.println("hideIconsForBouncer=$hideIconsForBouncer")
139 pw.println("bouncerWasShowingWhenHidden=$bouncerWasShowingWhenHidden")
140 pw.println("wereIconsJustHidden=$wereIconsJustHidden")
141 }
142 }
143