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 
18 package com.android.systemui.keyguard.ui.binder
19 
20 import android.graphics.PorterDuff
21 import android.graphics.PorterDuffColorFilter
22 import androidx.lifecycle.Lifecycle
23 import androidx.lifecycle.repeatOnLifecycle
24 import com.airbnb.lottie.LottieAnimationView
25 import com.airbnb.lottie.LottieProperty
26 import com.airbnb.lottie.model.KeyPath
27 import com.android.systemui.keyguard.ui.viewmodel.FingerprintViewModel
28 import com.android.systemui.lifecycle.repeatWhenAttached
29 import kotlinx.coroutines.ExperimentalCoroutinesApi
30 import kotlinx.coroutines.launch
31 
32 @ExperimentalCoroutinesApi
33 object UdfpsFingerprintViewBinder {
34     private var udfpsIconColor = 0
35 
36     /**
37      * Drives UI for the UDFPS fingerprint view when it's NOT on aod. See
38      * [UdfpsAodFingerprintViewBinder] and [UdfpsBackgroundViewBinder].
39      */
40     @JvmStatic
41     fun bind(
42         view: LottieAnimationView,
43         viewModel: FingerprintViewModel,
44     ) {
45         view.alpha = 0f
46         view.repeatWhenAttached {
47             repeatOnLifecycle(Lifecycle.State.STARTED) {
48                 launch {
49                     viewModel.transition.collect {
50                         view.alpha = it.alpha
51                         view.scaleX = it.scale
52                         view.scaleY = it.scale
53                         if (udfpsIconColor != (it.color)) {
54                             udfpsIconColor = it.color
55                             view.invalidate()
56                         }
57                     }
58                 }
59 
60                 launch {
61                     viewModel.burnInOffsets.collect { burnInOffsets ->
62                         view.translationX = burnInOffsets.burnInXOffset.toFloat()
63                         view.translationY = burnInOffsets.burnInYOffset.toFloat()
64                     }
65                 }
66 
67                 launch {
68                     viewModel.dozeAmount.collect { dozeAmount ->
69                         // Lottie progress represents: aod=0 to lockscreen=1
70                         view.progress = 1f - dozeAmount
71                     }
72                 }
73 
74                 launch {
75                     viewModel.padding.collect { padding ->
76                         view.setPadding(padding, padding, padding, padding)
77                     }
78                 }
79             }
80         }
81 
82         // Add a callback that updates the color to `udfpsIconColor` whenever invalidate is called
83         view.addValueCallback(KeyPath("**"), LottieProperty.COLOR_FILTER) {
84             PorterDuffColorFilter(udfpsIconColor, PorterDuff.Mode.SRC_ATOP)
85         }
86     }
87 }
88