Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractor.kt +28 −0 Original line number Diff line number Diff line Loading @@ -21,10 +21,16 @@ import android.animation.FloatEvaluator import android.animation.IntEvaluator import com.android.systemui.common.ui.data.repository.ConfigurationRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.statusbar.phone.hideAffordancesRequest import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart /** Encapsulates business logic for transitions between UDFPS states on the keyguard. */ @ExperimentalCoroutinesApi Loading @@ -35,6 +41,8 @@ constructor( configRepo: ConfigurationRepository, burnInInteractor: BurnInInteractor, keyguardInteractor: KeyguardInteractor, shadeRepository: ShadeRepository, dialogManager: SystemUIDialogManager, ) { private val intEvaluator = IntEvaluator() private val floatEvaluator = FloatEvaluator() Loading @@ -56,6 +64,26 @@ constructor( floatEvaluator.evaluate(dozeAmount, 0, fullyDozingBurnInProgress), ) } val dialogHideAffordancesRequest: Flow<Boolean> = dialogManager.hideAffordancesRequest val qsProgress: Flow<Float> = shadeRepository.qsExpansion // swipe from top of LS .map { (it * 2).coerceIn(0f, 1f) } .onStart { emit(0f) } val shadeExpansion: Flow<Float> = combine( shadeRepository.udfpsTransitionToFullShadeProgress, // swipe from middle of LS keyguardInteractor.statusBarState, // quick swipe from middle of LS ) { shadeProgress, statusBarState -> if (statusBarState == StatusBarState.SHADE_LOCKED) { 1f } else { shadeProgress } } .onStart { emit(0f) } } data class BurnInOffsets( Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt +92 −36 Original line number Diff line number Diff line Loading @@ -21,13 +21,17 @@ import androidx.annotation.ColorInt import com.android.settingslib.Utils.getColorAttrDefaultColor import com.android.systemui.R import com.android.systemui.keyguard.domain.interactor.BurnInOffsets import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState import javax.inject.Inject import kotlin.math.roundToInt import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge Loading @@ -38,6 +42,8 @@ open class UdfpsLockscreenViewModel( lockscreenColorResId: Int, alternateBouncerColorResId: Int, transitionInteractor: KeyguardTransitionInteractor, udfpsKeyguardInteractor: UdfpsKeyguardInteractor, keyguardInteractor: KeyguardInteractor, ) { private val toLockscreen: Flow<TransitionViewModel> = transitionInteractor.anyStateToLockscreenTransition.map { Loading @@ -54,11 +60,12 @@ open class UdfpsLockscreenViewModel( } private val toAlternateBouncer: Flow<TransitionViewModel> = keyguardInteractor.statusBarState.flatMapLatest { statusBarState -> transitionInteractor.anyStateToAlternateBouncerTransition.map { TransitionViewModel( alpha = 1f, scale = if (visibleInKeyguardState(it.from)) { if (visibleInKeyguardState(it.from, statusBarState)) { 1f } else { it.value Loading @@ -66,8 +73,10 @@ open class UdfpsLockscreenViewModel( color = getColorAttrDefaultColor(context, alternateBouncerColorResId), ) } } private val fadeOut: Flow<TransitionViewModel> = keyguardInteractor.statusBarState.flatMapLatest { statusBarState -> merge( transitionInteractor.anyStateToGoneTransition, transitionInteractor.anyStateToAodTransition, Loading @@ -78,7 +87,7 @@ open class UdfpsLockscreenViewModel( .map { TransitionViewModel( alpha = if (visibleInKeyguardState(it.from)) { if (visibleInKeyguardState(it.from, statusBarState)) { 1f - it.value } else { 0f Loading @@ -92,8 +101,12 @@ open class UdfpsLockscreenViewModel( }, ) } } private fun visibleInKeyguardState(state: KeyguardState): Boolean { private fun visibleInKeyguardState( state: KeyguardState, statusBarState: StatusBarState ): Boolean { return when (state) { KeyguardState.OFF, KeyguardState.DOZING, Loading @@ -102,17 +115,53 @@ open class UdfpsLockscreenViewModel( KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, KeyguardState.OCCLUDED -> false KeyguardState.LOCKSCREEN, KeyguardState.LOCKSCREEN -> statusBarState == StatusBarState.KEYGUARD KeyguardState.ALTERNATE_BOUNCER -> true } } val transition: Flow<TransitionViewModel> = private val keyguardStateTransition = merge( toAlternateBouncer, toLockscreen, fadeOut, ) private val dialogHideAffordancesAlphaMultiplier: Flow<Float> = udfpsKeyguardInteractor.dialogHideAffordancesRequest.map { hideAffordances -> if (hideAffordances) { 0f } else { 1f } } private val alphaMultiplier: Flow<Float> = combine( transitionInteractor.startedKeyguardState, dialogHideAffordancesAlphaMultiplier, udfpsKeyguardInteractor.shadeExpansion, udfpsKeyguardInteractor.qsProgress, ) { startedKeyguardState, dialogHideAffordancesAlphaMultiplier, shadeExpansion, qsProgress -> if (startedKeyguardState == KeyguardState.ALTERNATE_BOUNCER) { 1f } else { dialogHideAffordancesAlphaMultiplier * (1f - shadeExpansion) * (1f - qsProgress) } } val transition: Flow<TransitionViewModel> = combine( alphaMultiplier, keyguardStateTransition, ) { alphaMultiplier, keyguardStateTransition -> TransitionViewModel( alpha = keyguardStateTransition.alpha * alphaMultiplier, scale = keyguardStateTransition.scale, color = keyguardStateTransition.color, ) } val visible: Flow<Boolean> = transition.map { it.alpha != 0f } } Loading @@ -123,12 +172,15 @@ constructor( val context: Context, transitionInteractor: KeyguardTransitionInteractor, interactor: UdfpsKeyguardInteractor, keyguardInteractor: KeyguardInteractor, ) : UdfpsLockscreenViewModel( context, android.R.attr.textColorPrimary, com.android.internal.R.attr.materialColorOnPrimaryFixed, transitionInteractor, interactor, keyguardInteractor, ) { val dozeAmount: Flow<Float> = interactor.dozeAmount val burnInOffsets: Flow<BurnInOffsets> = interactor.burnInOffsets Loading @@ -147,12 +199,16 @@ class BackgroundViewModel constructor( val context: Context, transitionInteractor: KeyguardTransitionInteractor, interactor: UdfpsKeyguardInteractor, keyguardInteractor: KeyguardInteractor, ) : UdfpsLockscreenViewModel( context, com.android.internal.R.attr.colorSurface, com.android.internal.R.attr.materialColorPrimaryFixed, transitionInteractor, interactor, keyguardInteractor, ) data class TransitionViewModel( Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogManagerExt.kt 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * 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.phone import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow /** Whether dialogs are requesting for affordances to be hidden or not. */ val SystemUIDialogManager.hideAffordancesRequest: Flow<Boolean> get() = conflatedCallbackFlow { val callback = SystemUIDialogManager.Listener { hideAffordance -> trySendWithFailureLogging(hideAffordance, "dialogHideAffordancesRequest") } registerListener(callback) trySendWithFailureLogging(shouldHideAffordance(), "dialogHideAffordancesRequestInitial") awaitClose { unregisterListener(callback) } } packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractorTest.kt +64 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock Loading @@ -46,6 +49,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @ExperimentalCoroutinesApi Loading @@ -63,19 +67,21 @@ class UdfpsKeyguardInteractorTest : SysuiTestCase() { private lateinit var fakeCommandQueue: FakeCommandQueue private lateinit var featureFlags: FakeFeatureFlags private lateinit var burnInInteractor: BurnInInteractor private lateinit var shadeRepository: FakeShadeRepository @Mock private lateinit var burnInHelper: BurnInHelperWrapper @Mock private lateinit var dialogManager: SystemUIDialogManager private lateinit var underTest: UdfpsKeyguardInteractor @Before fun setUp() { MockitoAnnotations.initMocks(this) testScope = TestScope() configRepository = FakeConfigurationRepository() keyguardRepository = FakeKeyguardRepository() bouncerRepository = FakeKeyguardBouncerRepository() shadeRepository = FakeShadeRepository() fakeCommandQueue = FakeCommandQueue() featureFlags = FakeFeatureFlags().apply { Loading @@ -102,6 +108,8 @@ class UdfpsKeyguardInteractorTest : SysuiTestCase() { bouncerRepository, configRepository, ), shadeRepository, dialogManager, ) } Loading Loading @@ -142,6 +150,61 @@ class UdfpsKeyguardInteractorTest : SysuiTestCase() { assertThat(burnInOffsets?.burnInXOffset).isEqualTo(burnInXOffset) } @Test fun dialogHideAffordances() = testScope.runTest { val dialogHideAffordancesRequest by collectLastValue(underTest.dialogHideAffordancesRequest) runCurrent() val captor = argumentCaptor<SystemUIDialogManager.Listener>() verify(dialogManager).registerListener(captor.capture()) captor.value.shouldHideAffordances(false) assertThat(dialogHideAffordancesRequest).isEqualTo(false) captor.value.shouldHideAffordances(true) assertThat(dialogHideAffordancesRequest).isEqualTo(true) captor.value.shouldHideAffordances(false) assertThat(dialogHideAffordancesRequest).isEqualTo(false) } @Test fun shadeExpansion_updates() = testScope.runTest { keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) val shadeExpansion by collectLastValue(underTest.shadeExpansion) assertThat(shadeExpansion).isEqualTo(0f) shadeRepository.setUdfpsTransitionToFullShadeProgress(.5f) assertThat(shadeExpansion).isEqualTo(.5f) shadeRepository.setUdfpsTransitionToFullShadeProgress(.7f) assertThat(shadeExpansion).isEqualTo(.7f) shadeRepository.setUdfpsTransitionToFullShadeProgress(.22f) assertThat(shadeExpansion).isEqualTo(.22f) keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED) assertThat(shadeExpansion).isEqualTo(1f) } @Test fun qsProgress_updates() = testScope.runTest { val qsProgress by collectLastValue(underTest.qsProgress) assertThat(qsProgress).isEqualTo(0f) shadeRepository.setQsExpansion(.22f) assertThat(qsProgress).isEqualTo(.44f) shadeRepository.setQsExpansion(.5f) assertThat(qsProgress).isEqualTo(1f) shadeRepository.setQsExpansion(.7f) assertThat(qsProgress).isEqualTo(1f) } private fun initializeBurnInOffsets() { whenever(burnInHelper.burnInProgressOffset()).thenReturn(burnInProgress) whenever(burnInHelper.burnInOffset(anyInt(), /* xAxis */ eq(true))) Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt +7 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi Loading @@ -58,7 +60,9 @@ class UdfpsAodViewModelTest : SysuiTestCase() { private lateinit var keyguardRepository: FakeKeyguardRepository private lateinit var fakeCommandQueue: FakeCommandQueue private lateinit var featureFlags: FakeFeatureFlags private lateinit var shadeRepository: FakeShadeRepository @Mock private lateinit var dialogManager: SystemUIDialogManager @Mock private lateinit var burnInHelper: BurnInHelperWrapper @Before Loading @@ -70,6 +74,7 @@ class UdfpsAodViewModelTest : SysuiTestCase() { keyguardRepository = FakeKeyguardRepository() bouncerRepository = FakeKeyguardBouncerRepository() fakeCommandQueue = FakeCommandQueue() shadeRepository = FakeShadeRepository() featureFlags = FakeFeatureFlags().apply { set(Flags.REFACTOR_UDFPS_KEYGUARD_VIEWS, true) Loading @@ -93,6 +98,8 @@ class UdfpsAodViewModelTest : SysuiTestCase() { bouncerRepository, configRepository, ), shadeRepository, dialogManager, ) underTest = Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractor.kt +28 −0 Original line number Diff line number Diff line Loading @@ -21,10 +21,16 @@ import android.animation.FloatEvaluator import android.animation.IntEvaluator import com.android.systemui.common.ui.data.repository.ConfigurationRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.statusbar.phone.hideAffordancesRequest import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart /** Encapsulates business logic for transitions between UDFPS states on the keyguard. */ @ExperimentalCoroutinesApi Loading @@ -35,6 +41,8 @@ constructor( configRepo: ConfigurationRepository, burnInInteractor: BurnInInteractor, keyguardInteractor: KeyguardInteractor, shadeRepository: ShadeRepository, dialogManager: SystemUIDialogManager, ) { private val intEvaluator = IntEvaluator() private val floatEvaluator = FloatEvaluator() Loading @@ -56,6 +64,26 @@ constructor( floatEvaluator.evaluate(dozeAmount, 0, fullyDozingBurnInProgress), ) } val dialogHideAffordancesRequest: Flow<Boolean> = dialogManager.hideAffordancesRequest val qsProgress: Flow<Float> = shadeRepository.qsExpansion // swipe from top of LS .map { (it * 2).coerceIn(0f, 1f) } .onStart { emit(0f) } val shadeExpansion: Flow<Float> = combine( shadeRepository.udfpsTransitionToFullShadeProgress, // swipe from middle of LS keyguardInteractor.statusBarState, // quick swipe from middle of LS ) { shadeProgress, statusBarState -> if (statusBarState == StatusBarState.SHADE_LOCKED) { 1f } else { shadeProgress } } .onStart { emit(0f) } } data class BurnInOffsets( Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt +92 −36 Original line number Diff line number Diff line Loading @@ -21,13 +21,17 @@ import androidx.annotation.ColorInt import com.android.settingslib.Utils.getColorAttrDefaultColor import com.android.systemui.R import com.android.systemui.keyguard.domain.interactor.BurnInOffsets import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState import javax.inject.Inject import kotlin.math.roundToInt import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge Loading @@ -38,6 +42,8 @@ open class UdfpsLockscreenViewModel( lockscreenColorResId: Int, alternateBouncerColorResId: Int, transitionInteractor: KeyguardTransitionInteractor, udfpsKeyguardInteractor: UdfpsKeyguardInteractor, keyguardInteractor: KeyguardInteractor, ) { private val toLockscreen: Flow<TransitionViewModel> = transitionInteractor.anyStateToLockscreenTransition.map { Loading @@ -54,11 +60,12 @@ open class UdfpsLockscreenViewModel( } private val toAlternateBouncer: Flow<TransitionViewModel> = keyguardInteractor.statusBarState.flatMapLatest { statusBarState -> transitionInteractor.anyStateToAlternateBouncerTransition.map { TransitionViewModel( alpha = 1f, scale = if (visibleInKeyguardState(it.from)) { if (visibleInKeyguardState(it.from, statusBarState)) { 1f } else { it.value Loading @@ -66,8 +73,10 @@ open class UdfpsLockscreenViewModel( color = getColorAttrDefaultColor(context, alternateBouncerColorResId), ) } } private val fadeOut: Flow<TransitionViewModel> = keyguardInteractor.statusBarState.flatMapLatest { statusBarState -> merge( transitionInteractor.anyStateToGoneTransition, transitionInteractor.anyStateToAodTransition, Loading @@ -78,7 +87,7 @@ open class UdfpsLockscreenViewModel( .map { TransitionViewModel( alpha = if (visibleInKeyguardState(it.from)) { if (visibleInKeyguardState(it.from, statusBarState)) { 1f - it.value } else { 0f Loading @@ -92,8 +101,12 @@ open class UdfpsLockscreenViewModel( }, ) } } private fun visibleInKeyguardState(state: KeyguardState): Boolean { private fun visibleInKeyguardState( state: KeyguardState, statusBarState: StatusBarState ): Boolean { return when (state) { KeyguardState.OFF, KeyguardState.DOZING, Loading @@ -102,17 +115,53 @@ open class UdfpsLockscreenViewModel( KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, KeyguardState.OCCLUDED -> false KeyguardState.LOCKSCREEN, KeyguardState.LOCKSCREEN -> statusBarState == StatusBarState.KEYGUARD KeyguardState.ALTERNATE_BOUNCER -> true } } val transition: Flow<TransitionViewModel> = private val keyguardStateTransition = merge( toAlternateBouncer, toLockscreen, fadeOut, ) private val dialogHideAffordancesAlphaMultiplier: Flow<Float> = udfpsKeyguardInteractor.dialogHideAffordancesRequest.map { hideAffordances -> if (hideAffordances) { 0f } else { 1f } } private val alphaMultiplier: Flow<Float> = combine( transitionInteractor.startedKeyguardState, dialogHideAffordancesAlphaMultiplier, udfpsKeyguardInteractor.shadeExpansion, udfpsKeyguardInteractor.qsProgress, ) { startedKeyguardState, dialogHideAffordancesAlphaMultiplier, shadeExpansion, qsProgress -> if (startedKeyguardState == KeyguardState.ALTERNATE_BOUNCER) { 1f } else { dialogHideAffordancesAlphaMultiplier * (1f - shadeExpansion) * (1f - qsProgress) } } val transition: Flow<TransitionViewModel> = combine( alphaMultiplier, keyguardStateTransition, ) { alphaMultiplier, keyguardStateTransition -> TransitionViewModel( alpha = keyguardStateTransition.alpha * alphaMultiplier, scale = keyguardStateTransition.scale, color = keyguardStateTransition.color, ) } val visible: Flow<Boolean> = transition.map { it.alpha != 0f } } Loading @@ -123,12 +172,15 @@ constructor( val context: Context, transitionInteractor: KeyguardTransitionInteractor, interactor: UdfpsKeyguardInteractor, keyguardInteractor: KeyguardInteractor, ) : UdfpsLockscreenViewModel( context, android.R.attr.textColorPrimary, com.android.internal.R.attr.materialColorOnPrimaryFixed, transitionInteractor, interactor, keyguardInteractor, ) { val dozeAmount: Flow<Float> = interactor.dozeAmount val burnInOffsets: Flow<BurnInOffsets> = interactor.burnInOffsets Loading @@ -147,12 +199,16 @@ class BackgroundViewModel constructor( val context: Context, transitionInteractor: KeyguardTransitionInteractor, interactor: UdfpsKeyguardInteractor, keyguardInteractor: KeyguardInteractor, ) : UdfpsLockscreenViewModel( context, com.android.internal.R.attr.colorSurface, com.android.internal.R.attr.materialColorPrimaryFixed, transitionInteractor, interactor, keyguardInteractor, ) data class TransitionViewModel( Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogManagerExt.kt 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * 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.phone import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow /** Whether dialogs are requesting for affordances to be hidden or not. */ val SystemUIDialogManager.hideAffordancesRequest: Flow<Boolean> get() = conflatedCallbackFlow { val callback = SystemUIDialogManager.Listener { hideAffordance -> trySendWithFailureLogging(hideAffordance, "dialogHideAffordancesRequest") } registerListener(callback) trySendWithFailureLogging(shouldHideAffordance(), "dialogHideAffordancesRequestInitial") awaitClose { unregisterListener(callback) } }
packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractorTest.kt +64 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock Loading @@ -46,6 +49,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @ExperimentalCoroutinesApi Loading @@ -63,19 +67,21 @@ class UdfpsKeyguardInteractorTest : SysuiTestCase() { private lateinit var fakeCommandQueue: FakeCommandQueue private lateinit var featureFlags: FakeFeatureFlags private lateinit var burnInInteractor: BurnInInteractor private lateinit var shadeRepository: FakeShadeRepository @Mock private lateinit var burnInHelper: BurnInHelperWrapper @Mock private lateinit var dialogManager: SystemUIDialogManager private lateinit var underTest: UdfpsKeyguardInteractor @Before fun setUp() { MockitoAnnotations.initMocks(this) testScope = TestScope() configRepository = FakeConfigurationRepository() keyguardRepository = FakeKeyguardRepository() bouncerRepository = FakeKeyguardBouncerRepository() shadeRepository = FakeShadeRepository() fakeCommandQueue = FakeCommandQueue() featureFlags = FakeFeatureFlags().apply { Loading @@ -102,6 +108,8 @@ class UdfpsKeyguardInteractorTest : SysuiTestCase() { bouncerRepository, configRepository, ), shadeRepository, dialogManager, ) } Loading Loading @@ -142,6 +150,61 @@ class UdfpsKeyguardInteractorTest : SysuiTestCase() { assertThat(burnInOffsets?.burnInXOffset).isEqualTo(burnInXOffset) } @Test fun dialogHideAffordances() = testScope.runTest { val dialogHideAffordancesRequest by collectLastValue(underTest.dialogHideAffordancesRequest) runCurrent() val captor = argumentCaptor<SystemUIDialogManager.Listener>() verify(dialogManager).registerListener(captor.capture()) captor.value.shouldHideAffordances(false) assertThat(dialogHideAffordancesRequest).isEqualTo(false) captor.value.shouldHideAffordances(true) assertThat(dialogHideAffordancesRequest).isEqualTo(true) captor.value.shouldHideAffordances(false) assertThat(dialogHideAffordancesRequest).isEqualTo(false) } @Test fun shadeExpansion_updates() = testScope.runTest { keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) val shadeExpansion by collectLastValue(underTest.shadeExpansion) assertThat(shadeExpansion).isEqualTo(0f) shadeRepository.setUdfpsTransitionToFullShadeProgress(.5f) assertThat(shadeExpansion).isEqualTo(.5f) shadeRepository.setUdfpsTransitionToFullShadeProgress(.7f) assertThat(shadeExpansion).isEqualTo(.7f) shadeRepository.setUdfpsTransitionToFullShadeProgress(.22f) assertThat(shadeExpansion).isEqualTo(.22f) keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED) assertThat(shadeExpansion).isEqualTo(1f) } @Test fun qsProgress_updates() = testScope.runTest { val qsProgress by collectLastValue(underTest.qsProgress) assertThat(qsProgress).isEqualTo(0f) shadeRepository.setQsExpansion(.22f) assertThat(qsProgress).isEqualTo(.44f) shadeRepository.setQsExpansion(.5f) assertThat(qsProgress).isEqualTo(1f) shadeRepository.setQsExpansion(.7f) assertThat(qsProgress).isEqualTo(1f) } private fun initializeBurnInOffsets() { whenever(burnInHelper.burnInProgressOffset()).thenReturn(burnInProgress) whenever(burnInHelper.burnInOffset(anyInt(), /* xAxis */ eq(true))) Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt +7 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi Loading @@ -58,7 +60,9 @@ class UdfpsAodViewModelTest : SysuiTestCase() { private lateinit var keyguardRepository: FakeKeyguardRepository private lateinit var fakeCommandQueue: FakeCommandQueue private lateinit var featureFlags: FakeFeatureFlags private lateinit var shadeRepository: FakeShadeRepository @Mock private lateinit var dialogManager: SystemUIDialogManager @Mock private lateinit var burnInHelper: BurnInHelperWrapper @Before Loading @@ -70,6 +74,7 @@ class UdfpsAodViewModelTest : SysuiTestCase() { keyguardRepository = FakeKeyguardRepository() bouncerRepository = FakeKeyguardBouncerRepository() fakeCommandQueue = FakeCommandQueue() shadeRepository = FakeShadeRepository() featureFlags = FakeFeatureFlags().apply { set(Flags.REFACTOR_UDFPS_KEYGUARD_VIEWS, true) Loading @@ -93,6 +98,8 @@ class UdfpsAodViewModelTest : SysuiTestCase() { bouncerRepository, configRepository, ), shadeRepository, dialogManager, ) underTest = Loading