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.keyguard.KeyguardSecurityModel 21 import com.android.keyguard.KeyguardSecurityModel.SecurityMode.Password 22 import com.android.keyguard.KeyguardUpdateMonitor 23 import com.android.systemui.animation.Interpolators 24 import com.android.systemui.dagger.SysUISingleton 25 import com.android.systemui.dagger.qualifiers.Application 26 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository 27 import com.android.systemui.keyguard.shared.model.KeyguardState 28 import com.android.systemui.keyguard.shared.model.TransitionInfo 29 import com.android.systemui.keyguard.shared.model.WakefulnessState 30 import com.android.systemui.util.kotlin.sample 31 import javax.inject.Inject 32 import kotlin.time.Duration 33 import kotlin.time.Duration.Companion.milliseconds 34 import kotlinx.coroutines.CoroutineScope 35 import kotlinx.coroutines.flow.combine 36 import kotlinx.coroutines.launch 37 38 @SysUISingleton 39 class FromPrimaryBouncerTransitionInteractor 40 @Inject 41 constructor( 42 @Application private val scope: CoroutineScope, 43 private val keyguardInteractor: KeyguardInteractor, 44 private val keyguardTransitionRepository: KeyguardTransitionRepository, 45 private val keyguardTransitionInteractor: KeyguardTransitionInteractor, 46 private val keyguardSecurityModel: KeyguardSecurityModel, 47 ) : TransitionInteractor(FromPrimaryBouncerTransitionInteractor::class.simpleName!!) { 48 49 override fun start() { 50 listenForPrimaryBouncerToGone() 51 listenForPrimaryBouncerToLockscreenAodOrDozing() 52 } 53 54 private fun listenForPrimaryBouncerToLockscreenAodOrDozing() { 55 scope.launch { 56 keyguardInteractor.primaryBouncerShowing 57 .sample( 58 combine( 59 keyguardInteractor.wakefulnessModel, 60 keyguardTransitionInteractor.startedKeyguardTransitionStep, 61 keyguardInteractor.isAodAvailable, 62 ::toTriple 63 ), 64 ::toQuad 65 ) 66 .collect { 67 (isBouncerShowing, wakefulnessState, lastStartedTransitionStep, isAodAvailable) 68 -> 69 if ( 70 !isBouncerShowing && 71 lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER 72 ) { 73 val to = 74 if ( 75 wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP || 76 wakefulnessState.state == WakefulnessState.ASLEEP 77 ) { 78 if (isAodAvailable) { 79 KeyguardState.AOD 80 } else { 81 KeyguardState.DOZING 82 } 83 } else { 84 KeyguardState.LOCKSCREEN 85 } 86 keyguardTransitionRepository.startTransition( 87 TransitionInfo( 88 ownerName = name, 89 from = KeyguardState.PRIMARY_BOUNCER, 90 to = to, 91 animator = getAnimator(), 92 ) 93 ) 94 } 95 } 96 } 97 } 98 99 private fun listenForPrimaryBouncerToGone() { 100 scope.launch { 101 keyguardInteractor.isKeyguardGoingAway 102 .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair) 103 .collect { (isKeyguardGoingAway, lastStartedTransitionStep) -> 104 if ( 105 isKeyguardGoingAway && 106 lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER 107 ) { 108 val securityMode = 109 keyguardSecurityModel.getSecurityMode( 110 KeyguardUpdateMonitor.getCurrentUser() 111 ) 112 // IME for password requires a slightly faster animation 113 val duration = 114 if (securityMode == Password) { 115 TO_GONE_SHORT_DURATION 116 } else { 117 TO_GONE_DURATION 118 } 119 keyguardTransitionRepository.startTransition( 120 TransitionInfo( 121 ownerName = name, 122 from = KeyguardState.PRIMARY_BOUNCER, 123 to = KeyguardState.GONE, 124 animator = getAnimator(duration), 125 ), 126 resetIfCanceled = true, 127 ) 128 } 129 } 130 } 131 } 132 133 private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator { 134 return ValueAnimator().apply { 135 setInterpolator(Interpolators.LINEAR) 136 setDuration(duration.inWholeMilliseconds) 137 } 138 } 139 140 companion object { 141 private val DEFAULT_DURATION = 300.milliseconds 142 val TO_GONE_DURATION = 250.milliseconds 143 val TO_GONE_SHORT_DURATION = 200.milliseconds 144 } 145 } 146