Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt +57 −4 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.notification.stack.StackStateAnimator import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.KeyguardBypassController.OnBypassStateChangedListener import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener Loading @@ -38,7 +39,6 @@ import java.io.PrintWriter import javax.inject.Inject import kotlin.math.min @SysUISingleton class NotificationWakeUpCoordinator @Inject constructor( dumpManager: DumpManager, Loading Loading @@ -68,6 +68,7 @@ class NotificationWakeUpCoordinator @Inject constructor( private var mLinearDozeAmount: Float = 0.0f private var mDozeAmount: Float = 0.0f private var mDozeAmountSource: String = "init" private var mNotifsHiddenByDozeAmountOverride: Boolean = false private var mNotificationVisibleAmount = 0.0f private var mNotificationsVisible = false private var mNotificationsVisibleForExpansion = false Loading Loading @@ -130,6 +131,7 @@ class NotificationWakeUpCoordinator @Inject constructor( } } } /** * True if we can show pulsing heads up notifications */ Loading @@ -149,10 +151,19 @@ class NotificationWakeUpCoordinator @Inject constructor( return canShow } private val bypassStateChangedListener = object : OnBypassStateChangedListener { override fun onBypassStateChanged(isEnabled: Boolean) { // When the bypass state changes, we have to check whether we should re-show the // notifications by clearing the doze amount override which hides them. maybeClearDozeAmountOverrideHidingNotifs() } } init { dumpManager.registerDumpable(this) mHeadsUpManager.addListener(this) statusBarStateController.addCallback(this) bypassController.registerOnBypassStateChangedListener(bypassStateChangedListener) addListener(object : WakeUpListener { override fun onFullyHiddenChanged(isFullyHidden: Boolean) { if (isFullyHidden && mNotificationsVisibleForExpansion) { Loading Loading @@ -261,12 +272,18 @@ class NotificationWakeUpCoordinator @Inject constructor( setDozeAmount(linear, eased, source = "StatusBar") } fun setDozeAmount(linear: Float, eased: Float, source: String) { fun setDozeAmount( linear: Float, eased: Float, source: String, hidesNotifsByOverride: Boolean = false ) { val changed = linear != mLinearDozeAmount logger.logSetDozeAmount(linear, eased, source, statusBarStateController.state, changed) mLinearDozeAmount = linear mDozeAmount = eased mDozeAmountSource = source mNotifsHiddenByDozeAmountOverride = hidesNotifsByOverride mStackScrollerController.setDozeAmount(mDozeAmount) updateHideAmount() if (changed && linear == 0.0f) { Loading Loading @@ -295,6 +312,8 @@ class NotificationWakeUpCoordinator @Inject constructor( return } maybeClearDozeAmountOverrideHidingNotifs() if (bypassController.bypassEnabled && newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED && (!statusBarStateController.isDozing || shouldAnimateVisibility())) { Loading Loading @@ -325,7 +344,8 @@ class NotificationWakeUpCoordinator @Inject constructor( private fun overrideDozeAmountIfBypass(): Boolean { if (bypassController.bypassEnabled) { if (statusBarStateController.state == StatusBarState.KEYGUARD) { setDozeAmount(1f, 1f, source = "Override: bypass (keyguard)") setDozeAmount(1f, 1f, source = "Override: bypass (keyguard)", hidesNotifsByOverride = true) } else { setDozeAmount(0f, 0f, source = "Override: bypass (shade)") } Loading @@ -334,6 +354,37 @@ class NotificationWakeUpCoordinator @Inject constructor( return false } /** * If the last [setDozeAmount] call was an override to hide notifications, then this call will * check for the set of states that may have caused that override, and if none of them still * apply, and the device is awake or not on the keyguard, then dozeAmount will be reset to 0. * This fixes bugs where the bypass state changing could result in stale overrides, hiding * notifications either on the inside screen or even after unlock. */ private fun maybeClearDozeAmountOverrideHidingNotifs() { if (mNotifsHiddenByDozeAmountOverride) { val onKeyguard = statusBarStateController.state == StatusBarState.KEYGUARD val dozing = statusBarStateController.isDozing val bypass = bypassController.bypassEnabled val animating = screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard() // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff] and // [overrideDozeAmountIfBypass] based on 'animating' and 'bypass' respectively, so only // clear the override if both those conditions are cleared. But also require either // !dozing or !onKeyguard because those conditions should indicate that we intend // notifications to be visible, and thus it is safe to unhide them. val willRemove = (!onKeyguard || !dozing) && !bypass && !animating logger.logMaybeClearDozeAmountOverrideHidingNotifs( willRemove = willRemove, onKeyguard = onKeyguard, dozing = dozing, bypass = bypass, animating = animating, ) if (willRemove) { setDozeAmount(0f, 0f, source = "Removed: $mDozeAmountSource") } } } /** * If we're playing the screen off animation, force the notification doze amount to be 1f (fully * dozing). This is needed so that the notifications aren't briefly visible as the screen turns Loading @@ -344,7 +395,8 @@ class NotificationWakeUpCoordinator @Inject constructor( */ private fun overrideDozeAmountIfAnimatingScreenOff(linearDozeAmount: Float): Boolean { if (screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard()) { setDozeAmount(1f, 1f, source = "Override: animating screen off") setDozeAmount(1f, 1f, source = "Override: animating screen off", hidesNotifsByOverride = true) return true } Loading Loading @@ -430,6 +482,7 @@ class NotificationWakeUpCoordinator @Inject constructor( pw.println("mLinearDozeAmount: $mLinearDozeAmount") pw.println("mDozeAmount: $mDozeAmount") pw.println("mDozeAmountSource: $mDozeAmountSource") pw.println("mNotifsHiddenByDozeAmountOverride: $mNotifsHiddenByDozeAmountOverride") pw.println("mNotificationVisibleAmount: $mNotificationVisibleAmount") pw.println("mNotificationsVisible: $mNotificationsVisible") pw.println("mNotificationsVisibleForExpansion: $mNotificationsVisibleForExpansion") Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt +19 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,25 @@ constructor(@NotificationLog private val buffer: LogBuffer) { ) } fun logMaybeClearDozeAmountOverrideHidingNotifs( willRemove: Boolean, onKeyguard: Boolean, dozing: Boolean, bypass: Boolean, animating: Boolean, ) { buffer.log( TAG, DEBUG, { str1 = "willRemove=$willRemove onKeyguard=$onKeyguard dozing=$dozing" + " bypass=$bypass animating=$animating" }, { "maybeClearDozeAmountOverrideHidingNotifs() $str1" } ) } fun logOnDozeAmountChanged(linear: Float, eased: Float) { buffer.log( TAG, Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt +57 −4 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.notification.stack.StackStateAnimator import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.KeyguardBypassController.OnBypassStateChangedListener import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener Loading @@ -38,7 +39,6 @@ import java.io.PrintWriter import javax.inject.Inject import kotlin.math.min @SysUISingleton class NotificationWakeUpCoordinator @Inject constructor( dumpManager: DumpManager, Loading Loading @@ -68,6 +68,7 @@ class NotificationWakeUpCoordinator @Inject constructor( private var mLinearDozeAmount: Float = 0.0f private var mDozeAmount: Float = 0.0f private var mDozeAmountSource: String = "init" private var mNotifsHiddenByDozeAmountOverride: Boolean = false private var mNotificationVisibleAmount = 0.0f private var mNotificationsVisible = false private var mNotificationsVisibleForExpansion = false Loading Loading @@ -130,6 +131,7 @@ class NotificationWakeUpCoordinator @Inject constructor( } } } /** * True if we can show pulsing heads up notifications */ Loading @@ -149,10 +151,19 @@ class NotificationWakeUpCoordinator @Inject constructor( return canShow } private val bypassStateChangedListener = object : OnBypassStateChangedListener { override fun onBypassStateChanged(isEnabled: Boolean) { // When the bypass state changes, we have to check whether we should re-show the // notifications by clearing the doze amount override which hides them. maybeClearDozeAmountOverrideHidingNotifs() } } init { dumpManager.registerDumpable(this) mHeadsUpManager.addListener(this) statusBarStateController.addCallback(this) bypassController.registerOnBypassStateChangedListener(bypassStateChangedListener) addListener(object : WakeUpListener { override fun onFullyHiddenChanged(isFullyHidden: Boolean) { if (isFullyHidden && mNotificationsVisibleForExpansion) { Loading Loading @@ -261,12 +272,18 @@ class NotificationWakeUpCoordinator @Inject constructor( setDozeAmount(linear, eased, source = "StatusBar") } fun setDozeAmount(linear: Float, eased: Float, source: String) { fun setDozeAmount( linear: Float, eased: Float, source: String, hidesNotifsByOverride: Boolean = false ) { val changed = linear != mLinearDozeAmount logger.logSetDozeAmount(linear, eased, source, statusBarStateController.state, changed) mLinearDozeAmount = linear mDozeAmount = eased mDozeAmountSource = source mNotifsHiddenByDozeAmountOverride = hidesNotifsByOverride mStackScrollerController.setDozeAmount(mDozeAmount) updateHideAmount() if (changed && linear == 0.0f) { Loading Loading @@ -295,6 +312,8 @@ class NotificationWakeUpCoordinator @Inject constructor( return } maybeClearDozeAmountOverrideHidingNotifs() if (bypassController.bypassEnabled && newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED && (!statusBarStateController.isDozing || shouldAnimateVisibility())) { Loading Loading @@ -325,7 +344,8 @@ class NotificationWakeUpCoordinator @Inject constructor( private fun overrideDozeAmountIfBypass(): Boolean { if (bypassController.bypassEnabled) { if (statusBarStateController.state == StatusBarState.KEYGUARD) { setDozeAmount(1f, 1f, source = "Override: bypass (keyguard)") setDozeAmount(1f, 1f, source = "Override: bypass (keyguard)", hidesNotifsByOverride = true) } else { setDozeAmount(0f, 0f, source = "Override: bypass (shade)") } Loading @@ -334,6 +354,37 @@ class NotificationWakeUpCoordinator @Inject constructor( return false } /** * If the last [setDozeAmount] call was an override to hide notifications, then this call will * check for the set of states that may have caused that override, and if none of them still * apply, and the device is awake or not on the keyguard, then dozeAmount will be reset to 0. * This fixes bugs where the bypass state changing could result in stale overrides, hiding * notifications either on the inside screen or even after unlock. */ private fun maybeClearDozeAmountOverrideHidingNotifs() { if (mNotifsHiddenByDozeAmountOverride) { val onKeyguard = statusBarStateController.state == StatusBarState.KEYGUARD val dozing = statusBarStateController.isDozing val bypass = bypassController.bypassEnabled val animating = screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard() // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff] and // [overrideDozeAmountIfBypass] based on 'animating' and 'bypass' respectively, so only // clear the override if both those conditions are cleared. But also require either // !dozing or !onKeyguard because those conditions should indicate that we intend // notifications to be visible, and thus it is safe to unhide them. val willRemove = (!onKeyguard || !dozing) && !bypass && !animating logger.logMaybeClearDozeAmountOverrideHidingNotifs( willRemove = willRemove, onKeyguard = onKeyguard, dozing = dozing, bypass = bypass, animating = animating, ) if (willRemove) { setDozeAmount(0f, 0f, source = "Removed: $mDozeAmountSource") } } } /** * If we're playing the screen off animation, force the notification doze amount to be 1f (fully * dozing). This is needed so that the notifications aren't briefly visible as the screen turns Loading @@ -344,7 +395,8 @@ class NotificationWakeUpCoordinator @Inject constructor( */ private fun overrideDozeAmountIfAnimatingScreenOff(linearDozeAmount: Float): Boolean { if (screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard()) { setDozeAmount(1f, 1f, source = "Override: animating screen off") setDozeAmount(1f, 1f, source = "Override: animating screen off", hidesNotifsByOverride = true) return true } Loading Loading @@ -430,6 +482,7 @@ class NotificationWakeUpCoordinator @Inject constructor( pw.println("mLinearDozeAmount: $mLinearDozeAmount") pw.println("mDozeAmount: $mDozeAmount") pw.println("mDozeAmountSource: $mDozeAmountSource") pw.println("mNotifsHiddenByDozeAmountOverride: $mNotifsHiddenByDozeAmountOverride") pw.println("mNotificationVisibleAmount: $mNotificationVisibleAmount") pw.println("mNotificationsVisible: $mNotificationsVisible") pw.println("mNotificationsVisibleForExpansion: $mNotificationsVisibleForExpansion") Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt +19 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,25 @@ constructor(@NotificationLog private val buffer: LogBuffer) { ) } fun logMaybeClearDozeAmountOverrideHidingNotifs( willRemove: Boolean, onKeyguard: Boolean, dozing: Boolean, bypass: Boolean, animating: Boolean, ) { buffer.log( TAG, DEBUG, { str1 = "willRemove=$willRemove onKeyguard=$onKeyguard dozing=$dozing" + " bypass=$bypass animating=$animating" }, { "maybeClearDozeAmountOverrideHidingNotifs() $str1" } ) } fun logOnDozeAmountChanged(linear: Float, eased: Float) { buffer.log( TAG, Loading