Merge "Add haptic feedback to auth ripple animation" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8c8765d3c3
@@ -23,7 +23,11 @@ import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PointF
|
||||
import android.media.AudioAttributes
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.util.AttributeSet
|
||||
import android.util.MathUtils
|
||||
import android.view.View
|
||||
import android.view.animation.PathInterpolator
|
||||
import com.android.internal.graphics.ColorUtils
|
||||
@@ -31,15 +35,26 @@ import com.android.systemui.statusbar.charging.RippleShader
|
||||
|
||||
private const val RIPPLE_ANIMATION_DURATION: Long = 1533
|
||||
private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
|
||||
private const val RIPPLE_VIBRATION_PRIMITIVE: Int = VibrationEffect.Composition.PRIMITIVE_LOW_TICK
|
||||
private const val RIPPLE_VIBRATION_SIZE: Int = 60
|
||||
private const val RIPPLE_VIBRATION_SCALE_START: Float = 0.6f
|
||||
private const val RIPPLE_VIBRATION_SCALE_DECAY: Float = -0.1f
|
||||
|
||||
/**
|
||||
* Expanding ripple effect on the transition from biometric authentication success to showing
|
||||
* launcher.
|
||||
*/
|
||||
class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
|
||||
private val vibrator: Vibrator? = context?.getSystemService(Vibrator::class.java)
|
||||
private var rippleInProgress: Boolean = false
|
||||
private val rippleShader = RippleShader()
|
||||
private val ripplePaint = Paint()
|
||||
private val rippleVibrationEffect = createVibrationEffect(vibrator)
|
||||
private val rippleVibrationAttrs =
|
||||
AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
|
||||
.build()
|
||||
|
||||
init {
|
||||
rippleShader.color = 0xffffffff.toInt() // default color
|
||||
@@ -95,6 +110,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
||||
visibility = GONE
|
||||
}
|
||||
})
|
||||
vibrate()
|
||||
animatorSet.start()
|
||||
visibility = VISIBLE
|
||||
rippleInProgress = true
|
||||
@@ -108,4 +124,23 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
||||
// draw over the entire screen
|
||||
canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), ripplePaint)
|
||||
}
|
||||
|
||||
private fun vibrate() {
|
||||
if (rippleVibrationEffect != null) {
|
||||
vibrator?.vibrate(rippleVibrationEffect, rippleVibrationAttrs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createVibrationEffect(vibrator: Vibrator?): VibrationEffect? {
|
||||
if (vibrator?.areAllPrimitivesSupported(RIPPLE_VIBRATION_PRIMITIVE) == false) {
|
||||
return null
|
||||
}
|
||||
val composition = VibrationEffect.startComposition()
|
||||
for (i in 0 until RIPPLE_VIBRATION_SIZE) {
|
||||
val scale =
|
||||
RIPPLE_VIBRATION_SCALE_START * MathUtils.exp(RIPPLE_VIBRATION_SCALE_DECAY * i)
|
||||
composition.addPrimitive(RIPPLE_VIBRATION_PRIMITIVE, scale, 0 /* delay */)
|
||||
}
|
||||
return composition.compose()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user