1 /*
<lambda>null2  * Copyright (C) 2024 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.common.ui.domain.interactor.ConfigurationInteractor
21 import com.android.systemui.dagger.SysUISingleton
22 import com.android.systemui.keyguard.domain.interactor.FromGlanceableHubTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
23 import com.android.systemui.keyguard.shared.model.Edge
24 import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
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.StateToValue
28 import com.android.systemui.res.R
29 import com.android.systemui.scene.shared.model.Scenes
30 import javax.inject.Inject
31 import kotlin.time.Duration.Companion.milliseconds
32 import kotlinx.coroutines.ExperimentalCoroutinesApi
33 import kotlinx.coroutines.flow.Flow
34 import kotlinx.coroutines.flow.filterNotNull
35 import kotlinx.coroutines.flow.flatMapLatest
36 import kotlinx.coroutines.flow.map
37 
38 /**
39  * Breaks down GLANCEABLE_HUB->LOCKSCREEN transition into discrete steps for corresponding views to
40  * consume.
41  */
42 @ExperimentalCoroutinesApi
43 @SysUISingleton
44 class GlanceableHubToLockscreenTransitionViewModel
45 @Inject
46 constructor(
47     configurationInteractor: ConfigurationInteractor,
48     animationFlow: KeyguardTransitionAnimationFlow,
49 ) {
50     private val transitionAnimation =
51         animationFlow
52             .setup(
53                 duration = TO_LOCKSCREEN_DURATION,
54                 edge = Edge.create(from = Scenes.Communal, to = LOCKSCREEN),
55             )
56             .setupWithoutSceneContainer(
57                 edge = Edge.create(from = GLANCEABLE_HUB, to = LOCKSCREEN),
58             )
59 
60     val keyguardAlpha: Flow<Float> =
61         transitionAnimation.sharedFlow(
62             duration = 167.milliseconds,
63             startTime = 167.milliseconds,
64             onStep = { it },
65             onFinish = { 1f },
66             onCancel = { 0f },
67             name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardAlpha",
68         )
69 
70     // Show UMO as long as keyguard is not visible.
71     val showUmo: Flow<Boolean> = keyguardAlpha.map { alpha -> alpha == 0f }
72 
73     val keyguardTranslationX: Flow<StateToValue> =
74         configurationInteractor
75             .dimensionPixelSize(R.dimen.hub_to_lockscreen_transition_lockscreen_translation_x)
76             .flatMapLatest { translatePx: Int ->
77                 transitionAnimation.sharedFlowWithState(
78                     duration = TO_LOCKSCREEN_DURATION,
79                     onStep = { value -> -translatePx + value * translatePx },
80                     interpolator = EMPHASIZED,
81                     // Move notifications back to their original position since they can be
82                     // accessed from the shade, and also keyguard elements in case the animation
83                     // is cancelled.
84                     onFinish = { 0f },
85                     onCancel = { 0f },
86                     name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardTranslationX"
87                 )
88             }
89 
90     val notificationAlpha: Flow<Float> = keyguardAlpha
91 
92     val shortcutsAlpha: Flow<Float> = keyguardAlpha
93 
94     val notificationTranslationX: Flow<Float> =
95         keyguardTranslationX.map { it.value }.filterNotNull()
96 }
97