Wait to set propertiesInitialized to true

Until all fp props have sent some information.

Flag: NONE bug fix
Fixes: 336916379
Test: manually reboot device and observe lock
icon location on a UDFPS device

Change-Id: I18c15685bb0b9ac9c2c1e222d730d9bb27114de1
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
index 40d38dd..ba51d02 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
@@ -41,7 +41,10 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
 
@@ -52,7 +55,7 @@
  */
 interface FingerprintPropertyRepository {
     /** Whether the fingerprint properties have been initialized yet. */
-    val propertiesInitialized: StateFlow<Boolean>
+    val propertiesInitialized: Flow<Boolean>
 
     /** The id of fingerprint sensor. */
     val sensorId: Flow<Int>
@@ -110,15 +113,6 @@
                 initialValue = UNINITIALIZED_PROPS,
             )
 
-    override val propertiesInitialized: StateFlow<Boolean> =
-        props
-            .map { it != UNINITIALIZED_PROPS }
-            .stateIn(
-                applicationScope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = props.value != UNINITIALIZED_PROPS,
-            )
-
     override val sensorId: Flow<Int> = props.map { it.sensorId }
 
     override val strength: Flow<SensorStrength> = props.map { it.sensorStrength.toSensorStrength() }
@@ -139,6 +133,22 @@
             }
         }
 
+    override val propertiesInitialized: Flow<Boolean> =
+        combine(
+                props
+                    .map { it != UNINITIALIZED_PROPS }
+                    .onStart { emit(props.value != UNINITIALIZED_PROPS) },
+                sensorId.map {}.onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+                sensorLocations
+                    .map {}
+                    .onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+                sensorType.map {}.onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+                strength.map {}.onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+            ) { initialized, _, _, _, _ ->
+                initialized
+            }
+            .distinctUntilChanged()
+
     companion object {
         private const val TAG = "FingerprintPropertyRepositoryImpl"
         private val UNINITIALIZED_PROPS =
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
index 3112b67..a74b0b0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
@@ -46,13 +46,13 @@
     displayStateInteractor: DisplayStateInteractor,
     udfpsOverlayInteractor: UdfpsOverlayInteractor,
 ) {
-    val propertiesInitialized: StateFlow<Boolean> = repository.propertiesInitialized
+    val propertiesInitialized: Flow<Boolean> = repository.propertiesInitialized
     val isUdfps: StateFlow<Boolean> =
         repository.sensorType
             .map { it.isUdfps() }
             .stateIn(
                 scope = applicationScope,
-                started = SharingStarted.WhileSubscribed(),
+                started = SharingStarted.Eagerly,
                 initialValue = repository.sensorType.value.isUdfps(),
             )
 
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
index 80b52ed..6c6d730 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.deviceentry.domain.interactor
 
 import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
+import com.android.systemui.biometrics.shared.model.SensorLocation
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
@@ -58,4 +59,17 @@
                 flowOf(false)
             }
         }
+
+    /**
+     * Location of the under-display fingerprint sensor on the display. Null if the device does not
+     * support UDFPS.
+     */
+    val udfpsLocation: Flow<SensorLocation?> =
+        isUdfpsSupported.flatMapLatest {
+            if (it) {
+                fingerprintPropertyInteractor.sensorLocation
+            } else {
+                flowOf(null)
+            }
+        }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
index 857096e..7cee258 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
@@ -78,7 +78,7 @@
     private val refreshEvents: Flow<Unit> =
         merge(
             configurationInteractor.onAnyConfigurationChange,
-            fingerprintPropertyInteractor.propertiesInitialized.filter { it }.map { Unit },
+            fingerprintPropertyInteractor.propertiesInitialized.filter { it }.map {},
         )
 
     init {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
index 29041d1..0b8376a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
@@ -21,6 +21,7 @@
 import android.graphics.Point
 import android.graphics.Rect
 import android.util.DisplayMetrics
+import android.util.Log
 import android.view.View
 import android.view.WindowManager
 import androidx.annotation.VisibleForTesting
@@ -116,6 +117,10 @@
     override fun applyConstraints(constraintSet: ConstraintSet) {
         val isUdfpsSupported =
             if (DeviceEntryUdfpsRefactor.isEnabled) {
+                Log.d(
+                    "DefaultDeviceEntrySection",
+                    "isUdfpsSupported=${deviceEntryIconViewModel.get().isUdfpsSupported.value}"
+                )
                 deviceEntryIconViewModel.get().isUdfpsSupported.value
             } else {
                 authController.isUdfpsSupported
@@ -138,8 +143,24 @@
         val iconRadiusPx = (defaultDensity * 36).toInt()
 
         if (isUdfpsSupported) {
-            authController.udfpsLocation?.let { udfpsLocation ->
-                centerIcon(udfpsLocation, authController.udfpsRadius, constraintSet)
+            if (DeviceEntryUdfpsRefactor.isEnabled) {
+                deviceEntryIconViewModel.get().udfpsLocation.value?.let { udfpsLocation ->
+                    Log.d(
+                        "DeviceEntrySection",
+                        "udfpsLocation=$udfpsLocation" +
+                            " unusedAuthController=${authController.udfpsLocation}"
+                    )
+                    centerIcon(
+                        Point(udfpsLocation.centerX.toInt(), udfpsLocation.centerY.toInt()),
+                        udfpsLocation.radius,
+                        constraintSet
+                    )
+                }
+            } else {
+                authController.udfpsLocation?.let { udfpsLocation ->
+                    Log.d("DeviceEntrySection", "udfpsLocation=$udfpsLocation")
+                    centerIcon(udfpsLocation, authController.udfpsRadius, constraintSet)
+                }
             }
         } else {
             centerIcon(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index ae83c9e..8d90933 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -20,6 +20,7 @@
 import android.animation.IntEvaluator
 import com.android.keyguard.KeyguardViewController
 import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
+import com.android.systemui.biometrics.shared.model.SensorLocation
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
@@ -73,6 +74,12 @@
     @Application private val scope: CoroutineScope,
 ) {
     val isUdfpsSupported: StateFlow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsSupported
+    val udfpsLocation: StateFlow<SensorLocation?> =
+        deviceEntryUdfpsInteractor.udfpsLocation.stateIn(
+            scope = scope,
+            started = SharingStarted.Eagerly,
+            initialValue = null,
+        )
     private val intEvaluator = IntEvaluator()
     private val floatEvaluator = FloatEvaluator()
     private val showingAlternateBouncer: Flow<Boolean> =