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.ui.viewmodel
18 
19 import com.android.app.animation.Interpolators.EMPHASIZED
20 import com.android.systemui.dagger.SysUISingleton
21 import com.android.systemui.keyguard.domain.interactor.FromDreamingTransitionInteractor
22 import com.android.systemui.keyguard.domain.interactor.FromDreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
23 import com.android.systemui.keyguard.shared.model.Edge
24 import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
25 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
26 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
27 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
28 import javax.inject.Inject
29 import kotlin.time.Duration.Companion.milliseconds
30 import kotlinx.coroutines.ExperimentalCoroutinesApi
31 import kotlinx.coroutines.flow.Flow
32 
33 /**
34  * Breaks down DREAMING->LOCKSCREEN transition into discrete steps for corresponding views to
35  * consume.
36  */
37 @ExperimentalCoroutinesApi
38 @SysUISingleton
39 class DreamingToLockscreenTransitionViewModel
40 @Inject
41 constructor(
42     private val fromDreamingTransitionInteractor: FromDreamingTransitionInteractor,
43     animationFlow: KeyguardTransitionAnimationFlow,
44 ) : DeviceEntryIconTransition {
45     fun startTransition() = fromDreamingTransitionInteractor.startToLockscreenTransition()
46 
47     private val transitionAnimation =
48         animationFlow.setup(
49             duration = TO_LOCKSCREEN_DURATION,
50             edge = Edge.create(from = DREAMING, to = LOCKSCREEN),
51         )
52 
53     /** Dream overlay y-translation on exit */
54     fun dreamOverlayTranslationY(translatePx: Int): Flow<Float> {
55         return transitionAnimation.sharedFlow(
56             duration = TO_LOCKSCREEN_DURATION,
57             onStep = { it * translatePx },
58             interpolator = EMPHASIZED,
59         )
60     }
61 
62     /** Dream overlay views alpha - fade out */
63     val dreamOverlayAlpha: Flow<Float> =
64         transitionAnimation.sharedFlow(
65             duration = 250.milliseconds,
66             onStep = { 1f - it },
67         )
68 
69     /** Lockscreen views y-translation */
70     fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
71         return transitionAnimation.sharedFlow(
72             duration = TO_LOCKSCREEN_DURATION,
73             onStep = { value -> -translatePx + value * translatePx },
74             // Reset on cancel or finish
75             onFinish = { 0f },
76             onCancel = { 0f },
77             interpolator = EMPHASIZED,
78         )
79     }
80 
81     /** Lockscreen views alpha */
82     val lockscreenAlpha: Flow<Float> =
83         transitionAnimation.sharedFlow(
84             startTime = 233.milliseconds,
85             duration = 250.milliseconds,
86             onStep = { it },
87         )
88 
89     val shortcutsAlpha: Flow<Float> =
90         transitionAnimation.sharedFlow(
91             startTime = 233.milliseconds,
92             duration = 250.milliseconds,
93             onStep = { it },
94             onCancel = { 0f },
95         )
96 
97     val deviceEntryBackgroundViewAlpha = transitionAnimation.immediatelyTransitionTo(1f)
98     override val deviceEntryParentViewAlpha = lockscreenAlpha
99 }
100