summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff DeCew <jeffdq@google.com> 2022-12-12 19:20:51 +0000
committer Jeff DeCew <jeffdq@google.com> 2023-02-24 14:52:53 +0000
commitbb70a7973759b3df0bd838017ba44e7406b445b1 (patch)
treed8cabad2be11fc0d2e0ad319041e3d4af7d6804c
parent24311a64742c81b4ee5399e6785695d7c772334a (diff)
Fix the weirdly broken code in NotificationWakeUpCoordinator
* Remove an extra block of bypass code that was unreachanle * Update state and return early for EVERY special case in onStateChanged Test: atest NotificationWakeUpCoordinatorTest Bug: 250946719 Change-Id: I58117a5fecf8fb224915c7550e006b1b504ef09c
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt163
2 files changed, 172 insertions, 8 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 7e53d5431353..8874f59d6c17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification
import android.animation.ObjectAnimator
import android.util.FloatProperty
+import androidx.annotation.VisibleForTesting
import com.android.systemui.Dumpable
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
@@ -302,29 +303,29 @@ class NotificationWakeUpCoordinator @Inject constructor(
// the doze amount to 0f (not dozing) so that the notifications are no longer hidden.
// See: UnlockedScreenOffAnimationController.onFinishedWakingUp()
setDozeAmount(0f, 0f, source = "Override: Shade->Shade (lock cancelled by unlock)")
+ this.state = newState
+ return
}
if (overrideDozeAmountIfAnimatingScreenOff(mLinearDozeAmount)) {
+ this.state = newState
return
}
if (overrideDozeAmountIfBypass()) {
+ this.state = newState
return
}
maybeClearDozeAmountOverrideHidingNotifs()
- if (bypassController.bypassEnabled &&
- newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED &&
- (!statusBarStateController.isDozing || shouldAnimateVisibility())) {
- // We're leaving shade locked. Let's animate the notifications away
- setNotificationsVisible(visible = true, increaseSpeed = false, animate = false)
- setNotificationsVisible(visible = false, increaseSpeed = false, animate = true)
- }
-
this.state = newState
}
+ @VisibleForTesting
+ val statusBarState: Int
+ get() = state
+
override fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
val collapsedEnough = event.fraction <= 0.9f
if (collapsedEnough != this.collapsedEnoughToHide) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
new file mode 100644
index 000000000000..95591a4b321c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.phone.DozeParameters
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.mockito.withArgCaptor
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.anyFloat
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class NotificationWakeUpCoordinatorTest : SysuiTestCase() {
+
+ private val dumpManager: DumpManager = mock()
+ private val headsUpManager: HeadsUpManager = mock()
+ private val statusBarStateController: StatusBarStateController = mock()
+ private val bypassController: KeyguardBypassController = mock()
+ private val dozeParameters: DozeParameters = mock()
+ private val screenOffAnimationController: ScreenOffAnimationController = mock()
+ private val logger: NotificationWakeUpCoordinatorLogger = mock()
+ private val stackScrollerController: NotificationStackScrollLayoutController = mock()
+
+ private lateinit var notificationWakeUpCoordinator: NotificationWakeUpCoordinator
+ private lateinit var statusBarStateCallback: StatusBarStateController.StateListener
+ private lateinit var bypassChangeCallback: KeyguardBypassController.OnBypassStateChangedListener
+
+ private var bypassEnabled: Boolean = false
+ private var statusBarState: Int = StatusBarState.KEYGUARD
+ private var dozeAmount: Float = 0f
+
+ private fun setBypassEnabled(enabled: Boolean) {
+ bypassEnabled = enabled
+ bypassChangeCallback.onBypassStateChanged(enabled)
+ }
+
+ private fun setStatusBarState(state: Int) {
+ statusBarState = state
+ statusBarStateCallback.onStateChanged(state)
+ }
+
+ private fun setDozeAmount(dozeAmount: Float) {
+ this.dozeAmount = dozeAmount
+ statusBarStateCallback.onDozeAmountChanged(dozeAmount, dozeAmount)
+ }
+
+ @Before
+ fun setup() {
+ whenever(bypassController.bypassEnabled).then { bypassEnabled }
+ whenever(statusBarStateController.state).then { statusBarState }
+ notificationWakeUpCoordinator =
+ NotificationWakeUpCoordinator(
+ dumpManager,
+ headsUpManager,
+ statusBarStateController,
+ bypassController,
+ dozeParameters,
+ screenOffAnimationController,
+ logger,
+ )
+ statusBarStateCallback = withArgCaptor {
+ verify(statusBarStateController).addCallback(capture())
+ }
+ bypassChangeCallback = withArgCaptor {
+ verify(bypassController).registerOnBypassStateChangedListener(capture())
+ }
+ notificationWakeUpCoordinator.setStackScroller(stackScrollerController)
+ }
+
+ @Test
+ fun setDozeToOneWillFullyHideNotifications() {
+ setDozeAmount(1f)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue()
+ }
+
+ @Test
+ fun setDozeToZeroWillFullyShowNotifications() {
+ setDozeAmount(0f)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 0f, hideAmount = 0f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse()
+ }
+
+ @Test
+ fun setDozeToOneThenZeroWillFullyShowNotifications() {
+ setDozeToOneWillFullyHideNotifications()
+ clearInvocations(stackScrollerController)
+ setDozeToZeroWillFullyShowNotifications()
+ }
+
+ @Test
+ fun setDozeToHalfWillHalfShowNotifications() {
+ setDozeAmount(0.5f)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 0.5f, hideAmount = 0.5f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse()
+ }
+
+ @Test
+ fun setDozeToZeroWithBypassWillFullyHideNotifications() {
+ bypassEnabled = true
+ setDozeAmount(0f)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 01f, hideAmount = 1f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue()
+ }
+
+ @Test
+ fun disablingBypassWillShowNotifications() {
+ setDozeToZeroWithBypassWillFullyHideNotifications()
+ clearInvocations(stackScrollerController)
+ setBypassEnabled(false)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 0f, hideAmount = 0f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse()
+ }
+
+ @Test
+ fun switchingToShadeWithBypassEnabledWillShowNotifications() {
+ setDozeToZeroWithBypassWillFullyHideNotifications()
+ clearInvocations(stackScrollerController)
+ setStatusBarState(StatusBarState.SHADE)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 0f, hideAmount = 0f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse()
+ assertThat(notificationWakeUpCoordinator.statusBarState).isEqualTo(StatusBarState.SHADE)
+ }
+
+ private fun verifyStackScrollerDozeAndHideAmount(dozeAmount: Float, hideAmount: Float) {
+ // First verify that we did in-fact receive the correct values
+ verify(stackScrollerController).setDozeAmount(dozeAmount)
+ verify(stackScrollerController).setHideAmount(hideAmount, hideAmount)
+ // Now verify that there was just this ONE call to each of these methods
+ verify(stackScrollerController).setDozeAmount(anyFloat())
+ verify(stackScrollerController).setHideAmount(anyFloat(), anyFloat())
+ }
+}