1 /*
<lambda>null2  * Copyright (C) 2024 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.dagger.qualifiers.Application
21 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
22 import com.android.systemui.keyguard.data.repository.KeyguardRepository
23 import com.android.systemui.keyguard.shared.model.KeyguardState
24 import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
25 import javax.inject.Inject
26 import kotlinx.coroutines.CoroutineScope
27 import kotlinx.coroutines.flow.Flow
28 import kotlinx.coroutines.flow.filter
29 import kotlinx.coroutines.flow.map
30 import kotlinx.coroutines.launch
31 
32 /**
33  * Logic around the keyguard being enabled/disabled, per [KeyguardService]. If the keyguard is not
34  * enabled, the lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE.
35  *
36  * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold
37  * permission to do so (such as Phone). Some CTS tests also disable keyguard in onCreate or onStart
38  * rather than simply dismissing the keyguard or setting up the device to have Security: None, for
39  * reasons unknown.
40  */
41 @SysUISingleton
42 class KeyguardEnabledInteractor
43 @Inject
44 constructor(
45     @Application scope: CoroutineScope,
46     val repository: KeyguardRepository,
47     val biometricSettingsRepository: BiometricSettingsRepository,
48     transitionInteractor: KeyguardTransitionInteractor,
49 ) {
50 
51     init {
52         /**
53          * Whenever keyguard is disabled, transition to GONE unless we're in lockdown or already
54          * GONE.
55          */
56         scope.launch {
57             repository.isKeyguardEnabled
58                 .filter { enabled -> !enabled }
59                 .sampleCombine(
60                     biometricSettingsRepository.isCurrentUserInLockdown,
61                     transitionInteractor.currentTransitionInfoInternal,
62                 )
63                 .collect { (_, inLockdown, currentTransitionInfo) ->
64                     if (currentTransitionInfo.to != KeyguardState.GONE && !inLockdown) {
65                         transitionInteractor.startDismissKeyguardTransition("keyguard disabled")
66                     }
67                 }
68         }
69     }
70 
71     /**
72      * Whether we need to show the keyguard when the keyguard is re-enabled, since we hid it when it
73      * became disabled.
74      */
75     val showKeyguardWhenReenabled: Flow<Boolean> =
76         repository.isKeyguardEnabled
77             // Whenever the keyguard is disabled...
78             .filter { enabled -> !enabled }
79             .sampleCombine(
80                 transitionInteractor.currentTransitionInfoInternal,
81                 biometricSettingsRepository.isCurrentUserInLockdown
82             )
83             .map { (_, transitionInfo, inLockdown) ->
84                 // ...we hide the keyguard, if it's showing and we're not in lockdown. In that case,
85                 // we want to remember that and re-show it when keyguard is enabled again.
86                 transitionInfo.to != KeyguardState.GONE && !inLockdown
87             }
88 
89     fun notifyKeyguardEnabled(enabled: Boolean) {
90         repository.setKeyguardEnabled(enabled)
91     }
92 }
93