1 /* <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.systemui.keyguard.domain.interactor 18 19 import android.animation.ValueAnimator 20 import com.android.app.animation.Interpolators 21 import com.android.systemui.dagger.SysUISingleton 22 import com.android.systemui.dagger.qualifiers.Application 23 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository 24 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion.isWakeAndUnlock 25 import com.android.systemui.keyguard.shared.model.KeyguardState 26 import com.android.systemui.util.kotlin.Utils.Companion.toTriple 27 import com.android.systemui.util.kotlin.sample 28 import javax.inject.Inject 29 import kotlin.time.Duration.Companion.milliseconds 30 import kotlinx.coroutines.CoroutineScope 31 import kotlinx.coroutines.flow.combine 32 import kotlinx.coroutines.launch 33 34 @SysUISingleton 35 class FromDozingTransitionInteractor 36 @Inject 37 constructor( 38 override val transitionRepository: KeyguardTransitionRepository, 39 override val transitionInteractor: KeyguardTransitionInteractor, 40 @Application private val scope: CoroutineScope, 41 private val keyguardInteractor: KeyguardInteractor, 42 ) : 43 TransitionInteractor( 44 fromState = KeyguardState.DOZING, 45 ) { 46 47 override fun start() { 48 listenForDozingToLockscreenOrOccluded() 49 listenForDozingToGone() 50 } 51 52 private fun listenForDozingToLockscreenOrOccluded() { 53 scope.launch { 54 keyguardInteractor.wakefulnessModel 55 .sample( 56 combine( 57 transitionInteractor.startedKeyguardTransitionStep, 58 keyguardInteractor.isKeyguardOccluded, 59 ::Pair 60 ), 61 ::toTriple 62 ) 63 .collect { (wakefulnessModel, lastStartedTransition, occluded) -> 64 if ( 65 wakefulnessModel.isStartingToWakeOrAwake() && 66 lastStartedTransition.to == KeyguardState.DOZING 67 ) { 68 startTransitionTo( 69 if (occluded) KeyguardState.OCCLUDED else KeyguardState.LOCKSCREEN 70 ) 71 } 72 } 73 } 74 } 75 76 private fun listenForDozingToGone() { 77 scope.launch { 78 keyguardInteractor.biometricUnlockState 79 .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair) 80 .collect { (biometricUnlockState, lastStartedTransition) -> 81 if ( 82 lastStartedTransition.to == KeyguardState.DOZING && 83 isWakeAndUnlock(biometricUnlockState) 84 ) { 85 startTransitionTo(KeyguardState.GONE) 86 } 87 } 88 } 89 } 90 91 override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator { 92 return ValueAnimator().apply { 93 interpolator = Interpolators.LINEAR 94 duration = DEFAULT_DURATION.inWholeMilliseconds 95 } 96 } 97 98 companion object { 99 private val DEFAULT_DURATION = 500.milliseconds 100 } 101 } 102