Merge "Revert^2 "Update face authenticating asset"" into 24D1-dev
diff --git a/packages/SettingsLib/Color/res/values/colors.xml b/packages/SettingsLib/Color/res/values/colors.xml
index b0b9b10..ef0dd1b 100644
--- a/packages/SettingsLib/Color/res/values/colors.xml
+++ b/packages/SettingsLib/Color/res/values/colors.xml
@@ -17,6 +17,7 @@
<resources>
<!-- Dynamic colors-->
+ <color name="settingslib_color_blue700">#0B57D0</color>
<color name="settingslib_color_blue600">#1a73e8</color>
<color name="settingslib_color_blue400">#669df6</color>
<color name="settingslib_color_blue300">#8ab4f8</color>
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
index 0447ef8..bc3488fc 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
@@ -56,6 +56,9 @@
".black",
android.R.color.white);
map.put(
+ ".blue200",
+ R.color.settingslib_color_blue700);
+ map.put(
".blue400",
R.color.settingslib_color_blue600);
map.put(
diff --git a/packages/SystemUI/res/raw/face_dialog_authenticating.json b/packages/SystemUI/res/raw/face_dialog_authenticating.json
new file mode 100644
index 0000000..4e25e6d
--- /dev/null
+++ b/packages/SystemUI/res/raw/face_dialog_authenticating.json
@@ -0,0 +1 @@
+{"v":"5.7.13","fr":60,"ip":0,"op":61,"w":64,"h":64,"nm":"face_scanning 3","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[32,32,0],"ix":2,"l":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":30,"s":[95,95,100]},{"t":60,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.244,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.244,0]],"v":[[-2.249,0.001],[0.001,2.251],[2.249,0.001],[0.001,-2.251]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.1,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.242,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.242,0]],"v":[[-2.249,0],[0.001,2.25],[2.249,0],[0.001,-2.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[39.4,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.814,3.523],[-2.814,3.523],[-2.814,1.363],[0.652,1.363],[0.652,-3.523],[2.814,-3.523]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.791,28.479],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.154,0.15],[0,0],[0.117,-0.095],[0,0],[0.228,-0.121],[0.358,-0.103],[0.922,0.261],[0.3,0.16],[0.24,0.185],[0.14,0.139],[0.178,0.261],[0.143,0.451],[0,0],[0,0.494],[0,0],[-0.214,-0.676],[-0.392,-0.572],[-0.323,-0.317],[-0.228,-0.177],[-0.333,-0.179],[-0.503,-0.145],[-0.662,0],[-0.653,0.184],[-0.437,0.233],[-0.336,0.258],[0,0],[0,0]],"o":[[0,0],[-0.107,0.106],[0,0],[-0.24,0.185],[-0.301,0.16],[-0.92,0.261],[-0.357,-0.103],[-0.228,-0.121],[-0.158,-0.122],[-0.225,-0.221],[-0.272,-0.393],[0,0],[-0.147,-0.466],[0,0],[0,0.716],[0.206,0.656],[0.256,0.372],[0.204,0.201],[0.336,0.258],[0.436,0.233],[0.655,0.184],[0.662,0],[0.503,-0.145],[0.332,-0.179],[0,0],[0,0],[0.165,-0.136]],"v":[[6.094,1.465],[4.579,-0.076],[4.242,0.225],[4.124,0.315],[3.43,0.771],[2.439,1.165],[-0.342,1.165],[-1.331,0.771],[-2.027,0.315],[-2.48,-0.075],[-3.087,-0.801],[-3.712,-2.075],[-3.712,-2.075],[-3.934,-3.523],[-6.094,-3.523],[-5.771,-1.424],[-4.868,0.424],[-3.995,1.465],[-3.344,2.027],[-2.35,2.676],[-0.934,3.243],[1.049,3.523],[3.031,3.243],[4.449,2.676],[5.441,2.027],[5.482,1.997],[5.615,1.895]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.201,40.411],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.398,0],[0,-13.4],[13.398,0],[0,13.4]],"o":[[13.398,0],[0,13.4],[-13.398,0],[0,-13.4]],"v":[[0,-24.3],[24.3,0],[0,24.3],[-24.3,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[14.904,0],[0,-14.904],[-14.904,0],[0,14.904]],"o":[[-14.904,0],[0,14.904],[14.904,0],[0,-14.904]],"v":[[0,-27],[-27,0],[0,27],[27,0]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
index f5d09ad..82e911c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
@@ -18,9 +18,7 @@
package com.android.systemui.biometrics.ui.binder
import android.graphics.Rect
-import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable
-import android.graphics.drawable.Drawable
import android.util.Log
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
@@ -36,7 +34,6 @@
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.util.kotlin.Utils.Companion.toQuad
-import com.android.systemui.util.kotlin.Utils.Companion.toQuint
import com.android.systemui.util.kotlin.Utils.Companion.toTriple
import com.android.systemui.util.kotlin.sample
import kotlinx.coroutines.flow.combine
@@ -68,29 +65,42 @@
iconOverlayView.layoutParams.width = iconViewLayoutParamSizeOverride.first
iconOverlayView.layoutParams.height = iconViewLayoutParamSizeOverride.second
- } else {
- iconView.layoutParams.width = viewModel.fingerprintIconWidth.first()
- iconView.layoutParams.height = viewModel.fingerprintIconWidth.first()
-
- iconOverlayView.layoutParams.width = viewModel.fingerprintIconWidth.first()
- iconOverlayView.layoutParams.height = viewModel.fingerprintIconWidth.first()
}
var faceIcon: AnimatedVectorDrawable? = null
- val faceIconCallback =
- object : Animatable2.AnimationCallback() {
- override fun onAnimationStart(drawable: Drawable) {
- viewModel.onAnimationStart()
- }
- override fun onAnimationEnd(drawable: Drawable) {
- viewModel.onAnimationEnd()
+ fun updateXmlIconAsset(
+ iconAsset: Int,
+ shouldAnimateIconView: Boolean,
+ activeAuthType: AuthType
+ ) {
+ faceIcon?.apply { stop() }
+ faceIcon = iconView.context.getDrawable(iconAsset) as AnimatedVectorDrawable
+ faceIcon?.apply {
+ iconView.setIconFailureListener(iconAsset, activeAuthType)
+ iconView.setImageDrawable(this)
+ if (shouldAnimateIconView) {
+ forceAnimationOnUI()
+ start()
}
}
+ }
+
+ fun updateJsonIconAsset(
+ iconAsset: Int,
+ shouldAnimateIconView: Boolean,
+ activeAuthType: AuthType
+ ) {
+ iconView.setIconFailureListener(iconAsset, activeAuthType)
+ iconView.setAnimation(iconAsset)
+ iconView.frame = 0
+
+ if (shouldAnimateIconView) {
+ iconView.playAnimation()
+ }
+ }
launch {
- var width = 0
- var height = 0
combine(promptViewModel.size, viewModel.activeAuthType, ::Pair).collect {
(_, activeAuthType) ->
// Every time after bp shows, [isIconViewLoaded] is set to false in
@@ -100,6 +110,17 @@
when (activeAuthType) {
AuthType.Fingerprint,
AuthType.Coex -> {
+ if (iconViewLayoutParamSizeOverride == null) {
+ iconView.layoutParams.width =
+ viewModel.fingerprintIconWidth.first()
+ iconView.layoutParams.height =
+ viewModel.fingerprintIconHeight.first()
+
+ iconOverlayView.layoutParams.width =
+ viewModel.fingerprintIconWidth.first()
+ iconOverlayView.layoutParams.height =
+ viewModel.fingerprintIconHeight.first()
+ }
/**
* View is only set visible in BiometricViewSizeBinder once
* PromptSize is determined that accounts for iconView size, to
@@ -114,8 +135,10 @@
}
}
AuthType.Face -> {
- width = viewModel.faceIconWidth
- height = viewModel.faceIconHeight
+ if (iconViewLayoutParamSizeOverride == null) {
+ iconView.layoutParams.width = viewModel.faceIconWidth
+ iconView.layoutParams.height = viewModel.faceIconHeight
+ }
/**
* Set to true by default since face icon is a drawable, which
* doesn't have a LottieOnCompositionLoadedListener equivalent.
@@ -126,13 +149,6 @@
promptViewModel.setIsIconViewLoaded(true)
}
}
-
- if (width != 0 && height != 0) {
- iconView.layoutParams.width = width
- iconView.layoutParams.height = height
- iconOverlayView.layoutParams.width = width
- iconOverlayView.layoutParams.height = height
- }
}
}
@@ -160,52 +176,55 @@
combine(
viewModel.activeAuthType,
viewModel.shouldAnimateIconView,
- viewModel.shouldRepeatAnimation,
viewModel.showingError,
- ::toQuad
+ ::Triple
),
- ::toQuint
+ ::toQuad
)
- .collect {
- (
- iconAsset,
- activeAuthType,
- shouldAnimateIconView,
- shouldRepeatAnimation,
- showingError) ->
+ .collect { (iconAsset, activeAuthType, shouldAnimateIconView, showingError)
+ ->
if (iconAsset != -1) {
when (activeAuthType) {
AuthType.Fingerprint,
AuthType.Coex -> {
- iconView.setIconFailureListener(iconAsset, activeAuthType)
- iconView.setAnimation(iconAsset)
- iconView.frame = 0
-
- if (shouldAnimateIconView) {
- iconView.playAnimation()
+ // TODO(b/318569643): Until assets unified to one type, this
+ // check
+ // is needed in face-auth-error-triggered implicit ->
+ // explicit
+ // coex auth transition, in case iconAsset updates to
+ // face_dialog_dark_to_error (XML) after activeAuthType
+ // updates
+ // from AuthType.Face (which expects XML)
+ // to AuthType.Coex (which expects JSON)
+ if (iconAsset == R.drawable.face_dialog_dark_to_error) {
+ updateXmlIconAsset(
+ iconAsset,
+ shouldAnimateIconView,
+ activeAuthType
+ )
+ } else {
+ updateJsonIconAsset(
+ iconAsset,
+ shouldAnimateIconView,
+ activeAuthType
+ )
}
}
AuthType.Face -> {
- faceIcon?.apply {
- unregisterAnimationCallback(faceIconCallback)
- stop()
- }
- faceIcon =
- iconView.context.getDrawable(iconAsset)
- as AnimatedVectorDrawable
- faceIcon?.apply {
- iconView.setIconFailureListener(
+ // TODO(b/318569643): Consolidate logic once all face auth
+ // assets are migrated from drawable to json
+ if (iconAsset == R.raw.face_dialog_authenticating) {
+ updateJsonIconAsset(
iconAsset,
+ shouldAnimateIconView,
activeAuthType
)
- iconView.setImageDrawable(this)
- if (shouldAnimateIconView) {
- forceAnimationOnUI()
- if (shouldRepeatAnimation) {
- registerAnimationCallback(faceIconCallback)
- }
- start()
- }
+ } else {
+ updateXmlIconAsset(
+ iconAsset,
+ shouldAnimateIconView,
+ activeAuthType
+ )
}
}
}
@@ -309,11 +328,10 @@
// Face assets
R.drawable.face_dialog_wink_from_dark to "face_dialog_wink_from_dark",
R.drawable.face_dialog_dark_to_checkmark to "face_dialog_dark_to_checkmark",
- R.drawable.face_dialog_pulse_light_to_dark to "face_dialog_pulse_light_to_dark",
- R.drawable.face_dialog_pulse_dark_to_light to "face_dialog_pulse_dark_to_light",
R.drawable.face_dialog_dark_to_error to "face_dialog_dark_to_error",
R.drawable.face_dialog_error_to_idle to "face_dialog_error_to_idle",
R.drawable.face_dialog_idle_static to "face_dialog_idle_static",
+ R.raw.face_dialog_authenticating to "face_dialog_authenticating",
// Co-ex assets
R.raw.fingerprint_dialogue_unlocked_to_checkmark_success_lottie to
"fingerprint_dialogue_unlocked_to_checkmark_success_lottie",
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
index 257eb4a..c59fdcf 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
@@ -31,12 +31,10 @@
import com.android.systemui.util.kotlin.combine
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
/**
* Models UI of [BiometricPromptLayout.iconView] and [BiometricPromptLayout.biometric_icon_overlay]
@@ -57,11 +55,8 @@
}
/**
- * Indicates what auth type the UI currently displays.
- * Fingerprint-only auth -> Fingerprint
- * Face-only auth -> Face
- * Co-ex auth, implicit flow -> Face
- * Co-ex auth, explicit flow -> Coex
+ * Indicates what auth type the UI currently displays. Fingerprint-only auth -> Fingerprint
+ * Face-only auth -> Face Co-ex auth, implicit flow -> Face Co-ex auth, explicit flow -> Coex
*/
val activeAuthType: Flow<AuthType> =
combine(
@@ -129,35 +124,6 @@
_previousIconOverlayWasError.value = previousIconOverlayWasError
}
- /** Called when iconView begins animating. */
- fun onAnimationStart() {
- _animationEnded.value = false
- }
-
- /** Called when iconView ends animating. */
- fun onAnimationEnd() {
- _animationEnded.value = true
- }
-
- private val _animationEnded: MutableStateFlow<Boolean> = MutableStateFlow(false)
-
- /**
- * Whether a face iconView should pulse (i.e. while isAuthenticating and previous animation
- * ended).
- */
- val shouldPulseAnimation: Flow<Boolean> =
- combine(_animationEnded, promptViewModel.isAuthenticating) {
- animationEnded,
- isAuthenticating ->
- animationEnded && isAuthenticating
- }
- .distinctUntilChanged()
-
- private val _lastPulseLightToDark: MutableStateFlow<Boolean> = MutableStateFlow(false)
-
- /** Tracks whether a face iconView last pulsed light to dark (vs. dark to light) */
- val lastPulseLightToDark: Flow<Boolean> = _lastPulseLightToDark.asStateFlow()
-
/** Layout params for fingerprint iconView */
val fingerprintIconWidth: Flow<Int> = promptViewModel.fingerprintSensorDiameter
val fingerprintIconHeight: Flow<Int> = promptViewModel.fingerprintSensorDiameter
@@ -199,35 +165,22 @@
}
}
AuthType.Face ->
- shouldPulseAnimation.flatMapLatest { shouldPulseAnimation: Boolean ->
- if (shouldPulseAnimation) {
- val iconAsset =
- if (_lastPulseLightToDark.value) {
- R.drawable.face_dialog_pulse_dark_to_light
- } else {
- R.drawable.face_dialog_pulse_light_to_dark
- }
- _lastPulseLightToDark.value = !_lastPulseLightToDark.value
- flowOf(iconAsset)
- } else {
- combine(
- promptViewModel.isAuthenticated.distinctUntilChanged(),
- promptViewModel.isAuthenticating.distinctUntilChanged(),
- promptViewModel.isPendingConfirmation.distinctUntilChanged(),
- promptViewModel.showingError.distinctUntilChanged()
- ) {
- authState: PromptAuthState,
- isAuthenticating: Boolean,
- isPendingConfirmation: Boolean,
- showingError: Boolean ->
- getFaceIconViewAsset(
- authState,
- isAuthenticating,
- isPendingConfirmation,
- showingError
- )
- }
- }
+ combine(
+ promptViewModel.isAuthenticated.distinctUntilChanged(),
+ promptViewModel.isAuthenticating.distinctUntilChanged(),
+ promptViewModel.isPendingConfirmation.distinctUntilChanged(),
+ promptViewModel.showingError.distinctUntilChanged()
+ ) {
+ authState: PromptAuthState,
+ isAuthenticating: Boolean,
+ isPendingConfirmation: Boolean,
+ showingError: Boolean ->
+ getFaceIconViewAsset(
+ authState,
+ isAuthenticating,
+ isPendingConfirmation,
+ showingError
+ )
}
AuthType.Coex ->
combine(
@@ -331,8 +284,7 @@
} else if (authState.isAuthenticated) {
R.drawable.face_dialog_dark_to_checkmark
} else if (isAuthenticating) {
- _lastPulseLightToDark.value = false
- R.drawable.face_dialog_pulse_dark_to_light
+ R.raw.face_dialog_authenticating
} else if (showingError) {
R.drawable.face_dialog_dark_to_error
} else if (_previousIconWasError.value) {
@@ -707,16 +659,6 @@
}
}
- /** Whether the current BiometricPromptLayout.iconView asset animation should be repeated. */
- val shouldRepeatAnimation: Flow<Boolean> =
- activeAuthType.flatMapLatest { activeAuthType: AuthType ->
- when (activeAuthType) {
- AuthType.Fingerprint,
- AuthType.Coex -> flowOf(false)
- AuthType.Face -> promptViewModel.isAuthenticating.map { it }
- }
- }
-
/** Called on configuration changes */
fun onConfigurationChanged(newConfig: Configuration) {
displayStateInteractor.onConfigurationChanged(newConfig)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 5f975ec..0d89de4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -355,25 +355,11 @@
}
if (testCase.isFaceOnly) {
- val shouldRepeatAnimation by collectLastValue(iconViewModel.shouldRepeatAnimation)
- val shouldPulseAnimation by collectLastValue(iconViewModel.shouldPulseAnimation)
- val lastPulseLightToDark by collectLastValue(iconViewModel.lastPulseLightToDark)
-
- val expectedIconAsset =
- if (shouldPulseAnimation!!) {
- if (lastPulseLightToDark!!) {
- R.drawable.face_dialog_pulse_dark_to_light
- } else {
- R.drawable.face_dialog_pulse_light_to_dark
- }
- } else {
- R.drawable.face_dialog_pulse_dark_to_light
- }
+ val expectedIconAsset = R.raw.face_dialog_authenticating
assertThat(iconAsset).isEqualTo(expectedIconAsset)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_authenticating)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldRepeatAnimation).isEqualTo(true)
}
if (testCase.isCoex) {
@@ -395,26 +381,11 @@
}
} else {
// implicit flow
- val shouldRepeatAnimation by
- collectLastValue(iconViewModel.shouldRepeatAnimation)
- val shouldPulseAnimation by collectLastValue(iconViewModel.shouldPulseAnimation)
- val lastPulseLightToDark by collectLastValue(iconViewModel.lastPulseLightToDark)
-
- val expectedIconAsset =
- if (shouldPulseAnimation!!) {
- if (lastPulseLightToDark!!) {
- R.drawable.face_dialog_pulse_dark_to_light
- } else {
- R.drawable.face_dialog_pulse_light_to_dark
- }
- } else {
- R.drawable.face_dialog_pulse_dark_to_light
- }
+ val expectedIconAsset = R.raw.face_dialog_authenticating
assertThat(iconAsset).isEqualTo(expectedIconAsset)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_authenticating)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldRepeatAnimation).isEqualTo(true)
}
}
}
@@ -504,14 +475,9 @@
}
if (testCase.isFaceOnly) {
- val shouldRepeatAnimation by collectLastValue(iconViewModel.shouldRepeatAnimation)
- val shouldPulseAnimation by collectLastValue(iconViewModel.shouldPulseAnimation)
-
- assertThat(shouldPulseAnimation!!).isEqualTo(false)
assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_dark_to_error)
assertThat(iconContentDescriptionId).isEqualTo(R.string.keyguard_face_failed)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldRepeatAnimation).isEqualTo(false)
// Clear error, go to idle
errorJob.join()
@@ -520,7 +486,6 @@
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_idle)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldRepeatAnimation).isEqualTo(false)
}
if (testCase.isCoex) {
@@ -603,15 +568,10 @@
// If co-ex, using implicit flow (explicit flow always requires confirmation)
if (testCase.isFaceOnly || testCase.isCoex) {
- val shouldRepeatAnimation by collectLastValue(iconViewModel.shouldRepeatAnimation)
- val shouldPulseAnimation by collectLastValue(iconViewModel.shouldPulseAnimation)
-
- assertThat(shouldPulseAnimation!!).isEqualTo(false)
assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_dark_to_checkmark)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_authenticated)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldRepeatAnimation).isEqualTo(false)
}
}
}
@@ -633,15 +593,10 @@
)
if (testCase.isFaceOnly) {
- val shouldRepeatAnimation by collectLastValue(iconViewModel.shouldRepeatAnimation)
- val shouldPulseAnimation by collectLastValue(iconViewModel.shouldPulseAnimation)
-
- assertThat(shouldPulseAnimation!!).isEqualTo(false)
assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_wink_from_dark)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_authenticated)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldRepeatAnimation).isEqualTo(false)
}
// explicit flow because confirmation requested
@@ -683,15 +638,10 @@
viewModel.confirmAuthenticated()
if (testCase.isFaceOnly) {
- val shouldRepeatAnimation by collectLastValue(iconViewModel.shouldRepeatAnimation)
- val shouldPulseAnimation by collectLastValue(iconViewModel.shouldPulseAnimation)
-
- assertThat(shouldPulseAnimation!!).isEqualTo(false)
assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_dark_to_checkmark)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_confirmed)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldRepeatAnimation).isEqualTo(false)
}
// explicit flow because confirmation requested