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.ui.viewmodel
18 
19 import com.android.systemui.doze.util.BurnInHelperWrapper
20 import com.android.systemui.flags.FeatureFlags
21 import com.android.systemui.flags.Flags
22 import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
23 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
24 import javax.inject.Inject
25 import kotlinx.coroutines.flow.Flow
26 import kotlinx.coroutines.flow.combine
27 import kotlinx.coroutines.flow.distinctUntilChanged
28 import kotlinx.coroutines.flow.map
29 
30 /** View-model for the keyguard indication area view */
31 class KeyguardIndicationAreaViewModel
32 @Inject
33 constructor(
34     private val keyguardInteractor: KeyguardInteractor,
35     bottomAreaInteractor: KeyguardBottomAreaInteractor,
36     keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel,
37     private val burnInHelperWrapper: BurnInHelperWrapper,
38     private val shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel,
39     private val featureFlags: FeatureFlags,
40 ) {
41 
42     /** Notifies when a new configuration is set */
43     val configurationChange: Flow<Unit> = keyguardInteractor.configurationChange
44 
45     /** An observable for the alpha level for the entire bottom area. */
46     val alpha: Flow<Float> = keyguardBottomAreaViewModel.alpha
47 
48     /** An observable for whether the indication area should be padded. */
49     val isIndicationAreaPadded: Flow<Boolean> =
50         if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
51             combine(shortcutsCombinedViewModel.startButton, shortcutsCombinedViewModel.endButton) {
52                 startButtonModel,
53                 endButtonModel ->
54                 startButtonModel.isVisible || endButtonModel.isVisible
55             }
56                 .distinctUntilChanged()
57         } else {
58             combine(keyguardBottomAreaViewModel.startButton, keyguardBottomAreaViewModel.endButton) {
59                 startButtonModel,
60                 endButtonModel ->
61                 startButtonModel.isVisible || endButtonModel.isVisible
62             }
63                 .distinctUntilChanged()
64         }
65     /** An observable for the x-offset by which the indication area should be translated. */
66     val indicationAreaTranslationX: Flow<Float> =
67         if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
68             keyguardInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
69         } else {
70             bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
71         }
72 
73     /** Returns an observable for the y-offset by which the indication area should be translated. */
74     fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> {
75         return keyguardInteractor.dozeAmount
76             .map { dozeAmount ->
77                 dozeAmount *
78                     (burnInHelperWrapper.burnInOffset(
79                         /* amplitude = */ defaultBurnInOffset * 2,
80                         /* xAxis= */ false,
81                     ) - defaultBurnInOffset)
82             }
83             .distinctUntilChanged()
84     }
85 }
86