1 /*
<lambda>null2  * 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 android.content.Context
20 import com.android.settingslib.Utils
21 import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
22 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
23 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
24 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
25 import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
26 import com.android.systemui.shared.recents.utilities.Utilities.clamp
27 import javax.inject.Inject
28 import kotlinx.coroutines.ExperimentalCoroutinesApi
29 import kotlinx.coroutines.flow.Flow
30 import kotlinx.coroutines.flow.combine
31 import kotlinx.coroutines.flow.emptyFlow
32 import kotlinx.coroutines.flow.flatMapLatest
33 import kotlinx.coroutines.flow.flowOf
34 import kotlinx.coroutines.flow.map
35 import kotlinx.coroutines.flow.onStart
36 
37 /** Models the UI state for the UDFPS icon view in the alternate bouncer view. */
38 @ExperimentalCoroutinesApi
39 class AlternateBouncerUdfpsIconViewModel
40 @Inject
41 constructor(
42     val context: Context,
43     configurationInteractor: ConfigurationInteractor,
44     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
45     deviceEntryBackgroundViewModel: DeviceEntryBackgroundViewModel,
46     fingerprintPropertyInteractor: FingerprintPropertyInteractor,
47     udfpsOverlayInteractor: UdfpsOverlayInteractor,
48     alternateBouncerViewModel: AlternateBouncerViewModel,
49 ) {
50     private val isSupported: Flow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsSupported
51     val alpha: Flow<Float> =
52         alternateBouncerViewModel.transitionToAlternateBouncerProgress.map {
53             clamp(it * 2f, 0f, 1f)
54         }
55 
56     /**
57      * UDFPS icon location in pixels for the current display and screen resolution, in natural
58      * orientation.
59      */
60     val iconLocation: Flow<IconLocation> =
61         isSupported.flatMapLatest { supportsUI ->
62             if (supportsUI) {
63                 fingerprintPropertyInteractor.udfpsSensorBounds.map { bounds ->
64                     IconLocation(
65                         left = bounds.left,
66                         top = bounds.top,
67                         right = bounds.right,
68                         bottom = bounds.bottom,
69                     )
70                 }
71             } else {
72                 emptyFlow()
73             }
74         }
75     val accessibilityDelegateHint: Flow<DeviceEntryIconView.AccessibilityHintType> =
76         flowOf(DeviceEntryIconView.AccessibilityHintType.ENTER)
77 
78     private val fgIconColor: Flow<Int> =
79         configurationInteractor.onAnyConfigurationChange
80             .map { Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary) }
81             .onStart {
82                 emit(Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary))
83             }
84     private val fgIconPadding: Flow<Int> = udfpsOverlayInteractor.iconPadding
85     val fgViewModel: Flow<DeviceEntryForegroundViewModel.ForegroundIconViewModel> =
86         combine(
87             fgIconColor,
88             fgIconPadding,
89         ) { color, padding ->
90             DeviceEntryForegroundViewModel.ForegroundIconViewModel(
91                 type = DeviceEntryIconView.IconType.FINGERPRINT,
92                 useAodVariant = false,
93                 tint = color,
94                 padding = padding,
95             )
96         }
97 
98     val bgColor: Flow<Int> = deviceEntryBackgroundViewModel.color
99     val bgAlpha: Flow<Float> = flowOf(1f)
100 
101     data class IconLocation(
102         val left: Int,
103         val top: Int,
104         val right: Int,
105         val bottom: Int,
106     ) {
107         val width = right - left
108         val height = bottom - top
109     }
110 }
111