• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2022 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.data.repository
18 
19 import android.graphics.Point
20 import com.android.app.tracing.coroutines.launchTraced as launch
21 import com.android.internal.widget.LockPatternUtils
22 import com.android.keyguard.KeyguardUpdateMonitor
23 import com.android.keyguard.KeyguardUpdateMonitorCallback
24 import com.android.systemui.biometrics.AuthController
25 import com.android.systemui.biometrics.data.repository.FacePropertyRepository
26 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
27 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
28 import com.android.systemui.dagger.SysUISingleton
29 import com.android.systemui.dagger.qualifiers.Application
30 import com.android.systemui.dagger.qualifiers.Main
31 import com.android.systemui.doze.DozeMachine
32 import com.android.systemui.doze.DozeTransitionCallback
33 import com.android.systemui.doze.DozeTransitionListener
34 import com.android.systemui.dreams.DreamOverlayCallbackController
35 import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
36 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
37 import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
38 import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
39 import com.android.systemui.keyguard.shared.model.DismissAction
40 import com.android.systemui.keyguard.shared.model.DozeStateModel
41 import com.android.systemui.keyguard.shared.model.DozeTransitionModel
42 import com.android.systemui.keyguard.shared.model.KeyguardDone
43 import com.android.systemui.keyguard.shared.model.StatusBarState
44 import com.android.systemui.plugins.statusbar.StatusBarStateController
45 import com.android.systemui.scene.shared.flag.SceneContainerFlag
46 import com.android.systemui.settings.UserTracker
47 import com.android.systemui.statusbar.policy.KeyguardStateController
48 import com.android.systemui.util.time.SystemClock
49 import javax.inject.Inject
50 import kotlinx.coroutines.CoroutineDispatcher
51 import kotlinx.coroutines.CoroutineScope
52 import kotlinx.coroutines.channels.awaitClose
53 import kotlinx.coroutines.flow.Flow
54 import kotlinx.coroutines.flow.MutableSharedFlow
55 import kotlinx.coroutines.flow.MutableStateFlow
56 import kotlinx.coroutines.flow.SharingStarted
57 import kotlinx.coroutines.flow.StateFlow
58 import kotlinx.coroutines.flow.asSharedFlow
59 import kotlinx.coroutines.flow.asStateFlow
60 import kotlinx.coroutines.flow.distinctUntilChanged
61 import kotlinx.coroutines.flow.emptyFlow
62 import kotlinx.coroutines.flow.filter
63 import kotlinx.coroutines.flow.flowOn
64 import kotlinx.coroutines.flow.mapLatest
65 import kotlinx.coroutines.flow.onStart
66 import kotlinx.coroutines.flow.stateIn
67 
68 /** Defines interface for classes that encapsulate application state for the keyguard. */
69 interface KeyguardRepository {
70     /**
71      * Observable for whether the bottom area UI should animate the transition out of doze state.
72      *
73      * To learn more about doze state, please see [isDozing].
74      */
75     val animateBottomAreaDozingTransitions: StateFlow<Boolean>
76 
77     val keyguardAlpha: StateFlow<Float>
78 
79     val panelAlpha: MutableStateFlow<Float>
80 
81     val zoomOut: StateFlow<Float>
82 
83     /**
84      * Observable for whether the keyguard is showing.
85      *
86      * Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in
87      * the z-order (which is not really above the system UI window, but rather - the lock-screen
88      * becomes invisible to reveal the "occluding activity").
89      */
90     val isKeyguardShowing: StateFlow<Boolean>
91 
92     /** Is an activity showing over the keyguard? */
93     @Deprecated("Use KeyguardTransitionInteractor + KeyguardState.OCCLUDED")
94     val isKeyguardOccluded: StateFlow<Boolean>
95 
96     /**
97      * Whether the device is locked or unlocked right now. This is true when keyguard has been
98      * dismissed or can be dismissed by a swipe
99      */
100     val isKeyguardDismissible: StateFlow<Boolean>
101 
102     /**
103      * Observable for the signal that keyguard is about to go away.
104      *
105      * TODO(b/278086361): Remove once KEYGUARD_WM_STATE_REFACTOR flag is removed.
106      */
107     @Deprecated(
108         "Use KeyguardTransitionInteractor flows instead. The closest match for 'going " +
109             "away' is isInTransitionToState(GONE), but consider using more specific flows " +
110             "whenever possible."
111     )
112     val isKeyguardGoingAway: MutableStateFlow<Boolean>
113 
114     /**
115      * Whether the keyguard is enabled, per [KeyguardService]. If the keyguard is not enabled, the
116      * lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE.
117      *
118      * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold
119      * permission to do so (such as Phone).
120      *
121      * If the keyguard is disabled while we're locked, we will transition to GONE unless we're in
122      * lockdown mode. If the keyguard is re-enabled, we'll transition back to LOCKSCREEN if we were
123      * locked when it was disabled.
124      */
125     val isKeyguardEnabled: StateFlow<Boolean>
126 
127     /**
128      * Whether we can transition directly back to GONE from AOD/DOZING without any authentication
129      * events (such as a fingerprint wake and unlock), even though authentication would normally be
130      * required. This means that if you tap the screen or press the power button, you'll return
131      * directly to the unlocked app content without seeing the lockscreen, even if a secure
132      * authentication method (PIN/password/biometrics) is set.
133      *
134      * This is true in these cases:
135      * - The screen timed out, but the "lock after screen timeout" duration (default 5 seconds) has
136      *   not yet elapsed.
137      * - The power button was pressed, but "power button instantly locks" is not enabled, and the
138      *   "lock after screen timeout" duration has not elapsed.
139      *
140      * Note that this value specifically tells us if we can *ignore* authentication that would
141      * otherwise be required to transition from AOD/DOZING -> GONE. AOD/DOZING -> GONE is also
142      * possible if keyguard is disabled, either from an app request or because security is set to
143      * "none", but in that case, auth is not required so this boolean is not relevant.
144      *
145      * See [KeyguardWakeToGoneInteractor].
146      */
147     val canIgnoreAuthAndReturnToGone: StateFlow<Boolean>
148 
149     fun setCanIgnoreAuthAndReturnToGone(canWake: Boolean)
150 
151     /** Is the always-on display available to be used? */
152     val isAodAvailable: StateFlow<Boolean>
153 
154     fun setAodAvailable(value: Boolean)
155 
156     /**
157      * Observable for whether we are in doze state.
158      *
159      * Doze state is the same as "Always on Display" or "AOD". It is the state that the device can
160      * enter to conserve battery when the device is locked and inactive.
161      *
162      * Note that it is possible for the system to be transitioning into doze while this flow still
163      * returns `false`. In order to account for that, observers should also use the
164      * [linearDozeAmount] flow to check if it's greater than `0`
165      */
166     val isDozing: StateFlow<Boolean>
167 
168     /** Keyguard can be clipped at the top as the shade is dragged */
169     val topClippingBounds: MutableStateFlow<Int?>
170 
171     /**
172      * Observable for whether the device is dreaming.
173      *
174      * Dozing/AOD is a specific type of dream, but it is also possible for other non-systemui dreams
175      * to be active, such as screensavers.
176      */
177     val isDreaming: MutableStateFlow<Boolean>
178 
179     /** Observable for whether the device is dreaming with an overlay, see [DreamOverlayService] */
180     val isDreamingWithOverlay: Flow<Boolean>
181 
182     /**
183      * Observable for the amount of doze we are currently in.
184      *
185      * While in doze state, this amount can change - driving a cycle of animations designed to avoid
186      * pixel burn-in, etc.
187      *
188      * Also note that the value here may be greater than `0` while [isDozing] is still `false`, this
189      * happens during an animation/transition into doze mode. An observer would be wise to account
190      * for both flows if needed.
191      */
192     val linearDozeAmount: Flow<Float>
193 
194     /** Doze state information, as it transitions */
195     val dozeTransitionModel: Flow<DozeTransitionModel>
196 
197     val lastDozeTapToWakePosition: StateFlow<Point?>
198 
199     /** Last point that [KeyguardRootView] was tapped */
200     val lastRootViewTapPosition: MutableStateFlow<Point?>
201 
202     /** Is the ambient indication area visible? */
203     val ambientIndicationVisible: MutableStateFlow<Boolean>
204 
205     /** Observable for the [StatusBarState] */
206     val statusBarState: StateFlow<StatusBarState>
207 
208     /** Observable for biometric unlock state which includes the mode and unlock source */
209     val biometricUnlockState: StateFlow<BiometricUnlockModel>
210 
211     fun setBiometricUnlockState(
212         unlockMode: BiometricUnlockMode,
213         unlockSource: BiometricUnlockSource?,
214     )
215 
216     /** Approximate location on the screen of the fingerprint sensor. */
217     val fingerprintSensorLocation: Flow<Point?>
218 
219     /** Approximate location on the screen of the face unlock sensor/front facing camera. */
220     val faceSensorLocation: Flow<Point?>
221 
222     /** Whether quick settings or quick-quick settings is visible. */
223     val isQuickSettingsVisible: Flow<Boolean>
224 
225     /** Receive an event for doze time tick */
226     val dozeTimeTick: Flow<Long>
227 
228     /** Receive an event lockscreen being shown in a dismissible state */
229     val showDismissibleKeyguard: MutableStateFlow<Long>
230 
231     /** Observable for DismissAction */
232     val dismissAction: StateFlow<DismissAction>
233 
234     /** Observable updated when keyguardDone should be called either now or soon. */
235     val keyguardDone: Flow<KeyguardDone>
236 
237     /** Last camera launch detection event */
238     val onCameraLaunchDetected: MutableStateFlow<CameraLaunchSourceModel>
239 
240     /**
241      * Emits after the keyguard is done animating away.
242      *
243      * TODO(b/278086361): Remove once KEYGUARD_WM_STATE_REFACTOR flag is removed.
244      */
245     @Deprecated(
246         "Use KeyguardTransitionInteractor flows instead. The closest match for " +
247             "'keyguardDoneAnimationsFinished' is when the GONE transition is finished."
248     )
249     val keyguardDoneAnimationsFinished: Flow<Unit>
250 
251     /**
252      * Whether the primary authentication is required for the given user due to lockdown or
253      * encryption after reboot.
254      */
255     val isEncryptedOrLockdown: Flow<Boolean>
256 
257     /**
258      * Returns `true` if the keyguard is showing; `false` otherwise.
259      *
260      * Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in
261      * the z-order (which is not really above the system UI window, but rather - the lock-screen
262      * becomes invisible to reveal the "occluding activity").
263      */
264     fun isKeyguardShowing(): Boolean
265 
266     /** Sets whether the bottom area UI should animate the transition out of doze state. */
267     fun setAnimateDozingTransitions(animate: Boolean)
268 
269     /** Sets the current amount of alpha that should be used for rendering the keyguard. */
270     fun setKeyguardAlpha(alpha: Float)
271 
272     /** Temporary shim for fading out content when the brightness slider is used */
273     fun setPanelAlpha(alpha: Float)
274 
275     /** Sets the zoom out scale of spatial model pushback from e.g. pulling down the shade. */
276     fun setZoomOut(zoomOutFromShadeRadius: Float)
277 
278     /** Whether the device is actively dreaming */
279     fun setDreaming(isDreaming: Boolean)
280 
281     /**
282      * Returns whether the keyguard bottom area should be constrained to the top of the lock icon
283      */
284     fun isUdfpsSupported(): Boolean
285 
286     /** Sets whether quick settings or quick-quick settings is visible. */
287     fun setQuickSettingsVisible(isVisible: Boolean)
288 
289     fun setLastDozeTapToWakePosition(position: Point)
290 
291     fun setIsDozing(isDozing: Boolean)
292 
293     fun dozeTimeTick()
294 
295     fun showDismissibleKeyguard()
296 
297     fun setDismissAction(dismissAction: DismissAction)
298 
299     suspend fun setKeyguardDone(keyguardDoneType: KeyguardDone)
300 
301     /**
302      * Updates signal that the keyguard done animations are finished
303      *
304      * TODO(b/278086361): Remove once KEYGUARD_WM_STATE_REFACTOR flag is removed.
305      */
306     @Deprecated(
307         "Use KeyguardTransitionInteractor flows instead. The closest match for " +
308             "'keyguardDoneAnimationsFinished' is when the GONE transition is finished."
309     )
310     fun keyguardDoneAnimationsFinished()
311 
312     /** Sets whether the keyguard is enabled (see [isKeyguardEnabled]). */
313     fun setKeyguardEnabled(enabled: Boolean)
314 
315     /** @see isShowKeyguardWhenReenabled */
316     fun setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled: Boolean)
317 
318     /**
319      * Returns `true` if the keyguard should be re-shown once it becomes re-enabled again; `false`
320      * otherwise.
321      */
322     fun isShowKeyguardWhenReenabled(): Boolean
323 }
324 
325 /** Encapsulates application state for the keyguard. */
326 @SysUISingleton
327 class KeyguardRepositoryImpl
328 @Inject
329 constructor(
330     statusBarStateController: StatusBarStateController,
331     private val keyguardStateController: KeyguardStateController,
332     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
333     private val dozeTransitionListener: DozeTransitionListener,
334     private val authController: AuthController,
335     private val dreamOverlayCallbackController: DreamOverlayCallbackController,
336     @Main private val mainDispatcher: CoroutineDispatcher,
337     @Application private val scope: CoroutineScope,
338     private val systemClock: SystemClock,
339     facePropertyRepository: FacePropertyRepository,
340     private val userTracker: UserTracker,
341     lockPatternUtils: LockPatternUtils,
342 ) : KeyguardRepository {
343     private val _dismissAction: MutableStateFlow<DismissAction> =
344         MutableStateFlow(DismissAction.None)
345     override val dismissAction = _dismissAction.asStateFlow()
346 
setDismissActionnull347     override fun setDismissAction(dismissAction: DismissAction) {
348         _dismissAction.value = dismissAction
349     }
350 
351     private val _keyguardDone: MutableSharedFlow<KeyguardDone> = MutableSharedFlow()
352     override val keyguardDone = _keyguardDone.asSharedFlow()
353 
setKeyguardDonenull354     override suspend fun setKeyguardDone(keyguardDoneType: KeyguardDone) {
355         _keyguardDone.emit(keyguardDoneType)
356     }
357 
358     override val keyguardDoneAnimationsFinished: MutableSharedFlow<Unit> = MutableSharedFlow()
359 
keyguardDoneAnimationsFinishednull360     override fun keyguardDoneAnimationsFinished() {
361         keyguardDoneAnimationsFinished.tryEmit(Unit)
362     }
363 
364     private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
365     override val animateBottomAreaDozingTransitions =
366         _animateBottomAreaDozingTransitions.asStateFlow()
367 
368     private val _keyguardAlpha = MutableStateFlow(1f)
369     override val keyguardAlpha = _keyguardAlpha.asStateFlow()
370 
371     override val onCameraLaunchDetected = MutableStateFlow(CameraLaunchSourceModel())
372 
373     override val panelAlpha: MutableStateFlow<Float> = MutableStateFlow(1f)
374     override val zoomOut: MutableStateFlow<Float> = MutableStateFlow(0f)
375     override val topClippingBounds = MutableStateFlow<Int?>(null)
376 
377     override val isKeyguardShowing: MutableStateFlow<Boolean> =
378         MutableStateFlow(keyguardStateController.isShowing)
379 
380     private val _isAodAvailable = MutableStateFlow(false)
381     override val isAodAvailable: StateFlow<Boolean> = _isAodAvailable.asStateFlow()
382 
setAodAvailablenull383     override fun setAodAvailable(value: Boolean) {
384         _isAodAvailable.value = value
385     }
386 
387     override val isKeyguardOccluded: MutableStateFlow<Boolean> =
388         MutableStateFlow(keyguardStateController.isOccluded)
389 
390     override val isKeyguardDismissible: MutableStateFlow<Boolean> =
391         MutableStateFlow(keyguardStateController.isUnlocked)
392 
393     override val isKeyguardGoingAway: MutableStateFlow<Boolean> =
394         MutableStateFlow(keyguardStateController.isKeyguardGoingAway)
395 
396     private val _isKeyguardEnabled =
397         MutableStateFlow(!lockPatternUtils.isLockScreenDisabled(userTracker.userId))
398     override val isKeyguardEnabled: StateFlow<Boolean> = _isKeyguardEnabled.asStateFlow()
399 
400     private val _canIgnoreAuthAndReturnToGone = MutableStateFlow(false)
401     override val canIgnoreAuthAndReturnToGone = _canIgnoreAuthAndReturnToGone.asStateFlow()
402 
setCanIgnoreAuthAndReturnToGonenull403     override fun setCanIgnoreAuthAndReturnToGone(canWakeToGone: Boolean) {
404         _canIgnoreAuthAndReturnToGone.value = canWakeToGone
405     }
406 
407     private val _isDozing = MutableStateFlow(statusBarStateController.isDozing)
408     override val isDozing: StateFlow<Boolean> = _isDozing.asStateFlow()
409 
410     private var isShowKeyguardWhenReenabled: Boolean = false
411 
setIsDozingnull412     override fun setIsDozing(isDozing: Boolean) {
413         _isDozing.value = isDozing
414     }
415 
416     private val _dozeTimeTick = MutableStateFlow<Long>(0)
417     override val dozeTimeTick = _dozeTimeTick.asStateFlow()
418 
dozeTimeTicknull419     override fun dozeTimeTick() {
420         _dozeTimeTick.value = systemClock.uptimeMillis()
421     }
422 
423     override val showDismissibleKeyguard = MutableStateFlow<Long>(0L)
424 
showDismissibleKeyguardnull425     override fun showDismissibleKeyguard() {
426         showDismissibleKeyguard.value = systemClock.uptimeMillis()
427     }
428 
429     private val _lastDozeTapToWakePosition = MutableStateFlow<Point?>(null)
430     override val lastDozeTapToWakePosition = _lastDozeTapToWakePosition.asStateFlow()
431 
setLastDozeTapToWakePositionnull432     override fun setLastDozeTapToWakePosition(position: Point) {
433         _lastDozeTapToWakePosition.value = position
434     }
435 
436     override val lastRootViewTapPosition: MutableStateFlow<Point?> = MutableStateFlow(null)
437 
438     override val ambientIndicationVisible: MutableStateFlow<Boolean> = MutableStateFlow(false)
439 
440     override val isDreamingWithOverlay: Flow<Boolean> =
<lambda>null441         conflatedCallbackFlow {
442                 val callback =
443                     object : DreamOverlayCallbackController.Callback {
444                         override fun onStartDream() {
445                             trySendWithFailureLogging(true, TAG, "updated isDreamingWithOverlay")
446                         }
447 
448                         override fun onWakeUp() {
449                             trySendWithFailureLogging(false, TAG, "updated isDreamingWithOverlay")
450                         }
451                     }
452                 dreamOverlayCallbackController.addCallback(callback)
453                 trySendWithFailureLogging(
454                     dreamOverlayCallbackController.isDreaming,
455                     TAG,
456                     "initial isDreamingWithOverlay",
457                 )
458 
459                 awaitClose { dreamOverlayCallbackController.removeCallback(callback) }
460             }
461             .distinctUntilChanged()
462 
463     override val isDreaming: MutableStateFlow<Boolean> = MutableStateFlow(false)
464 
465     private val _preSceneLinearDozeAmount: Flow<Float> =
466         if (SceneContainerFlag.isEnabled) {
467             emptyFlow()
468         } else {
<lambda>null469             conflatedCallbackFlow {
470                 val callback =
471                     object : StatusBarStateController.StateListener {
472                         override fun onDozeAmountChanged(linear: Float, eased: Float) {
473                             trySendWithFailureLogging(linear, TAG, "updated dozeAmount")
474                         }
475                     }
476 
477                 statusBarStateController.addCallback(callback)
478                 trySendWithFailureLogging(
479                     statusBarStateController.dozeAmount,
480                     TAG,
481                     "initial dozeAmount",
482                 )
483 
484                 awaitClose { statusBarStateController.removeCallback(callback) }
485             }
486         }
487 
488     override val linearDozeAmount: Flow<Float>
489         get() {
490             SceneContainerFlag.assertInLegacyMode()
491             return _preSceneLinearDozeAmount
492         }
493 
<lambda>null494     override val dozeTransitionModel: Flow<DozeTransitionModel> = conflatedCallbackFlow {
495         val callback =
496             object : DozeTransitionCallback {
497                 override fun onDozeTransition(
498                     oldState: DozeMachine.State,
499                     newState: DozeMachine.State,
500                 ) {
501                     trySendWithFailureLogging(
502                         DozeTransitionModel(
503                             from = dozeMachineStateToModel(oldState),
504                             to = dozeMachineStateToModel(newState),
505                         ),
506                         TAG,
507                         "doze transition model",
508                     )
509                 }
510             }
511 
512         dozeTransitionListener.addCallback(callback)
513         trySendWithFailureLogging(
514             DozeTransitionModel(
515                 from = dozeMachineStateToModel(dozeTransitionListener.oldState),
516                 to = dozeMachineStateToModel(dozeTransitionListener.newState),
517             ),
518             TAG,
519             "initial doze transition model",
520         )
521 
522         awaitClose { dozeTransitionListener.removeCallback(callback) }
523     }
524 
525     override val isEncryptedOrLockdown: Flow<Boolean> =
<lambda>null526         conflatedCallbackFlow {
527                 val callback =
528                     object : KeyguardUpdateMonitorCallback() {
529                         override fun onStrongAuthStateChanged(userId: Int) {
530                             trySendWithFailureLogging(userId, TAG, "strong auth state change")
531                         }
532                     }
533                 keyguardUpdateMonitor.registerCallback(callback)
534                 awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
535             }
userIdnull536             .filter { userId -> userId == userTracker.userId }
<lambda>null537             .onStart { emit(userTracker.userId) }
userIdnull538             .mapLatest { userId -> keyguardUpdateMonitor.isEncryptedOrLockdown(userId) }
539             // KeyguardUpdateMonitor#registerCallback needs to be called on the main thread.
540             .flowOn(mainDispatcher)
541 
isKeyguardShowingnull542     override fun isKeyguardShowing(): Boolean {
543         return keyguardStateController.isShowing
544     }
545 
546     // TODO(b/297345631): Expose this at the interactor level instead so that it can be powered by
547     // [SceneInteractor] when scenes are ready.
548     override val statusBarState: StateFlow<StatusBarState> =
<lambda>null549         conflatedCallbackFlow {
550                 val callback =
551                     object : StatusBarStateController.StateListener {
552                         override fun onStateChanged(state: Int) {
553                             trySendWithFailureLogging(
554                                 statusBarStateIntToObject(state),
555                                 TAG,
556                                 "state",
557                             )
558                         }
559                     }
560 
561                 statusBarStateController.addCallback(callback)
562                 awaitClose { statusBarStateController.removeCallback(callback) }
563             }
564             .stateIn(
565                 scope,
566                 SharingStarted.Eagerly,
567                 statusBarStateIntToObject(statusBarStateController.state),
568             )
569 
570     private val _biometricUnlockState: MutableStateFlow<BiometricUnlockModel> =
571         MutableStateFlow(BiometricUnlockModel(BiometricUnlockMode.NONE, null))
572     override val biometricUnlockState: StateFlow<BiometricUnlockModel> =
573         _biometricUnlockState.asStateFlow()
574 
setBiometricUnlockStatenull575     override fun setBiometricUnlockState(
576         unlockMode: BiometricUnlockMode,
577         unlockSource: BiometricUnlockSource?,
578     ) {
579         _biometricUnlockState.value = BiometricUnlockModel(unlockMode, unlockSource)
580     }
581 
<lambda>null582     override val fingerprintSensorLocation: Flow<Point?> = conflatedCallbackFlow {
583         fun sendFpLocation() {
584             trySendWithFailureLogging(
585                 authController.fingerprintSensorLocation,
586                 TAG,
587                 "AuthController.Callback#onFingerprintLocationChanged",
588             )
589         }
590 
591         val callback =
592             object : AuthController.Callback {
593                 override fun onFingerprintLocationChanged() {
594                     sendFpLocation()
595                 }
596             }
597 
598         authController.addCallback(callback)
599         sendFpLocation()
600 
601         awaitClose { authController.removeCallback(callback) }
602     }
603 
604     override val faceSensorLocation: Flow<Point?> = facePropertyRepository.sensorLocation
605 
606     private val _isQuickSettingsVisible = MutableStateFlow(false)
607     override val isQuickSettingsVisible: Flow<Boolean> = _isQuickSettingsVisible.asStateFlow()
608 
609     init {
610         val callback =
611             object : KeyguardStateController.Callback {
onKeyguardShowingChangednull612                 override fun onKeyguardShowingChanged() {
613                     isKeyguardShowing.value = keyguardStateController.isShowing
614                     isKeyguardOccluded.value = keyguardStateController.isOccluded
615                     isKeyguardDismissible.value = keyguardStateController.isUnlocked
616                 }
617 
onUnlockedChangednull618                 override fun onUnlockedChanged() {
619                     isKeyguardDismissible.value = keyguardStateController.isUnlocked
620                 }
621             }
622 
623         keyguardStateController.addCallback(callback)
624 
625         scope
<lambda>null626             .launch {
627                 isKeyguardShowing.collect {
628                     // no-op to allow for callback removal
629                 }
630             }
<lambda>null631             .invokeOnCompletion { keyguardStateController.removeCallback(callback) }
632     }
633 
setAnimateDozingTransitionsnull634     override fun setAnimateDozingTransitions(animate: Boolean) {
635         _animateBottomAreaDozingTransitions.value = animate
636     }
637 
setKeyguardAlphanull638     override fun setKeyguardAlpha(alpha: Float) {
639         _keyguardAlpha.value = alpha
640     }
641 
setPanelAlphanull642     override fun setPanelAlpha(alpha: Float) {
643         panelAlpha.value = alpha
644     }
645 
setZoomOutnull646     override fun setZoomOut(zoomOutFromShadeRadius: Float) {
647         zoomOut.value = zoomOutFromShadeRadius
648     }
649 
setDreamingnull650     override fun setDreaming(isDreaming: Boolean) {
651         this.isDreaming.value = isDreaming
652     }
653 
isUdfpsSupportednull654     override fun isUdfpsSupported(): Boolean = keyguardUpdateMonitor.isUdfpsSupported
655 
656     override fun setQuickSettingsVisible(isVisible: Boolean) {
657         _isQuickSettingsVisible.value = isVisible
658     }
659 
setKeyguardEnablednull660     override fun setKeyguardEnabled(enabled: Boolean) {
661         _isKeyguardEnabled.value = enabled
662     }
663 
setShowKeyguardWhenReenablednull664     override fun setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled: Boolean) {
665         SceneContainerFlag.unsafeAssertInNewMode()
666         this.isShowKeyguardWhenReenabled = isShowKeyguardWhenReenabled
667     }
668 
isShowKeyguardWhenReenablednull669     override fun isShowKeyguardWhenReenabled(): Boolean {
670         SceneContainerFlag.unsafeAssertInNewMode()
671         return isShowKeyguardWhenReenabled
672     }
673 
statusBarStateIntToObjectnull674     private fun statusBarStateIntToObject(value: Int): StatusBarState {
675         return when (value) {
676             0 -> StatusBarState.SHADE
677             1 -> StatusBarState.KEYGUARD
678             2 -> StatusBarState.SHADE_LOCKED
679             else -> throw IllegalArgumentException("Invalid StatusBarState value: $value")
680         }
681     }
682 
dozeMachineStateToModelnull683     private fun dozeMachineStateToModel(state: DozeMachine.State): DozeStateModel {
684         return when (state) {
685             DozeMachine.State.UNINITIALIZED -> DozeStateModel.UNINITIALIZED
686             DozeMachine.State.INITIALIZED -> DozeStateModel.INITIALIZED
687             DozeMachine.State.DOZE -> DozeStateModel.DOZE
688             DozeMachine.State.DOZE_SUSPEND_TRIGGERS -> DozeStateModel.DOZE_SUSPEND_TRIGGERS
689             DozeMachine.State.DOZE_AOD -> DozeStateModel.DOZE_AOD
690             DozeMachine.State.DOZE_REQUEST_PULSE -> DozeStateModel.DOZE_REQUEST_PULSE
691             DozeMachine.State.DOZE_PULSING -> DozeStateModel.DOZE_PULSING
692             DozeMachine.State.DOZE_PULSING_BRIGHT -> DozeStateModel.DOZE_PULSING_BRIGHT
693             DozeMachine.State.DOZE_PULSE_DONE -> DozeStateModel.DOZE_PULSE_DONE
694             DozeMachine.State.FINISH -> DozeStateModel.FINISH
695             DozeMachine.State.DOZE_AOD_PAUSED -> DozeStateModel.DOZE_AOD_PAUSED
696             DozeMachine.State.DOZE_AOD_PAUSING -> DozeStateModel.DOZE_AOD_PAUSING
697             DozeMachine.State.DOZE_AOD_DOCKED -> DozeStateModel.DOZE_AOD_DOCKED
698             else -> throw IllegalArgumentException("Invalid DozeMachine.State: state")
699         }
700     }
701 
702     companion object {
703         private const val TAG = "KeyguardRepositoryImpl"
704     }
705 }
706