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.FromLockscreenTransitionInteractor
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 LOCKSCREEN->GLANCEABLE_HUB transition into discrete steps for corresponding views to
40  * consume.
41  */
42 @ExperimentalCoroutinesApi
43 @SysUISingleton
44 class LockscreenToGlanceableHubTransitionViewModel
45 @Inject
46 constructor(
47     configurationInteractor: ConfigurationInteractor,
48     animationFlow: KeyguardTransitionAnimationFlow,
49 ) {
50     private val transitionAnimation =
51         animationFlow
52             .setup(
53                 duration = FromLockscreenTransitionInteractor.TO_GLANCEABLE_HUB_DURATION,
54                 edge = Edge.create(from = LOCKSCREEN, to = Scenes.Communal),
55             )
56             .setupWithoutSceneContainer(
57                 edge = Edge.create(from = LOCKSCREEN, to = GLANCEABLE_HUB),
58             )
59 
60     val keyguardAlpha: Flow<Float> =
61         transitionAnimation.sharedFlow(
62             duration = 167.milliseconds,
63             onStep = { 1f - it },
64             onFinish = { 0f },
65             onCancel = { 1f },
66             name = "LOCKSCREEN->GLANCEABLE_HUB: keyguardAlpha",
67         )
68 
69     // Show UMO as long as keyguard is not visible.
70     val showUmo: Flow<Boolean> = keyguardAlpha.map { alpha -> alpha == 0f }
71 
72     val keyguardTranslationX: Flow<StateToValue> =
73         configurationInteractor
74             .dimensionPixelSize(R.dimen.lockscreen_to_hub_transition_lockscreen_translation_x)
75             .flatMapLatest { translatePx: Int ->
76                 transitionAnimation.sharedFlowWithState(
77                     duration = FromLockscreenTransitionInteractor.TO_GLANCEABLE_HUB_DURATION,
78                     onStep = { value -> value * translatePx },
79                     // Move notifications back to their original position since they can be
80                     // accessed from the shade, and also keyguard elements in case the animation
81                     // is cancelled.
82                     onFinish = { 0f },
83                     onCancel = { 0f },
84                     interpolator = EMPHASIZED,
85                     name = "LOCKSCREEN->GLANCEABLE_HUB: keyguardTranslationX"
86                 )
87             }
88 
89     val notificationAlpha: Flow<Float> = keyguardAlpha
90 
91     val shortcutsAlpha: Flow<Float> = keyguardAlpha
92 
93     val notificationTranslationX: Flow<Float> =
94         keyguardTranslationX.map { it.value }.filterNotNull()
95 }
96