1 /* 2 * 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 android.hardware.biometrics.BiometricSourceType 21 import com.android.keyguard.KeyguardUpdateMonitor 22 import com.android.keyguard.KeyguardUpdateMonitorCallback 23 import com.android.systemui.biometrics.AuthController 24 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging 25 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow 26 import com.android.systemui.common.shared.model.Position 27 import com.android.systemui.dagger.SysUISingleton 28 import com.android.systemui.dagger.qualifiers.Application 29 import com.android.systemui.dagger.qualifiers.Main 30 import com.android.systemui.doze.DozeMachine 31 import com.android.systemui.doze.DozeTransitionCallback 32 import com.android.systemui.doze.DozeTransitionListener 33 import com.android.systemui.dreams.DreamOverlayCallbackController 34 import com.android.systemui.keyguard.ScreenLifecycle 35 import com.android.systemui.keyguard.WakefulnessLifecycle 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.DozeStateModel 39 import com.android.systemui.keyguard.shared.model.DozeTransitionModel 40 import com.android.systemui.keyguard.shared.model.KeyguardRootViewVisibilityState 41 import com.android.systemui.keyguard.shared.model.ScreenModel 42 import com.android.systemui.keyguard.shared.model.StatusBarState 43 import com.android.systemui.keyguard.shared.model.WakefulnessModel 44 import com.android.systemui.plugins.statusbar.StatusBarStateController 45 import com.android.systemui.statusbar.phone.BiometricUnlockController 46 import com.android.systemui.statusbar.phone.BiometricUnlockController.WakeAndUnlockMode 47 import com.android.systemui.statusbar.phone.DozeParameters 48 import com.android.systemui.statusbar.phone.KeyguardBypassController 49 import com.android.systemui.statusbar.policy.KeyguardStateController 50 import com.android.systemui.util.time.SystemClock 51 import javax.inject.Inject 52 import kotlinx.coroutines.CoroutineDispatcher 53 import kotlinx.coroutines.CoroutineScope 54 import kotlinx.coroutines.channels.awaitClose 55 import kotlinx.coroutines.flow.Flow 56 import kotlinx.coroutines.flow.MutableStateFlow 57 import kotlinx.coroutines.flow.SharingStarted 58 import kotlinx.coroutines.flow.StateFlow 59 import kotlinx.coroutines.flow.asStateFlow 60 import kotlinx.coroutines.flow.distinctUntilChanged 61 import kotlinx.coroutines.flow.flowOn 62 import kotlinx.coroutines.flow.stateIn 63 64 /** Defines interface for classes that encapsulate application state for the keyguard. */ 65 interface KeyguardRepository { 66 /** 67 * Observable for whether the bottom area UI should animate the transition out of doze state. 68 * 69 * To learn more about doze state, please see [isDozing]. 70 */ 71 val animateBottomAreaDozingTransitions: StateFlow<Boolean> 72 73 /** 74 * Observable for the current amount of alpha that should be used for rendering the bottom area. 75 * UI. 76 */ 77 val bottomAreaAlpha: StateFlow<Float> 78 79 val keyguardAlpha: StateFlow<Float> 80 81 /** 82 * Observable of the relative offset of the lock-screen clock from its natural position on the 83 * screen. 84 */ 85 val clockPosition: StateFlow<Position> 86 87 /** 88 * Observable for whether the keyguard is showing. 89 * 90 * Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in 91 * the z-order (which is not really above the system UI window, but rather - the lock-screen 92 * becomes invisible to reveal the "occluding activity"). 93 */ 94 val isKeyguardShowing: Flow<Boolean> 95 96 /** Is the keyguard in a unlocked state? */ 97 val isKeyguardUnlocked: StateFlow<Boolean> 98 99 /** Is an activity showing over the keyguard? */ 100 val isKeyguardOccluded: Flow<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: Flow<Boolean> 113 114 /** Is the always-on display available to be used? */ 115 val isAodAvailable: Flow<Boolean> 116 117 /** 118 * Observable for whether we are in doze state. 119 * 120 * Doze state is the same as "Always on Display" or "AOD". It is the state that the device can 121 * enter to conserve battery when the device is locked and inactive. 122 * 123 * Note that it is possible for the system to be transitioning into doze while this flow still 124 * returns `false`. In order to account for that, observers should also use the 125 * [linearDozeAmount] flow to check if it's greater than `0` 126 */ 127 val isDozing: StateFlow<Boolean> 128 129 /** 130 * Observable for whether the device is dreaming. 131 * 132 * Dozing/AOD is a specific type of dream, but it is also possible for other non-systemui dreams 133 * to be active, such as screensavers. 134 */ 135 val isDreaming: Flow<Boolean> 136 137 /** Observable for whether the device is dreaming with an overlay, see [DreamOverlayService] */ 138 val isDreamingWithOverlay: Flow<Boolean> 139 140 /** Observable for device dreaming state and the active dream is hosted in lockscreen */ 141 val isActiveDreamLockscreenHosted: StateFlow<Boolean> 142 143 /** 144 * Observable for the amount of doze we are currently in. 145 * 146 * While in doze state, this amount can change - driving a cycle of animations designed to avoid 147 * pixel burn-in, etc. 148 * 149 * Also note that the value here may be greater than `0` while [isDozing] is still `false`, this 150 * happens during an animation/transition into doze mode. An observer would be wise to account 151 * for both flows if needed. 152 */ 153 val linearDozeAmount: Flow<Float> 154 155 /** Doze state information, as it transitions */ 156 val dozeTransitionModel: Flow<DozeTransitionModel> 157 158 val lastDozeTapToWakePosition: StateFlow<Point?> 159 160 /** Observable for the [StatusBarState] */ 161 val statusBarState: Flow<StatusBarState> 162 163 /** Observable for device wake/sleep state */ 164 val wakefulness: StateFlow<WakefulnessModel> 165 166 /** Observable for device screen state */ 167 val screenModel: StateFlow<ScreenModel> 168 169 /** Observable for biometric unlock modes */ 170 val biometricUnlockState: Flow<BiometricUnlockModel> 171 172 /** Approximate location on the screen of the fingerprint sensor. */ 173 val fingerprintSensorLocation: Flow<Point?> 174 175 /** Approximate location on the screen of the face unlock sensor/front facing camera. */ 176 val faceSensorLocation: Flow<Point?> 177 178 /** Source of the most recent biometric unlock, such as fingerprint or face. */ 179 val biometricUnlockSource: Flow<BiometricUnlockSource?> 180 181 /** Whether quick settings or quick-quick settings is visible. */ 182 val isQuickSettingsVisible: Flow<Boolean> 183 184 /** Represents the current state of the KeyguardRootView visibility */ 185 val keyguardRootViewVisibility: Flow<KeyguardRootViewVisibilityState> 186 187 /** Receive an event for doze time tick */ 188 val dozeTimeTick: Flow<Long> 189 190 /** 191 * Returns `true` if the keyguard is showing; `false` otherwise. 192 * 193 * Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in 194 * the z-order (which is not really above the system UI window, but rather - the lock-screen 195 * becomes invisible to reveal the "occluding activity"). 196 */ 197 fun isKeyguardShowing(): Boolean 198 199 /** 200 * Whether lock screen bypass is enabled. When enabled, the lock screen will be automatically 201 * dismissed once the authentication challenge is completed. For example, completing a biometric 202 * authentication challenge via face unlock or fingerprint sensor can automatically bypass the 203 * lock screen. 204 */ 205 fun isBypassEnabled(): Boolean 206 207 /** Sets whether the bottom area UI should animate the transition out of doze state. */ 208 fun setAnimateDozingTransitions(animate: Boolean) 209 210 /** Sets the current amount of alpha that should be used for rendering the bottom area. */ 211 @Deprecated("Deprecated as part of b/278057014") fun setBottomAreaAlpha(alpha: Float) 212 213 /** Sets the current amount of alpha that should be used for rendering the keyguard. */ 214 fun setKeyguardAlpha(alpha: Float) 215 216 fun setKeyguardVisibility( 217 statusBarState: Int, 218 goingToFullShade: Boolean, 219 occlusionTransitionRunning: Boolean 220 ) 221 222 /** 223 * Sets the relative offset of the lock-screen clock from its natural position on the screen. 224 */ 225 fun setClockPosition(x: Int, y: Int) 226 227 /** 228 * Returns whether the keyguard bottom area should be constrained to the top of the lock icon 229 */ 230 fun isUdfpsSupported(): Boolean 231 232 /** Sets whether quick settings or quick-quick settings is visible. */ 233 fun setQuickSettingsVisible(isVisible: Boolean) 234 235 fun setLastDozeTapToWakePosition(position: Point) 236 237 fun setIsDozing(isDozing: Boolean) 238 239 fun setIsActiveDreamLockscreenHosted(isLockscreenHosted: Boolean) 240 241 fun dozeTimeTick() 242 } 243 244 /** Encapsulates application state for the keyguard. */ 245 @SysUISingleton 246 class KeyguardRepositoryImpl 247 @Inject 248 constructor( 249 statusBarStateController: StatusBarStateController, 250 wakefulnessLifecycle: WakefulnessLifecycle, 251 screenLifecycle: ScreenLifecycle, 252 biometricUnlockController: BiometricUnlockController, 253 private val keyguardStateController: KeyguardStateController, 254 private val keyguardBypassController: KeyguardBypassController, 255 private val keyguardUpdateMonitor: KeyguardUpdateMonitor, 256 private val dozeTransitionListener: DozeTransitionListener, 257 private val dozeParameters: DozeParameters, 258 private val authController: AuthController, 259 private val dreamOverlayCallbackController: DreamOverlayCallbackController, 260 @Main private val mainDispatcher: CoroutineDispatcher, 261 @Application private val scope: CoroutineScope, 262 private val systemClock: SystemClock, 263 ) : KeyguardRepository { 264 private val _animateBottomAreaDozingTransitions = MutableStateFlow(false) 265 override val animateBottomAreaDozingTransitions = 266 _animateBottomAreaDozingTransitions.asStateFlow() 267 268 private val _bottomAreaAlpha = MutableStateFlow(1f) 269 override val bottomAreaAlpha = _bottomAreaAlpha.asStateFlow() 270 271 private val _keyguardAlpha = MutableStateFlow(1f) 272 override val keyguardAlpha = _keyguardAlpha.asStateFlow() 273 274 private val _clockPosition = MutableStateFlow(Position(0, 0)) 275 override val clockPosition = _clockPosition.asStateFlow() 276 277 override val isKeyguardShowing: Flow<Boolean> = 278 conflatedCallbackFlow { 279 val callback = 280 object : KeyguardStateController.Callback { 281 override fun onKeyguardShowingChanged() { 282 trySendWithFailureLogging( 283 keyguardStateController.isShowing, 284 TAG, 285 "updated isKeyguardShowing" 286 ) 287 } 288 } 289 290 keyguardStateController.addCallback(callback) 291 // Adding the callback does not send an initial update. 292 trySendWithFailureLogging( 293 keyguardStateController.isShowing, 294 TAG, 295 "initial isKeyguardShowing" 296 ) 297 298 awaitClose { keyguardStateController.removeCallback(callback) } 299 } 300 .distinctUntilChanged() 301 302 override val isAodAvailable: Flow<Boolean> = 303 conflatedCallbackFlow { 304 val callback = 305 DozeParameters.Callback { 306 trySendWithFailureLogging( 307 dozeParameters.alwaysOn, 308 TAG, 309 "updated isAodAvailable" 310 ) 311 } 312 313 dozeParameters.addCallback(callback) 314 // Adding the callback does not send an initial update. 315 trySendWithFailureLogging(dozeParameters.alwaysOn, TAG, "initial isAodAvailable") 316 317 awaitClose { dozeParameters.removeCallback(callback) } 318 } 319 .distinctUntilChanged() 320 321 override val isKeyguardOccluded: Flow<Boolean> = 322 conflatedCallbackFlow { 323 val callback = 324 object : KeyguardStateController.Callback { 325 override fun onKeyguardShowingChanged() { 326 trySendWithFailureLogging( 327 keyguardStateController.isOccluded, 328 TAG, 329 "updated isKeyguardOccluded" 330 ) 331 } 332 } 333 334 keyguardStateController.addCallback(callback) 335 // Adding the callback does not send an initial update. 336 trySendWithFailureLogging( 337 keyguardStateController.isOccluded, 338 TAG, 339 "initial isKeyguardOccluded" 340 ) 341 342 awaitClose { keyguardStateController.removeCallback(callback) } 343 } 344 .distinctUntilChanged() 345 346 override val isKeyguardUnlocked: StateFlow<Boolean> = 347 conflatedCallbackFlow { 348 val callback = 349 object : KeyguardStateController.Callback { 350 override fun onUnlockedChanged() { 351 trySendWithFailureLogging( 352 keyguardStateController.isUnlocked, 353 TAG, 354 "updated isKeyguardUnlocked due to onUnlockedChanged" 355 ) 356 } 357 358 override fun onKeyguardShowingChanged() { 359 trySendWithFailureLogging( 360 keyguardStateController.isUnlocked, 361 TAG, 362 "updated isKeyguardUnlocked due to onKeyguardShowingChanged" 363 ) 364 } 365 } 366 367 keyguardStateController.addCallback(callback) 368 // Adding the callback does not send an initial update. 369 trySendWithFailureLogging( 370 keyguardStateController.isUnlocked, 371 TAG, 372 "initial isKeyguardUnlocked" 373 ) 374 375 awaitClose { keyguardStateController.removeCallback(callback) } 376 } 377 .distinctUntilChanged() 378 .stateIn( 379 scope, 380 SharingStarted.Eagerly, 381 initialValue = false, 382 ) 383 384 override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow { 385 val callback = 386 object : KeyguardStateController.Callback { 387 override fun onKeyguardGoingAwayChanged() { 388 trySendWithFailureLogging( 389 keyguardStateController.isKeyguardGoingAway, 390 TAG, 391 "updated isKeyguardGoingAway" 392 ) 393 } 394 } 395 396 keyguardStateController.addCallback(callback) 397 // Adding the callback does not send an initial update. 398 trySendWithFailureLogging( 399 keyguardStateController.isKeyguardGoingAway, 400 TAG, 401 "initial isKeyguardGoingAway" 402 ) 403 404 awaitClose { keyguardStateController.removeCallback(callback) } 405 } 406 407 private val _isDozing = MutableStateFlow(statusBarStateController.isDozing) 408 override val isDozing: StateFlow<Boolean> = _isDozing.asStateFlow() 409 410 override fun setIsDozing(isDozing: Boolean) { 411 _isDozing.value = isDozing 412 } 413 414 private val _dozeTimeTick = MutableStateFlow<Long>(0) 415 override val dozeTimeTick = _dozeTimeTick.asStateFlow() 416 417 override fun dozeTimeTick() { 418 _dozeTimeTick.value = systemClock.uptimeMillis() 419 } 420 421 private val _lastDozeTapToWakePosition = MutableStateFlow<Point?>(null) 422 override val lastDozeTapToWakePosition = _lastDozeTapToWakePosition.asStateFlow() 423 424 override fun setLastDozeTapToWakePosition(position: Point) { 425 _lastDozeTapToWakePosition.value = position 426 } 427 428 override val isDreamingWithOverlay: Flow<Boolean> = 429 conflatedCallbackFlow { 430 val callback = 431 object : DreamOverlayCallbackController.Callback { 432 override fun onStartDream() { 433 trySendWithFailureLogging(true, TAG, "updated isDreamingWithOverlay") 434 } 435 override fun onWakeUp() { 436 trySendWithFailureLogging(false, TAG, "updated isDreamingWithOverlay") 437 } 438 } 439 dreamOverlayCallbackController.addCallback(callback) 440 trySendWithFailureLogging( 441 dreamOverlayCallbackController.isDreaming, 442 TAG, 443 "initial isDreamingWithOverlay", 444 ) 445 446 awaitClose { dreamOverlayCallbackController.removeCallback(callback) } 447 } 448 .distinctUntilChanged() 449 450 override val isDreaming: Flow<Boolean> = 451 conflatedCallbackFlow { 452 val callback = 453 object : KeyguardUpdateMonitorCallback() { 454 override fun onDreamingStateChanged(isDreaming: Boolean) { 455 trySendWithFailureLogging(isDreaming, TAG, "updated isDreaming") 456 } 457 } 458 keyguardUpdateMonitor.registerCallback(callback) 459 trySendWithFailureLogging( 460 keyguardUpdateMonitor.isDreaming, 461 TAG, 462 "initial isDreaming", 463 ) 464 465 awaitClose { keyguardUpdateMonitor.removeCallback(callback) } 466 } 467 .flowOn(mainDispatcher) 468 .distinctUntilChanged() 469 470 override val linearDozeAmount: Flow<Float> = conflatedCallbackFlow { 471 val callback = 472 object : StatusBarStateController.StateListener { 473 override fun onDozeAmountChanged(linear: Float, eased: Float) { 474 trySendWithFailureLogging(linear, TAG, "updated dozeAmount") 475 } 476 } 477 478 statusBarStateController.addCallback(callback) 479 trySendWithFailureLogging(statusBarStateController.dozeAmount, TAG, "initial dozeAmount") 480 481 awaitClose { statusBarStateController.removeCallback(callback) } 482 } 483 484 override val dozeTransitionModel: Flow<DozeTransitionModel> = conflatedCallbackFlow { 485 val callback = 486 object : DozeTransitionCallback { 487 override fun onDozeTransition( 488 oldState: DozeMachine.State, 489 newState: DozeMachine.State 490 ) { 491 trySendWithFailureLogging( 492 DozeTransitionModel( 493 from = dozeMachineStateToModel(oldState), 494 to = dozeMachineStateToModel(newState), 495 ), 496 TAG, 497 "doze transition model" 498 ) 499 } 500 } 501 502 dozeTransitionListener.addCallback(callback) 503 trySendWithFailureLogging( 504 DozeTransitionModel( 505 from = dozeMachineStateToModel(dozeTransitionListener.oldState), 506 to = dozeMachineStateToModel(dozeTransitionListener.newState), 507 ), 508 TAG, 509 "initial doze transition model" 510 ) 511 512 awaitClose { dozeTransitionListener.removeCallback(callback) } 513 } 514 515 override fun isKeyguardShowing(): Boolean { 516 return keyguardStateController.isShowing 517 } 518 519 override fun isBypassEnabled(): Boolean { 520 return keyguardBypassController.bypassEnabled 521 } 522 523 override val statusBarState: Flow<StatusBarState> = conflatedCallbackFlow { 524 val callback = 525 object : StatusBarStateController.StateListener { 526 override fun onStateChanged(state: Int) { 527 trySendWithFailureLogging(statusBarStateIntToObject(state), TAG, "state") 528 } 529 } 530 531 statusBarStateController.addCallback(callback) 532 trySendWithFailureLogging( 533 statusBarStateIntToObject(statusBarStateController.getState()), 534 TAG, 535 "initial state" 536 ) 537 538 awaitClose { statusBarStateController.removeCallback(callback) } 539 } 540 541 override val biometricUnlockState: Flow<BiometricUnlockModel> = conflatedCallbackFlow { 542 fun dispatchUpdate() { 543 trySendWithFailureLogging( 544 biometricModeIntToObject(biometricUnlockController.mode), 545 TAG, 546 "biometric mode" 547 ) 548 } 549 550 val callback = 551 object : BiometricUnlockController.BiometricUnlockEventsListener { 552 override fun onModeChanged(@WakeAndUnlockMode mode: Int) { 553 dispatchUpdate() 554 } 555 556 override fun onResetMode() { 557 dispatchUpdate() 558 } 559 } 560 561 biometricUnlockController.addListener(callback) 562 dispatchUpdate() 563 564 awaitClose { biometricUnlockController.removeListener(callback) } 565 } 566 567 override val wakefulness: StateFlow<WakefulnessModel> = 568 conflatedCallbackFlow { 569 val observer = 570 object : WakefulnessLifecycle.Observer { 571 override fun onStartedWakingUp() { 572 dispatchNewState() 573 } 574 575 override fun onFinishedWakingUp() { 576 dispatchNewState() 577 } 578 579 override fun onPostFinishedWakingUp() { 580 dispatchNewState() 581 } 582 583 override fun onStartedGoingToSleep() { 584 dispatchNewState() 585 } 586 587 override fun onFinishedGoingToSleep() { 588 dispatchNewState() 589 } 590 591 private fun dispatchNewState() { 592 trySendWithFailureLogging( 593 WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle), 594 TAG, 595 "updated wakefulness state", 596 ) 597 } 598 } 599 600 wakefulnessLifecycle.addObserver(observer) 601 awaitClose { wakefulnessLifecycle.removeObserver(observer) } 602 } 603 .stateIn( 604 scope, 605 // Use Eagerly so that we're always listening and never miss an event. 606 SharingStarted.Eagerly, 607 initialValue = WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle), 608 ) 609 610 override val screenModel: StateFlow<ScreenModel> = 611 conflatedCallbackFlow { 612 val observer = 613 object : ScreenLifecycle.Observer { 614 override fun onScreenTurningOn() { 615 dispatchNewState() 616 } 617 override fun onScreenTurnedOn() { 618 dispatchNewState() 619 } 620 override fun onScreenTurningOff() { 621 dispatchNewState() 622 } 623 override fun onScreenTurnedOff() { 624 dispatchNewState() 625 } 626 627 private fun dispatchNewState() { 628 trySendWithFailureLogging( 629 ScreenModel.fromScreenLifecycle(screenLifecycle), 630 TAG, 631 "updated screen state", 632 ) 633 } 634 } 635 636 screenLifecycle.addObserver(observer) 637 awaitClose { screenLifecycle.removeObserver(observer) } 638 } 639 .stateIn( 640 scope, 641 // Use Eagerly so that we're always listening and never miss an event. 642 SharingStarted.Eagerly, 643 initialValue = ScreenModel.fromScreenLifecycle(screenLifecycle), 644 ) 645 646 override val fingerprintSensorLocation: Flow<Point?> = conflatedCallbackFlow { 647 fun sendFpLocation() { 648 trySendWithFailureLogging( 649 authController.fingerprintSensorLocation, 650 TAG, 651 "AuthController.Callback#onFingerprintLocationChanged" 652 ) 653 } 654 655 val callback = 656 object : AuthController.Callback { 657 override fun onFingerprintLocationChanged() { 658 sendFpLocation() 659 } 660 } 661 662 authController.addCallback(callback) 663 sendFpLocation() 664 665 awaitClose { authController.removeCallback(callback) } 666 } 667 668 override val faceSensorLocation: Flow<Point?> = conflatedCallbackFlow { 669 fun sendSensorLocation() { 670 trySendWithFailureLogging( 671 authController.faceSensorLocation, 672 TAG, 673 "AuthController.Callback#onFingerprintLocationChanged" 674 ) 675 } 676 677 val callback = 678 object : AuthController.Callback { 679 override fun onFaceSensorLocationChanged() { 680 sendSensorLocation() 681 } 682 } 683 684 authController.addCallback(callback) 685 sendSensorLocation() 686 687 awaitClose { authController.removeCallback(callback) } 688 } 689 690 override val biometricUnlockSource: Flow<BiometricUnlockSource?> = conflatedCallbackFlow { 691 val callback = 692 object : KeyguardUpdateMonitorCallback() { 693 override fun onBiometricAuthenticated( 694 userId: Int, 695 biometricSourceType: BiometricSourceType?, 696 isStrongBiometric: Boolean 697 ) { 698 trySendWithFailureLogging( 699 BiometricUnlockSource.fromBiometricSourceType(biometricSourceType), 700 TAG, 701 "onBiometricAuthenticated" 702 ) 703 } 704 } 705 706 keyguardUpdateMonitor.registerCallback(callback) 707 trySendWithFailureLogging(null, TAG, "initial value") 708 awaitClose { keyguardUpdateMonitor.removeCallback(callback) } 709 } 710 711 private val _isQuickSettingsVisible = MutableStateFlow(false) 712 override val isQuickSettingsVisible: Flow<Boolean> = _isQuickSettingsVisible.asStateFlow() 713 714 private val _isActiveDreamLockscreenHosted = MutableStateFlow(false) 715 override val isActiveDreamLockscreenHosted = _isActiveDreamLockscreenHosted.asStateFlow() 716 717 private val _keyguardRootViewVisibility = 718 MutableStateFlow( 719 KeyguardRootViewVisibilityState( 720 com.android.systemui.statusbar.StatusBarState.SHADE, 721 goingToFullShade = false, 722 occlusionTransitionRunning = false, 723 ) 724 ) 725 override val keyguardRootViewVisibility: Flow<KeyguardRootViewVisibilityState> = 726 _keyguardRootViewVisibility.asStateFlow() 727 728 override fun setAnimateDozingTransitions(animate: Boolean) { 729 _animateBottomAreaDozingTransitions.value = animate 730 } 731 732 override fun setBottomAreaAlpha(alpha: Float) { 733 _bottomAreaAlpha.value = alpha 734 } 735 736 override fun setKeyguardAlpha(alpha: Float) { 737 _keyguardAlpha.value = alpha 738 } 739 740 override fun setKeyguardVisibility( 741 statusBarState: Int, 742 goingToFullShade: Boolean, 743 occlusionTransitionRunning: Boolean 744 ) { 745 _keyguardRootViewVisibility.value = 746 KeyguardRootViewVisibilityState( 747 statusBarState, 748 goingToFullShade, 749 occlusionTransitionRunning 750 ) 751 } 752 753 override fun setClockPosition(x: Int, y: Int) { 754 _clockPosition.value = Position(x, y) 755 } 756 757 override fun isUdfpsSupported(): Boolean = keyguardUpdateMonitor.isUdfpsSupported 758 759 override fun setQuickSettingsVisible(isVisible: Boolean) { 760 _isQuickSettingsVisible.value = isVisible 761 } 762 763 override fun setIsActiveDreamLockscreenHosted(isLockscreenHosted: Boolean) { 764 _isActiveDreamLockscreenHosted.value = isLockscreenHosted 765 } 766 767 private fun statusBarStateIntToObject(value: Int): StatusBarState { 768 return when (value) { 769 0 -> StatusBarState.SHADE 770 1 -> StatusBarState.KEYGUARD 771 2 -> StatusBarState.SHADE_LOCKED 772 else -> throw IllegalArgumentException("Invalid StatusBarState value: $value") 773 } 774 } 775 776 private fun biometricModeIntToObject(@WakeAndUnlockMode value: Int): BiometricUnlockModel { 777 return when (value) { 778 0 -> BiometricUnlockModel.NONE 779 1 -> BiometricUnlockModel.WAKE_AND_UNLOCK 780 2 -> BiometricUnlockModel.WAKE_AND_UNLOCK_PULSING 781 3 -> BiometricUnlockModel.SHOW_BOUNCER 782 4 -> BiometricUnlockModel.ONLY_WAKE 783 5 -> BiometricUnlockModel.UNLOCK_COLLAPSING 784 6 -> BiometricUnlockModel.WAKE_AND_UNLOCK_FROM_DREAM 785 7 -> BiometricUnlockModel.DISMISS_BOUNCER 786 else -> throw IllegalArgumentException("Invalid BiometricUnlockModel value: $value") 787 } 788 } 789 790 private fun dozeMachineStateToModel(state: DozeMachine.State): DozeStateModel { 791 return when (state) { 792 DozeMachine.State.UNINITIALIZED -> DozeStateModel.UNINITIALIZED 793 DozeMachine.State.INITIALIZED -> DozeStateModel.INITIALIZED 794 DozeMachine.State.DOZE -> DozeStateModel.DOZE 795 DozeMachine.State.DOZE_SUSPEND_TRIGGERS -> DozeStateModel.DOZE_SUSPEND_TRIGGERS 796 DozeMachine.State.DOZE_AOD -> DozeStateModel.DOZE_AOD 797 DozeMachine.State.DOZE_REQUEST_PULSE -> DozeStateModel.DOZE_REQUEST_PULSE 798 DozeMachine.State.DOZE_PULSING -> DozeStateModel.DOZE_PULSING 799 DozeMachine.State.DOZE_PULSING_BRIGHT -> DozeStateModel.DOZE_PULSING_BRIGHT 800 DozeMachine.State.DOZE_PULSE_DONE -> DozeStateModel.DOZE_PULSE_DONE 801 DozeMachine.State.FINISH -> DozeStateModel.FINISH 802 DozeMachine.State.DOZE_AOD_PAUSED -> DozeStateModel.DOZE_AOD_PAUSED 803 DozeMachine.State.DOZE_AOD_PAUSING -> DozeStateModel.DOZE_AOD_PAUSING 804 DozeMachine.State.DOZE_AOD_DOCKED -> DozeStateModel.DOZE_AOD_DOCKED 805 else -> throw IllegalArgumentException("Invalid DozeMachine.State: state") 806 } 807 } 808 809 companion object { 810 private const val TAG = "KeyguardRepositoryImpl" 811 } 812 } 813