1 /* 2 * Copyright (C) 2023 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.ui.viewmodel 18 19 import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE 20 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor 21 import com.android.systemui.dagger.SysUISingleton 22 import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION 23 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor 24 import com.android.systemui.keyguard.shared.model.ScrimAlpha 25 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow 26 import com.android.systemui.statusbar.SysuiStatusBarStateController 27 import javax.inject.Inject 28 import kotlin.time.Duration.Companion.milliseconds 29 import kotlinx.coroutines.flow.Flow 30 import kotlinx.coroutines.flow.map 31 32 /** 33 * Breaks down PRIMARY_BOUNCER->GONE transition into discrete steps for corresponding views to 34 * consume. 35 */ 36 @SysUISingleton 37 class PrimaryBouncerToGoneTransitionViewModel 38 @Inject 39 constructor( 40 private val interactor: KeyguardTransitionInteractor, 41 private val statusBarStateController: SysuiStatusBarStateController, 42 private val primaryBouncerInteractor: PrimaryBouncerInteractor, 43 ) { 44 private val transitionAnimation = 45 KeyguardTransitionAnimationFlow( 46 transitionDuration = TO_GONE_DURATION, 47 transitionFlow = interactor.primaryBouncerToGoneTransition, 48 ) 49 50 private var leaveShadeOpen: Boolean = false 51 private var willRunDismissFromKeyguard: Boolean = false 52 53 /** Bouncer container alpha */ 54 val bouncerAlpha: Flow<Float> = 55 transitionAnimation.createFlow( 56 duration = 200.milliseconds, 57 onStart = { 58 willRunDismissFromKeyguard = primaryBouncerInteractor.willRunDismissFromKeyguard() 59 }, 60 onStep = { 61 if (willRunDismissFromKeyguard) { 62 0f 63 } else { 64 1f - it 65 } 66 }, 67 ) 68 69 /** Lockscreen alpha */ 70 val lockscreenAlpha: Flow<Float> = 71 transitionAnimation.createFlow( 72 duration = 50.milliseconds, 73 onStart = { 74 leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() 75 willRunDismissFromKeyguard = primaryBouncerInteractor.willRunDismissFromKeyguard() 76 }, 77 onStep = { 78 if (willRunDismissFromKeyguard || leaveShadeOpen) { 79 1f 80 } else { 81 0f 82 } 83 }, 84 ) 85 86 /** Scrim alpha values */ 87 val scrimAlpha: Flow<ScrimAlpha> = 88 transitionAnimation 89 .createFlow( 90 duration = TO_GONE_DURATION, 91 interpolator = EMPHASIZED_ACCELERATE, 92 onStart = { 93 leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() 94 willRunDismissFromKeyguard = 95 primaryBouncerInteractor.willRunDismissFromKeyguard() 96 }, 97 onStep = { 1f - it }, 98 ) 99 .map { 100 if (willRunDismissFromKeyguard) { 101 ScrimAlpha() 102 } else if (leaveShadeOpen) { 103 ScrimAlpha( 104 behindAlpha = 1f, 105 notificationsAlpha = 1f, 106 ) 107 } else { 108 ScrimAlpha(behindAlpha = it) 109 } 110 } 111 } 112