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