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.domain.interactor
18 
19 import com.android.systemui.dagger.SysUISingleton
20 import com.android.systemui.keyguard.data.repository.KeyguardSurfaceBehindRepository
21 import com.android.systemui.keyguard.shared.model.KeyguardState
22 import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
23 import kotlinx.coroutines.ExperimentalCoroutinesApi
24 import kotlinx.coroutines.flow.Flow
25 import kotlinx.coroutines.flow.combine
26 import kotlinx.coroutines.flow.flatMapLatest
27 import kotlinx.coroutines.flow.flowOf
28 import kotlinx.coroutines.flow.map
29 import javax.inject.Inject
30 
31 @SysUISingleton
32 class KeyguardSurfaceBehindInteractor
33 @Inject
34 constructor(
35     private val repository: KeyguardSurfaceBehindRepository,
36     private val fromLockscreenInteractor: FromLockscreenTransitionInteractor,
37     private val fromPrimaryBouncerInteractor: FromPrimaryBouncerTransitionInteractor,
38     transitionInteractor: KeyguardTransitionInteractor,
39 ) {
40 
41     @OptIn(ExperimentalCoroutinesApi::class)
42     val viewParams: Flow<KeyguardSurfaceBehindModel> =
43         transitionInteractor.isInTransitionToAnyState
44             .flatMapLatest { isInTransition ->
45                 if (!isInTransition) {
46                     defaultParams
47                 } else {
48                     combine(
49                         transitionSpecificViewParams,
50                         defaultParams,
51                     ) { transitionParams, defaultParams ->
52                         transitionParams ?: defaultParams
53                     }
54                 }
55             }
56 
57     val isAnimatingSurface = repository.isAnimatingSurface
58 
59     private val defaultParams =
60         transitionInteractor.finishedKeyguardState.map { state ->
61             KeyguardSurfaceBehindModel(
62                 alpha =
63                     if (WindowManagerLockscreenVisibilityInteractor.isSurfaceVisible(state)) 1f
64                     else 0f
65             )
66         }
67 
68     /**
69      * View params provided by the transition interactor for the most recently STARTED transition.
70      * This is used to run transition-specific animations on the surface.
71      *
72      * If null, there are no transition-specific view params needed for this transition and we will
73      * use a reasonable default.
74      */
75     @OptIn(ExperimentalCoroutinesApi::class)
76     private val transitionSpecificViewParams: Flow<KeyguardSurfaceBehindModel?> =
77         transitionInteractor.startedKeyguardTransitionStep.flatMapLatest { startedStep ->
78             when (startedStep.from) {
79                 KeyguardState.LOCKSCREEN -> fromLockscreenInteractor.surfaceBehindModel
80                 KeyguardState.PRIMARY_BOUNCER -> fromPrimaryBouncerInteractor.surfaceBehindModel
81                 // Return null for other states, where no transition specific params are needed.
82                 else -> flowOf(null)
83             }
84         }
85 
86     fun setAnimatingSurface(animating: Boolean) {
87         repository.setAnimatingSurface(animating)
88     }
89 }
90