Merge "UDFPS Enrollment refactor (3/N)" into main

This commit is contained in:
Joshua Mccloskey
2024-04-02 18:20:03 +00:00
committed by Android (Google) Code Review
5 changed files with 90 additions and 78 deletions

View File

@@ -17,6 +17,7 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.fragment package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.fragment
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.TextView import android.widget.TextView
@@ -117,7 +118,9 @@ class UdfpsEnrollFragment() : Fragment(R.layout.fingerprint_v2_udfps_enroll_enro
} }
} }
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.lifecycleScope.launch {
viewModel.udfpsEvent.collect { udfpsEnrollView.onUdfpsEvent(it) } viewModel.udfpsEvent.collect {
Log.d(TAG, "EnrollEvent $it")
udfpsEnrollView.onUdfpsEvent(it) }
} }
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.lifecycleScope.launch {

View File

@@ -151,17 +151,27 @@ class UdfpsViewModel() : ViewModel() {
private val enrollEvents: List<List<UdfpsEnrollEvent>> = private val enrollEvents: List<List<UdfpsEnrollEvent>> =
listOf( listOf(
listOf(OverlayShown), listOf(OverlayShown),
CreateProgress(10, 10), listOf(UdfpsHelp(1,"hi")),
CreateProgress(9, 10), listOf(UdfpsHelp(1,"hi")),
CreateProgress(8, 10), CreateProgress(15, 16),
CreateProgress(7, 10), listOf(UdfpsHelp(1,"hi")),
CreateProgress(6, 10), CreateProgress(14, 16),
CreateProgress(5, 10), listOf(PointerDown, UdfpsHelp(1,"hi"), PointerUp),
CreateProgress(4, 10), listOf(PointerDown, UdfpsHelp(1,"hi"), PointerUp),
CreateProgress(3, 10), CreateProgress(13, 16),
CreateProgress(2, 10), CreateProgress(12, 16),
CreateProgress(1, 10), CreateProgress(11, 16),
CreateProgress(0, 10), CreateProgress(10, 16),
CreateProgress(9, 16),
CreateProgress(8, 16),
CreateProgress(7, 16),
CreateProgress(6, 16),
CreateProgress(5, 16),
CreateProgress(4, 16),
CreateProgress(3, 16),
CreateProgress(2, 16),
CreateProgress(1, 16),
CreateProgress(0, 16),
) )
/** This will be removed */ /** This will be removed */

View File

@@ -169,15 +169,26 @@ class UdfpsEnrollIconV2 internal constructor(context: Context, attrs: AttributeS
invalidateSelf() invalidateSelf()
} }
/** Stop drawing the fingerprint icon. */
fun stopDrawing() {
alpha = 0
}
/** Resume drawing the fingerprint icon */
fun startDrawing() {
alpha = 255
}
override fun draw(canvas: Canvas) { override fun draw(canvas: Canvas) {
movingTargetFpIcon.alpha = alpha
fingerprintDrawable.setAlpha(alpha)
sensorOutlinePaint.setAlpha(alpha)
val currLocation = getCurrLocation() val currLocation = getCurrLocation()
canvas.scale(currentScale, currentScale, currLocation.centerX(), currLocation.centerY()) canvas.scale(currentScale, currentScale, currLocation.centerX(), currLocation.centerY())
sensorRectBounds?.let { canvas.drawOval(currLocation, sensorOutlinePaint) } sensorRectBounds?.let { canvas.drawOval(currLocation, sensorOutlinePaint) }
fingerprintDrawable.bounds = currLocation.toRect() fingerprintDrawable.bounds = currLocation.toRect()
fingerprintDrawable.draw(canvas) fingerprintDrawable.draw(canvas)
fingerprintDrawable.setAlpha(alpha)
sensorOutlinePaint.setAlpha(alpha)
} }
private fun getCurrLocation(): RectF = private fun getCurrLocation(): RectF =

View File

@@ -34,11 +34,11 @@ import android.util.DisplayMetrics
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import android.view.animation.Interpolator import android.view.animation.Interpolator
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.core.animation.doOnEnd
import androidx.core.graphics.toRectF import androidx.core.graphics.toRectF
import com.android.internal.annotations.VisibleForTesting import com.android.internal.annotations.VisibleForTesting
import com.android.settings.R import com.android.settings.R
import kotlin.math.max import kotlin.math.max
import kotlin.math.min
/** /**
* UDFPS enrollment progress bar. This view is responsible for drawing the progress ring and its * UDFPS enrollment progress bar. This view is responsible for drawing the progress ring and its
@@ -136,18 +136,22 @@ class UdfpsEnrollProgressBarDrawableV2(private val mContext: Context, attrs: Att
/** Indicates enrollment progress has occurred. */ /** Indicates enrollment progress has occurred. */
fun onEnrollmentProgress(remaining: Int, totalSteps: Int) { fun onEnrollmentProgress(remaining: Int, totalSteps: Int) {
afterFirstTouch = true afterFirstTouch = true
updateState(remaining, totalSteps, false /* showingHelp */) updateProgress(remaining, totalSteps)
} }
/** Indicates enrollment help has occurred. */ /** Indicates enrollment help has occurred. */
fun onEnrollmentHelp(remaining: Int, totalSteps: Int) { fun onEnrollmentHelp() {
updateState(remaining, totalSteps, true /* showingHelp */) if (remainingSteps == totalSteps) {
// We haven't had any progress, animate the background arc fill
animateBackgroundColor()
} else {
// else we have had progress, animate the progress fill
flashHelpFillColor()
}
} }
/** Indicates the last step was acquired. */ /** Indicates the last step was acquired. */
fun onLastStepAcquired() { fun onLastStepAcquired() {}
updateState(0, totalSteps, false /* showingHelp */)
}
override fun draw(canvas: Canvas) { override fun draw(canvas: Canvas) {
@@ -224,15 +228,12 @@ class UdfpsEnrollProgressBarDrawableV2(private val mContext: Context, attrs: Att
} }
} }
private fun updateState(remainingSteps: Int, totalSteps: Int, showingHelp: Boolean) { private fun updateProgress(remainingSteps: Int, totalSteps: Int) {
updateProgress(remainingSteps, totalSteps, showingHelp)
updateFillColor(showingHelp)
}
private fun updateProgress(remainingSteps: Int, totalSteps: Int, showingHelp: Boolean) {
if (this.remainingSteps == remainingSteps && this.totalSteps == totalSteps) { if (this.remainingSteps == remainingSteps && this.totalSteps == totalSteps) {
return return
} }
this.remainingSteps = remainingSteps
this.totalSteps = totalSteps
if (this.showingHelp) { if (this.showingHelp) {
if (vibrator != null && isAccessibilityEnabled) { if (vibrator != null && isAccessibilityEnabled) {
vibrator.vibrate( vibrator.vibrate(
@@ -270,13 +271,8 @@ class UdfpsEnrollProgressBarDrawableV2(private val mContext: Context, attrs: Att
this.showingHelp = showingHelp this.showingHelp = showingHelp
this.remainingSteps = remainingSteps this.remainingSteps = remainingSteps
this.totalSteps = totalSteps this.totalSteps = totalSteps
val progressSteps = max(0.0, (totalSteps - remainingSteps).toDouble()).toInt() val targetProgress = (totalSteps - remainingSteps).toFloat().div(max(1, totalSteps))
// If needed, add 1 to progress and total steps to account for initial touch.
val adjustedSteps = if (afterFirstTouch) progressSteps + 1 else progressSteps
val adjustedTotal = if (afterFirstTouch) this.totalSteps + 1 else this.totalSteps
val targetProgress =
min(1.0, (adjustedSteps.toFloat() / adjustedTotal.toFloat()).toDouble()).toFloat()
if (progressAnimator != null && progressAnimator!!.isRunning) { if (progressAnimator != null && progressAnimator!!.isRunning) {
progressAnimator!!.cancel() progressAnimator!!.cancel()
} }
@@ -286,13 +282,12 @@ class UdfpsEnrollProgressBarDrawableV2(private val mContext: Context, attrs: Att
it.addUpdateListener(progressUpdateListener) it.addUpdateListener(progressUpdateListener)
it.start() it.start()
} }
if (remainingSteps == 0) {
startCompletionAnimation()
} else if (remainingSteps > 0) {
rollBackCompletionAnimation()
}
} }
/**
* Flashes the background progress to a different color, followed by setting it back to the
* original progress color.
*/
private fun animateBackgroundColor() { private fun animateBackgroundColor() {
if (backgroundColorAnimator != null && backgroundColorAnimator!!.isRunning) { if (backgroundColorAnimator != null && backgroundColorAnimator!!.isRunning) {
backgroundColorAnimator!!.end() backgroundColorAnimator!!.end()
@@ -304,21 +299,20 @@ class UdfpsEnrollProgressBarDrawableV2(private val mContext: Context, attrs: Att
it.repeatMode = ValueAnimator.REVERSE it.repeatMode = ValueAnimator.REVERSE
it.interpolator = DEACCEL it.interpolator = DEACCEL
it.addUpdateListener(backgroundColorUpdateListener) it.addUpdateListener(backgroundColorUpdateListener)
it.doOnEnd { backgroundPaint.color = movingTargetFill }
it.start() it.start()
} }
} }
private fun updateFillColor(showingHelp: Boolean) { /**
if (!afterFirstTouch && showingHelp) { * Flashes the progress to a different color, followed by setting it back to the original progress
// If we are on the first touch, animate the background color * color.
// instead of the progress color. */
animateBackgroundColor() private fun flashHelpFillColor() {
return
}
if (fillColorAnimator != null && fillColorAnimator!!.isRunning) { if (fillColorAnimator != null && fillColorAnimator!!.isRunning) {
fillColorAnimator!!.end() fillColorAnimator!!.end()
} }
@ColorInt val targetColor = if (showingHelp) helpColor else progressColor @ColorInt val targetColor = helpColor
fillColorAnimator = fillColorAnimator =
ValueAnimator.ofArgb(fillPaint.color, targetColor).also { ValueAnimator.ofArgb(fillPaint.color, targetColor).also {
it.setDuration(FILL_COLOR_ANIMATION_DURATION_MS) it.setDuration(FILL_COLOR_ANIMATION_DURATION_MS)
@@ -326,6 +320,7 @@ class UdfpsEnrollProgressBarDrawableV2(private val mContext: Context, attrs: Att
it.repeatMode = ValueAnimator.REVERSE it.repeatMode = ValueAnimator.REVERSE
it.interpolator = DEACCEL it.interpolator = DEACCEL
it.addUpdateListener(fillColorUpdateListener) it.addUpdateListener(fillColorUpdateListener)
it.doOnEnd { fillPaint.color = enrollProgressColor }
it.start() it.start()
} }
} }

View File

@@ -54,23 +54,22 @@ class UdfpsEnrollViewV2(context: Context, attrs: AttributeSet?) : FrameLayout(co
*/ */
fun setSensorRect(rect: Rect) { fun setSensorRect(rect: Rect) {
this.sensorRect = rect this.sensorRect = rect
post {
findViewById<ImageView?>(R.id.udfps_enroll_animation_fp_progress_view)?.also {
it.setImageDrawable(fingerprintProgressDrawable)
}
findViewById<ImageView>(R.id.udfps_enroll_animation_fp_view)?.also {
it.setImageDrawable(fingerprintIcon)
}
val parentView = parent as ViewGroup
val coords = parentView.getLocationOnScreen()
val parentLeft = coords[0]
val parentTop = coords[1]
val sensorRectOffset = Rect(sensorRect)
sensorRectOffset.offset(-parentLeft, -parentTop)
fingerprintIcon.drawSensorRectAt(sensorRectOffset) findViewById<ImageView?>(R.id.udfps_enroll_animation_fp_progress_view)?.also {
fingerprintProgressDrawable.drawProgressAt(sensorRectOffset) it.setImageDrawable(fingerprintProgressDrawable)
} }
findViewById<ImageView>(R.id.udfps_enroll_animation_fp_view)?.also {
it.setImageDrawable(fingerprintIcon)
}
val parentView = parent as ViewGroup
val coords = parentView.getLocationOnScreen()
val parentLeft = coords[0]
val parentTop = coords[1]
val sensorRectOffset = Rect(sensorRect)
sensorRectOffset.offset(-parentLeft, -parentTop)
fingerprintIcon.drawSensorRectAt(sensorRectOffset)
fingerprintProgressDrawable.drawProgressAt(sensorRectOffset)
} }
/** Updates the current enrollment stage. */ /** Updates the current enrollment stage. */
@@ -97,15 +96,7 @@ class UdfpsEnrollViewV2(context: Context, attrs: AttributeSet?) : FrameLayout(co
fingerprintProgressDrawable.setAccessibilityEnabled(enabled) fingerprintProgressDrawable.setAccessibilityEnabled(enabled)
} }
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { private fun udfpsError(errMsgId: Int, errString: String) {}
invalidate()
super.onLayout(changed, left, top, right, bottom)
invalidate()
}
private fun udfpsError(errMsgId: Int, errString: String) {
Log.e(TAG, "Implement udfpsError")
}
private fun overlayShown() { private fun overlayShown() {
Log.e(TAG, "Implement overlayShown") Log.e(TAG, "Implement overlayShown")
@@ -113,28 +104,30 @@ class UdfpsEnrollViewV2(context: Context, attrs: AttributeSet?) : FrameLayout(co
/** Receive enroll progress event */ /** Receive enroll progress event */
private fun onEnrollmentProgress(remaining: Int, totalSteps: Int) { private fun onEnrollmentProgress(remaining: Int, totalSteps: Int) {
post { fingerprintIcon.onEnrollmentProgress(remaining, totalSteps)
fingerprintIcon.onEnrollmentProgress(remaining, totalSteps) fingerprintProgressDrawable.onEnrollmentProgress(remaining, totalSteps)
fingerprintProgressDrawable.onEnrollmentProgress(remaining, totalSteps)
}
} }
/** Receive enroll help event */ /** Receive enroll help event */
private fun onEnrollmentHelp() { private fun onEnrollmentHelp() {
post { fingerprintProgressDrawable.onEnrollmentHelp(mRemainingSteps, mTotalSteps) } fingerprintProgressDrawable.onEnrollmentHelp()
} }
/** Receive onAcquired event */ /** Receive onAcquired event */
private fun onAcquired(isAcquiredGood: Boolean) { private fun onAcquired(isAcquiredGood: Boolean) {
val animateIfLastStepGood = isAcquiredGood && mRemainingSteps <= 2 && mRemainingSteps >= 0 val animateIfLastStepGood = isAcquiredGood && mRemainingSteps <= 2 && mRemainingSteps >= 0
post { if (animateIfLastStepGood) fingerprintProgressDrawable.onLastStepAcquired() } if (animateIfLastStepGood) fingerprintProgressDrawable.onLastStepAcquired()
} }
/** Receive onPointerDown event */ /** Receive onPointerDown event */
private fun onPointerDown() {} private fun onPointerDown() {
fingerprintIcon.stopDrawing()
}
/** Receive onPointerUp event */ /** Receive onPointerUp event */
private fun onPointerUp() {} private fun onPointerUp() {
fingerprintIcon.startDrawing()
}
companion object { companion object {
private const val TAG = "UdfpsEnrollView" private const val TAG = "UdfpsEnrollView"