• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
20 import com.android.systemui.deviceentry.domain.interactor.BiometricMessageInteractor
21 import com.android.systemui.deviceentry.shared.model.BiometricMessage
22 import com.android.systemui.deviceentry.shared.model.FaceMessage
23 import com.android.systemui.deviceentry.shared.model.FaceTimeoutMessage
24 import com.android.systemui.deviceentry.shared.model.FingerprintLockoutMessage
25 import com.android.systemui.deviceentry.shared.model.FingerprintMessage
26 import com.android.systemui.statusbar.KeyguardIndicationController.DEFAULT_MESSAGE_TIME
27 import com.android.systemui.util.kotlin.sample
28 import javax.inject.Inject
29 import kotlinx.coroutines.flow.Flow
30 import kotlinx.coroutines.flow.filter
31 import kotlinx.coroutines.flow.filterIsInstance
32 import kotlinx.coroutines.flow.filterNot
33 import kotlinx.coroutines.flow.flatMapLatest
34 import kotlinx.coroutines.flow.flowOf
35 import kotlinx.coroutines.flow.map
36 import kotlinx.coroutines.flow.merge
37 import kotlinx.coroutines.flow.onStart
38 
39 /** View model for the alternate bouncer message area. */
40 class AlternateBouncerMessageAreaViewModel
41 @Inject
42 constructor(
43     biometricMessageInteractor: BiometricMessageInteractor,
44     alternateBouncerInteractor: AlternateBouncerInteractor,
45     systemClock: com.android.systemui.util.time.SystemClock,
46 ) {
47     private val fingerprintMessageWithTimestamp: Flow<Pair<FingerprintMessage?, Long>> =
48         biometricMessageInteractor.fingerprintMessage
49             .filterNot { it is FingerprintLockoutMessage }
50             .map { Pair(it, systemClock.uptimeMillis()) }
51             .filterIsInstance<Pair<FingerprintMessage?, Long>>()
52             .onStart { emit(Pair(null, -3500L)) }
53     private val fingerprintMessage: Flow<FingerprintMessage> =
54         fingerprintMessageWithTimestamp.filter { it.first != null }.map { it.first!! }
55     private val faceMessage: Flow<FaceMessage> =
56         biometricMessageInteractor.faceMessage
57             .filterNot { it is FaceTimeoutMessage }
58             // Don't show face messages if within the default message time for fp messages to show
59             .sample(fingerprintMessageWithTimestamp, ::Pair)
60             .filter { (_, fpMessage) ->
61                 (systemClock.uptimeMillis() - fpMessage.second) >= DEFAULT_MESSAGE_TIME
62             }
63             .map { (faceMsg, _) -> faceMsg }
64 
65     val message: Flow<BiometricMessage?> =
66         alternateBouncerInteractor.isVisible.flatMapLatest { isVisible ->
67             if (isVisible) {
68                 merge(
69                     fingerprintMessage,
70                     faceMessage,
71                 )
72             } else {
73                 flowOf(null)
74             }
75         }
76 }
77