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