summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Shawn Lin <shawnlin@google.com> 2024-02-27 05:59:24 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-02-27 05:59:24 +0000
commitb9d0add75949a47c8d66842999a9cc975aa3b96a (patch)
tree62f91bdf5841918fd88c7324314ace1a38d97673
parent9b2ce0e931c896649fab3cef5dbf6d2a08ce0bfb (diff)
parent7552f13b50482a77a2834050e6e2c1cfc05d6a63 (diff)
Merge "Retrying face auth when the camera changed while face auth is running" into main
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt42
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt8
6 files changed, 114 insertions, 7 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt
index ae1539ebaf89..59b59bf1e437 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt
@@ -50,6 +50,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
@@ -64,13 +65,16 @@ interface FacePropertyRepository {
/** The current face sensor location in current device rotation */
val sensorLocation: StateFlow<Point?>
+
+ /** The info of current available camera. */
+ val cameraInfo: StateFlow<CameraInfo?>
}
/** Describes a biometric sensor */
data class FaceSensorInfo(val id: Int, val strength: SensorStrength)
/** Data class for camera info */
-private data class CameraInfo(
+data class CameraInfo(
/** The logical id of the camera */
val cameraId: String,
/** The physical id of the camera */
@@ -124,7 +128,7 @@ constructor(
private val cameraInfoList: List<CameraInfo> = loadCameraInfoList()
private var currentPhysicalCameraId: String? = null
- private val defaultSensorLocation: StateFlow<Point?> =
+ override val cameraInfo: StateFlow<CameraInfo?> =
ConflatedCallbackFlow.conflatedCallbackFlow {
val callback =
object : CameraManager.AvailabilityCallback() {
@@ -142,7 +146,7 @@ constructor(
physicalCameraId == it.cameraPhysicalId
}
trySendWithFailureLogging(
- cameraInfo?.cameraLocation,
+ cameraInfo,
TAG,
"Update face sensor location to $cameraInfo."
)
@@ -168,7 +172,7 @@ constructor(
}
currentPhysicalCameraId = cameraInfo?.cameraPhysicalId
trySendWithFailureLogging(
- cameraInfo?.cameraLocation,
+ cameraInfo,
TAG,
"Update face sensor location to $cameraInfo."
)
@@ -181,8 +185,16 @@ constructor(
.stateIn(
applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue =
- if (cameraInfoList.isNotEmpty()) cameraInfoList[0].cameraLocation else null
+ initialValue = if (cameraInfoList.isNotEmpty()) cameraInfoList[0] else null
+ )
+
+ private val defaultSensorLocation: StateFlow<Point?> =
+ cameraInfo
+ .map { it?.cameraLocation }
+ .stateIn(
+ applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = null
)
override val sensorLocation: StateFlow<Point?> =
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
index cf91e147d1b3..0c9fbc27cc5d 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
@@ -189,6 +189,18 @@ constructor(
}
}
.launchIn(applicationScope)
+
+ facePropertyRepository.cameraInfo
+ .onEach {
+ if (it != null && isRunning()) {
+ repository.cancel()
+ runFaceAuth(
+ FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED,
+ fallbackToDetect = true
+ )
+ }
+ }
+ .launchIn(applicationScope)
}
private suspend fun resetLockedOutState(currentUserId: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt
index ee220d5fb713..08a6166fe557 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt
@@ -31,6 +31,7 @@ import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ALTERNATE
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ASSISTANT_VISIBILITY_CHANGED
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.AUTH_REQUEST_DURING_CANCELLATION
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.BIOMETRIC_ENABLED
+import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.CAMERA_AVAILABLE_CHANGED
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.CAMERA_LAUNCHED
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DEVICE_WOKEN_UP_ON_REACH_GESTURE
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DISPLAY_OFF
@@ -130,6 +131,7 @@ private object InternalFaceAuthReasons {
"Face auth stopped because non strong biometric allowed changed"
const val POSTURE_CHANGED = "Face auth started/stopped due to device posture changed."
const val DISPLAY_OFF = "Face auth stopped due to display state OFF."
+ const val CAMERA_AVAILABLE_CHANGED = "Face auth started due to the available camera changed"
}
/**
@@ -221,7 +223,9 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
@UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, NON_STRONG_BIOMETRIC_ALLOWED_CHANGED),
@UiEvent(doc = ACCESSIBILITY_ACTION) FACE_AUTH_ACCESSIBILITY_ACTION(1454, ACCESSIBILITY_ACTION),
- @UiEvent(doc = DISPLAY_OFF) FACE_AUTH_DISPLAY_OFF(1461, DISPLAY_OFF);
+ @UiEvent(doc = DISPLAY_OFF) FACE_AUTH_DISPLAY_OFF(1461, DISPLAY_OFF),
+ @UiEvent(doc = CAMERA_AVAILABLE_CHANGED)
+ FACE_AUTH_CAMERA_AVAILABLE_CHANGED(1623, CAMERA_AVAILABLE_CHANGED);
override fun getId(): Int = this.id
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
index 9f24d5dfea79..f5e96c93271a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
@@ -237,6 +237,35 @@ class FacePropertyRepositoryImplTest : SysuiTestCase() {
}
}
+ @Test
+ fun providesTheCameraInfoOnCameraAvailableChange() {
+ testScope.runTest {
+ runCurrent()
+ collectLastValue(underTest.cameraInfo)
+
+ verify(faceManager).addAuthenticatorsRegisteredCallback(callback.capture())
+ callback.value.onAllAuthenticatorsRegistered(
+ listOf(createSensorProperties(1, SensorProperties.STRENGTH_STRONG))
+ )
+ runCurrent()
+ verify(cameraManager)
+ .registerAvailabilityCallback(any(Executor::class.java), cameraCallback.capture())
+
+ cameraCallback.value.onPhysicalCameraAvailable("0", PHYSICAL_CAMERA_ID_OUTER_FRONT)
+ runCurrent()
+
+ val cameraInfo by collectLastValue(underTest.cameraInfo)
+ assertThat(cameraInfo)
+ .isEqualTo(
+ CameraInfo(
+ "0",
+ PHYSICAL_CAMERA_ID_OUTER_FRONT,
+ Point(OUTER_FRONT_SENSOR_LOCATION[0], OUTER_FRONT_SENSOR_LOCATION[1])
+ )
+ )
+ }
+ }
+
private fun createSensorProperties(id: Int, strength: Int) =
FaceSensorPropertiesInternal(id, strength, 0, emptyList(), 1, false, false, false)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
index e30dd35d74c1..e1e9fcb2d059 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
@@ -25,6 +25,7 @@ import androidx.test.filters.SmallTest
import com.android.keyguard.keyguardUpdateMonitor
import com.android.keyguard.trustManager
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.CameraInfo
import com.android.systemui.biometrics.data.repository.FaceSensorInfo
import com.android.systemui.biometrics.data.repository.facePropertyRepository
import com.android.systemui.biometrics.shared.model.LockoutMode
@@ -490,6 +491,47 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
verify(trustManager).clearAllBiometricRecognized(eq(BiometricSourceType.FACE), anyInt())
}
+ @Test
+ fun faceAuthIsRequestedWhenAuthIsRunningWhileCameraInfoChanged() =
+ testScope.runTest {
+ facePropertyRepository.setCameraIno(null)
+ underTest.start()
+
+ faceAuthRepository.requestAuthenticate(
+ FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED,
+ true
+ )
+ facePropertyRepository.setCameraIno(CameraInfo("0", "1", null))
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value)
+ .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED, true))
+ }
+
+ @Test
+ fun faceAuthIsNotRequestedWhenNoAuthRunningWhileCameraInfoChanged() =
+ testScope.runTest {
+ facePropertyRepository.setCameraIno(null)
+ underTest.start()
+
+ facePropertyRepository.setCameraIno(CameraInfo("0", "1", null))
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
+ }
+
+ @Test
+ fun faceAuthIsNotRequestedWhenAuthIsRunningWhileCameraInfoIsNull() =
+ testScope.runTest {
+ facePropertyRepository.setCameraIno(null)
+ underTest.start()
+
+ facePropertyRepository.setCameraIno(null)
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
+ }
+
companion object {
private const val primaryUserId = 1
private val primaryUser = UserInfo(primaryUserId, "test user", UserInfo.FLAG_PRIMARY)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt
index 77f501f550d7..68ef55573dc8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt
@@ -33,6 +33,10 @@ class FakeFacePropertyRepository : FacePropertyRepository {
override val sensorLocation: StateFlow<Point?>
get() = faceSensorLocation
+ private val currentCameraInfo = MutableStateFlow<CameraInfo?>(null)
+ override val cameraInfo: StateFlow<CameraInfo?>
+ get() = currentCameraInfo
+
fun setLockoutMode(userId: Int, mode: LockoutMode) {
lockoutModesForUser[userId] = mode
}
@@ -47,4 +51,8 @@ class FakeFacePropertyRepository : FacePropertyRepository {
fun setSensorLocation(value: Point?) {
faceSensorLocation.value = value
}
+
+ fun setCameraIno(value: CameraInfo?) {
+ currentCameraInfo.value = value
+ }
}