From ef9ee759d590744d8c3a23f29c2ce9fc6147cc88 Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Wed, 7 Jun 2023 15:58:18 +0000 Subject: [PATCH] [Central Surfaces] Move shelf click wakes to PowerInteractor. Bug: 277764509 Test: atest LockscreenShadeTransitionControllerTest NotificationShelfInteractorTest NotificationShelfViewModelTest Test: Turn off NOTIFICATION_SHELF_REFACTOR flag -> tap on notif shelf on lockscreen -> verify PowerInteractor notified Test Turn on NOTIFIATION_SHELF_REFACTOR flag -> tap on notif shelf on lockscreen -> verify PowerInteractor notified Change-Id: Icc8c3b5fb67cddbd8ee28f76f3045ef7cee903c3 --- .../LockscreenShadeTransitionController.kt | 9 ++--- .../interactor/NotificationShelfInteractor.kt | 12 ++---- ...LockscreenShadeTransitionControllerTest.kt | 11 ++++++ .../NotificationShelfInteractorTest.kt | 36 +++++++++++++----- .../NotificationShelfViewModelTest.kt | 38 ++++++++++++++----- 5 files changed, 71 insertions(+), 35 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index c098f455512a7..e2d2ac0fcb58c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -6,7 +6,6 @@ import android.animation.ValueAnimator import android.content.Context import android.content.res.Configuration import android.os.PowerManager -import android.os.SystemClock import android.util.IndentingPrintWriter import android.util.MathUtils import android.view.MotionEvent @@ -30,6 +29,7 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QS import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.notification.collection.NotificationEntry @@ -76,6 +76,7 @@ class LockscreenShadeTransitionController @Inject constructor( dumpManager: DumpManager, qsTransitionControllerFactory: LockscreenShadeQsTransitionController.Factory, private val shadeRepository: ShadeRepository, + private val powerInteractor: PowerInteractor, ) : Dumpable { private var pulseHeight: Float = 0f @get:VisibleForTesting @@ -278,11 +279,7 @@ class LockscreenShadeTransitionController @Inject constructor( // Bind the click listener of the shelf to go to the full shade notificationShelfController.setOnClickListener { if (statusBarStateController.state == StatusBarState.KEYGUARD) { - centralSurfaces.wakeUpIfDozing( - SystemClock.uptimeMillis(), - "SHADE_CLICK", - PowerManager.WAKE_REASON_GESTURE, - ) + powerInteractor.wakeUpIfDozing("SHADE_CLICK", PowerManager.WAKE_REASON_GESTURE) goToLockedShade(it) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt index 69484b06c776a..4b896154c841b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt @@ -20,10 +20,9 @@ import android.os.PowerManager import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository +import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.statusbar.LockscreenShadeTransitionController import com.android.systemui.statusbar.NotificationShelf -import com.android.systemui.statusbar.phone.CentralSurfaces -import com.android.systemui.util.time.SystemClock import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -35,8 +34,7 @@ class NotificationShelfInteractor constructor( private val keyguardRepository: KeyguardRepository, private val deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository, - private val centralSurfaces: CentralSurfaces, - private val systemClock: SystemClock, + private val powerInteractor: PowerInteractor, private val keyguardTransitionController: LockscreenShadeTransitionController, ) { /** Is the shelf showing on the keyguard? */ @@ -55,11 +53,7 @@ constructor( /** Transition keyguard to the locked shade, triggered by the shelf. */ fun goToLockedShadeFromShelf() { - centralSurfaces.wakeUpIfDozing( - systemClock.uptimeMillis(), - "SHADE_CLICK", - PowerManager.WAKE_REASON_GESTURE, - ) + powerInteractor.wakeUpIfDozing("SHADE_CLICK", PowerManager.WAKE_REASON_GESTURE) keyguardTransitionController.goToLockedShade(null) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 2351f7600c65d..21e0f68cff2de 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -8,12 +8,15 @@ import com.android.systemui.ExpandHelper import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.classifier.FalsingCollectorFake import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.media.controls.ui.MediaHierarchyManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QS +import com.android.systemui.power.data.repository.FakePowerRepository +import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow @@ -26,6 +29,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.LSShadeTransitionLogger import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.policy.FakeConfigurationController +import com.android.systemui.util.mockito.mock import org.junit.After import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -83,6 +87,12 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { @Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController @Mock lateinit var activityStarter: ActivityStarter @Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback + private val powerInteractor = PowerInteractor( + FakePowerRepository(), + FalsingCollectorFake(), + screenOffAnimationController = mock(), + statusBarStateController = mock(), + ) @JvmField @Rule val mockito = MockitoJUnit.rule() private val configurationController = FakeConfigurationController() @@ -129,6 +139,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { qsTransitionControllerFactory = { qsTransitionController }, activityStarter = activityStarter, shadeRepository = FakeShadeRepository(), + powerInteractor = powerInteractor, ) transitionController.addCallback(transitionControllerCallback) whenever(nsslController.view).thenReturn(stackscroller) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt index 944eb2d8aadfc..a87dd2d3d6707 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt @@ -22,21 +22,23 @@ import android.os.PowerManager import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.classifier.FalsingCollectorFake import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.power.data.repository.FakePowerRepository +import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.statusbar.LockscreenShadeTransitionController -import com.android.systemui.statusbar.phone.CentralSurfaces -import com.android.systemui.util.mockito.any +import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock -import com.android.systemui.util.time.FakeSystemClock +import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyLong import org.mockito.Mockito.isNull import org.mockito.Mockito.verify @@ -46,15 +48,27 @@ class NotificationShelfInteractorTest : SysuiTestCase() { private val keyguardRepository = FakeKeyguardRepository() private val deviceEntryFaceAuthRepository = FakeDeviceEntryFaceAuthRepository() - private val centralSurfaces: CentralSurfaces = mock() - private val systemClock = FakeSystemClock() + + private val screenOffAnimationController = + mock().also { + whenever(it.allowWakeUpIfDozing()).thenReturn(true) + } + private val statusBarStateController: StatusBarStateController = mock() + private val powerRepository = FakePowerRepository() + private val powerInteractor = + PowerInteractor( + powerRepository, + FalsingCollectorFake(), + screenOffAnimationController, + statusBarStateController, + ) + private val keyguardTransitionController: LockscreenShadeTransitionController = mock() private val underTest = NotificationShelfInteractor( keyguardRepository, deviceEntryFaceAuthRepository, - centralSurfaces, - systemClock, + powerInteractor, keyguardTransitionController, ) @@ -107,10 +121,12 @@ class NotificationShelfInteractorTest : SysuiTestCase() { @Test fun goToLockedShadeFromShelf_wakesUpFromDoze() { + whenever(statusBarStateController.isDozing).thenReturn(true) + underTest.goToLockedShadeFromShelf() - verify(centralSurfaces) - .wakeUpIfDozing(anyLong(), any(), eq(PowerManager.WAKE_REASON_GESTURE)) + assertThat(powerRepository.lastWakeReason).isNotNull() + assertThat(powerRepository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_GESTURE) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt index e9a8f3f0d60c2..7ae150231b985 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt @@ -24,23 +24,26 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.FakeAccessibilityRepository import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor +import com.android.systemui.classifier.FalsingCollectorFake import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.power.data.repository.FakePowerRepository +import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.statusbar.LockscreenShadeTransitionController import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor -import com.android.systemui.statusbar.phone.CentralSurfaces -import com.android.systemui.util.mockito.any +import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.util.mockito.eq -import com.android.systemui.util.time.FakeSystemClock +import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.verify @@ -54,14 +57,23 @@ class NotificationShelfViewModelTest : SysuiTestCase() { @Rule @JvmField val mockitoRule: MockitoRule = MockitoJUnit.rule() // mocks - @Mock private lateinit var centralSurfaces: CentralSurfaces @Mock private lateinit var keyguardTransitionController: LockscreenShadeTransitionController + @Mock private lateinit var screenOffAnimationController: ScreenOffAnimationController + @Mock private lateinit var statusBarStateController: StatusBarStateController // fakes private val keyguardRepository = FakeKeyguardRepository() private val deviceEntryFaceAuthRepository = FakeDeviceEntryFaceAuthRepository() - private val systemClock = FakeSystemClock() private val a11yRepo = FakeAccessibilityRepository() + private val powerRepository = FakePowerRepository() + private val powerInteractor by lazy { + PowerInteractor( + powerRepository, + FalsingCollectorFake(), + screenOffAnimationController, + statusBarStateController, + ) + } // real impls private val a11yInteractor = AccessibilityInteractor(a11yRepo) @@ -70,13 +82,17 @@ class NotificationShelfViewModelTest : SysuiTestCase() { NotificationShelfInteractor( keyguardRepository, deviceEntryFaceAuthRepository, - centralSurfaces, - systemClock, + powerInteractor, keyguardTransitionController, ) } private val underTest by lazy { NotificationShelfViewModel(interactor, activatableViewModel) } + @Before + fun setUp() { + whenever(screenOffAnimationController.allowWakeUpIfDozing()).thenReturn(true) + } + @Test fun canModifyColorOfNotifications_whenKeyguardNotShowing() = runTest { val canModifyNotifColor by collectLastValue(underTest.canModifyColorOfNotifications) @@ -126,10 +142,12 @@ class NotificationShelfViewModelTest : SysuiTestCase() { @Test fun onClicked_goesToLockedShade() { + whenever(statusBarStateController.isDozing).thenReturn(true) + underTest.onShelfClicked() - verify(centralSurfaces) - .wakeUpIfDozing(ArgumentMatchers.anyLong(), any(), eq(PowerManager.WAKE_REASON_GESTURE)) + assertThat(powerRepository.lastWakeReason).isNotNull() + assertThat(powerRepository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_GESTURE) verify(keyguardTransitionController).goToLockedShade(Mockito.isNull(), eq(true)) } }