Merge "Update dwell ripple animation" into sc-v2-dev
This commit is contained in:
@@ -80,11 +80,6 @@ class AuthRippleController @Inject constructor(
|
|||||||
private var circleReveal: LightRevealEffect? = null
|
private var circleReveal: LightRevealEffect? = null
|
||||||
|
|
||||||
private var udfpsController: UdfpsController? = null
|
private var udfpsController: UdfpsController? = null
|
||||||
|
|
||||||
private var dwellScale = 2f
|
|
||||||
private var expandedDwellScale = 2.5f
|
|
||||||
private var aodDwellScale = 1.9f
|
|
||||||
private var aodExpandedDwellScale = 2.3f
|
|
||||||
private var udfpsRadius: Float = -1f
|
private var udfpsRadius: Float = -1f
|
||||||
|
|
||||||
override fun onInit() {
|
override fun onInit() {
|
||||||
@@ -128,7 +123,7 @@ class AuthRippleController @Inject constructor(
|
|||||||
updateSensorLocation()
|
updateSensorLocation()
|
||||||
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
||||||
fingerprintSensorLocation != null) {
|
fingerprintSensorLocation != null) {
|
||||||
mView.setSensorLocation(fingerprintSensorLocation!!)
|
mView.setFingerprintSensorLocation(fingerprintSensorLocation!!, udfpsRadius)
|
||||||
showUnlockedRipple()
|
showUnlockedRipple()
|
||||||
} else if (biometricSourceType == BiometricSourceType.FACE &&
|
} else if (biometricSourceType == BiometricSourceType.FACE &&
|
||||||
faceSensorLocation != null) {
|
faceSensorLocation != null) {
|
||||||
@@ -241,24 +236,12 @@ class AuthRippleController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateRippleColor() {
|
private fun updateRippleColor() {
|
||||||
mView.setColor(
|
mView.setLockScreenColor(Utils.getColorAttrDefaultColor(sysuiContext,
|
||||||
Utils.getColorAttr(sysuiContext, android.R.attr.colorAccent).defaultColor)
|
R.attr.wallpaperTextColorAccent))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showDwellRipple() {
|
private fun showDwellRipple() {
|
||||||
if (statusBarStateController.isDozing) {
|
mView.startDwellRipple(statusBarStateController.isDozing)
|
||||||
mView.startDwellRipple(
|
|
||||||
/* startRadius */ udfpsRadius,
|
|
||||||
/* endRadius */ udfpsRadius * aodDwellScale,
|
|
||||||
/* expandedRadius */ udfpsRadius * aodExpandedDwellScale,
|
|
||||||
/* isDozing */ true)
|
|
||||||
} else {
|
|
||||||
mView.startDwellRipple(
|
|
||||||
/* startRadius */ udfpsRadius,
|
|
||||||
/* endRadius */ udfpsRadius * dwellScale,
|
|
||||||
/* expandedRadius */ udfpsRadius * expandedDwellScale,
|
|
||||||
/* isDozing */ false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val keyguardUpdateMonitorCallback =
|
private val keyguardUpdateMonitorCallback =
|
||||||
@@ -295,7 +278,7 @@ class AuthRippleController @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mView.setSensorLocation(fingerprintSensorLocation!!)
|
mView.setFingerprintSensorLocation(fingerprintSensorLocation!!, udfpsRadius)
|
||||||
showDwellRipple()
|
showDwellRipple()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,8 +290,8 @@ class AuthRippleController @Inject constructor(
|
|||||||
private val authControllerCallback =
|
private val authControllerCallback =
|
||||||
object : AuthController.Callback {
|
object : AuthController.Callback {
|
||||||
override fun onAllAuthenticatorsRegistered() {
|
override fun onAllAuthenticatorsRegistered() {
|
||||||
updateSensorLocation()
|
|
||||||
updateUdfpsDependentParams()
|
updateUdfpsDependentParams()
|
||||||
|
updateSensorLocation()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEnrollmentsChanged() {
|
override fun onEnrollmentsChanged() {
|
||||||
@@ -329,20 +312,6 @@ class AuthRippleController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class AuthRippleCommand : Command {
|
inner class AuthRippleCommand : Command {
|
||||||
fun printLockScreenDwellInfo(pw: PrintWriter) {
|
|
||||||
pw.println("lock screen dwell ripple: " +
|
|
||||||
"\n\tsensorLocation=$fingerprintSensorLocation" +
|
|
||||||
"\n\tdwellScale=$dwellScale" +
|
|
||||||
"\n\tdwellExpand=$expandedDwellScale")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun printAodDwellInfo(pw: PrintWriter) {
|
|
||||||
pw.println("aod dwell ripple: " +
|
|
||||||
"\n\tsensorLocation=$fingerprintSensorLocation" +
|
|
||||||
"\n\tdwellScale=$aodDwellScale" +
|
|
||||||
"\n\tdwellExpand=$aodExpandedDwellScale")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun execute(pw: PrintWriter, args: List<String>) {
|
override fun execute(pw: PrintWriter, args: List<String>) {
|
||||||
if (args.isEmpty()) {
|
if (args.isEmpty()) {
|
||||||
invalidCommand(pw)
|
invalidCommand(pw)
|
||||||
@@ -350,11 +319,9 @@ class AuthRippleController @Inject constructor(
|
|||||||
when (args[0]) {
|
when (args[0]) {
|
||||||
"dwell" -> {
|
"dwell" -> {
|
||||||
showDwellRipple()
|
showDwellRipple()
|
||||||
if (statusBarStateController.isDozing) {
|
pw.println("lock screen dwell ripple: " +
|
||||||
printAodDwellInfo(pw)
|
"\n\tsensorLocation=$fingerprintSensorLocation" +
|
||||||
} else {
|
"\n\tudfpsRadius=$udfpsRadius")
|
||||||
printLockScreenDwellInfo(pw)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"fingerprint" -> {
|
"fingerprint" -> {
|
||||||
updateSensorLocation()
|
updateSensorLocation()
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.animation.AnimatorSet
|
|||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.PointF
|
import android.graphics.PointF
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
@@ -28,6 +29,7 @@ import android.view.View
|
|||||||
import android.view.animation.PathInterpolator
|
import android.view.animation.PathInterpolator
|
||||||
import com.android.internal.graphics.ColorUtils
|
import com.android.internal.graphics.ColorUtils
|
||||||
import com.android.systemui.animation.Interpolators
|
import com.android.systemui.animation.Interpolators
|
||||||
|
import com.android.systemui.statusbar.charging.DwellRippleShader
|
||||||
import com.android.systemui.statusbar.charging.RippleShader
|
import com.android.systemui.statusbar.charging.RippleShader
|
||||||
|
|
||||||
private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
|
private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
|
||||||
@@ -43,23 +45,32 @@ private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
|
|||||||
class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
|
class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
|
||||||
private val retractInterpolator = PathInterpolator(.05f, .93f, .1f, 1f)
|
private val retractInterpolator = PathInterpolator(.05f, .93f, .1f, 1f)
|
||||||
|
|
||||||
private val dwellPulseDuration = 50L
|
private val dwellPulseDuration = 100L
|
||||||
private val dwellAlphaDuration = dwellPulseDuration
|
private val dwellExpandDuration = 2000L - dwellPulseDuration
|
||||||
private val dwellAlpha: Float = 1f
|
|
||||||
private val dwellExpandDuration = 1200L - dwellPulseDuration
|
|
||||||
|
|
||||||
private val aodDwellPulseDuration = 50L
|
private var drawDwell: Boolean = false
|
||||||
private var aodDwellAlphaDuration = aodDwellPulseDuration
|
private var drawRipple: Boolean = false
|
||||||
private var aodDwellAlpha: Float = .8f
|
|
||||||
private var aodDwellExpandDuration = 1200L - aodDwellPulseDuration
|
|
||||||
|
|
||||||
|
private var lockScreenColorVal = Color.WHITE
|
||||||
private val retractDuration = 400L
|
private val retractDuration = 400L
|
||||||
private var alphaInDuration: Long = 0
|
private var alphaInDuration: Long = 0
|
||||||
private var unlockedRippleInProgress: Boolean = false
|
private var unlockedRippleInProgress: Boolean = false
|
||||||
|
private val dwellShader = DwellRippleShader()
|
||||||
|
private val dwellPaint = Paint()
|
||||||
private val rippleShader = RippleShader()
|
private val rippleShader = RippleShader()
|
||||||
private val ripplePaint = Paint()
|
private val ripplePaint = Paint()
|
||||||
private var retractAnimator: Animator? = null
|
private var retractAnimator: Animator? = null
|
||||||
private var dwellPulseOutAnimator: Animator? = null
|
private var dwellPulseOutAnimator: Animator? = null
|
||||||
|
private var dwellRadius: Float = 0f
|
||||||
|
set(value) {
|
||||||
|
dwellShader.maxRadius = value
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
private var dwellOrigin: PointF = PointF()
|
||||||
|
set(value) {
|
||||||
|
dwellShader.origin = value
|
||||||
|
field = value
|
||||||
|
}
|
||||||
private var radius: Float = 0f
|
private var radius: Float = 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
rippleShader.radius = value
|
rippleShader.radius = value
|
||||||
@@ -76,6 +87,11 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
rippleShader.progress = 0f
|
rippleShader.progress = 0f
|
||||||
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
|
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
|
||||||
ripplePaint.shader = rippleShader
|
ripplePaint.shader = rippleShader
|
||||||
|
|
||||||
|
dwellShader.color = 0xffffffff.toInt() // default color
|
||||||
|
dwellShader.progress = 0f
|
||||||
|
dwellShader.distortionStrength = .4f
|
||||||
|
dwellPaint.shader = dwellShader
|
||||||
visibility = GONE
|
visibility = GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +100,13 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
radius = maxOf(location.x, location.y, width - location.x, height - location.y).toFloat()
|
radius = maxOf(location.x, location.y, width - location.x, height - location.y).toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setFingerprintSensorLocation(location: PointF, sensorRadius: Float) {
|
||||||
|
origin = location
|
||||||
|
radius = maxOf(location.x, location.y, width - location.x, height - location.y).toFloat()
|
||||||
|
dwellOrigin = location
|
||||||
|
dwellRadius = sensorRadius * 1.5f
|
||||||
|
}
|
||||||
|
|
||||||
fun setAlphaInDuration(duration: Long) {
|
fun setAlphaInDuration(duration: Long) {
|
||||||
alphaInDuration = duration
|
alphaInDuration = duration
|
||||||
}
|
}
|
||||||
@@ -97,14 +120,14 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dwellPulseOutAnimator?.isRunning == true) {
|
if (dwellPulseOutAnimator?.isRunning == true) {
|
||||||
val retractRippleAnimator = ValueAnimator.ofFloat(rippleShader.progress, 0f)
|
val retractRippleAnimator = ValueAnimator.ofFloat(dwellShader.progress, 0f)
|
||||||
.apply {
|
.apply {
|
||||||
interpolator = retractInterpolator
|
interpolator = retractInterpolator
|
||||||
duration = retractDuration
|
duration = retractDuration
|
||||||
addUpdateListener { animator ->
|
addUpdateListener { animator ->
|
||||||
val now = animator.currentPlayTime
|
val now = animator.currentPlayTime
|
||||||
rippleShader.progress = animator.animatedValue as Float
|
dwellShader.progress = animator.animatedValue as Float
|
||||||
rippleShader.time = now.toFloat()
|
dwellShader.time = now.toFloat()
|
||||||
|
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
@@ -114,8 +137,8 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
interpolator = Interpolators.LINEAR
|
interpolator = Interpolators.LINEAR
|
||||||
duration = retractDuration
|
duration = retractDuration
|
||||||
addUpdateListener { animator ->
|
addUpdateListener { animator ->
|
||||||
rippleShader.color = ColorUtils.setAlphaComponent(
|
dwellShader.color = ColorUtils.setAlphaComponent(
|
||||||
rippleShader.color,
|
dwellShader.color,
|
||||||
animator.animatedValue as Int
|
animator.animatedValue as Int
|
||||||
)
|
)
|
||||||
invalidate()
|
invalidate()
|
||||||
@@ -127,13 +150,12 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
addListener(object : AnimatorListenerAdapter() {
|
addListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationStart(animation: Animator?) {
|
override fun onAnimationStart(animation: Animator?) {
|
||||||
dwellPulseOutAnimator?.cancel()
|
dwellPulseOutAnimator?.cancel()
|
||||||
rippleShader.shouldFadeOutRipple = false
|
drawDwell = true
|
||||||
visibility = VISIBLE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: Animator?) {
|
override fun onAnimationEnd(animation: Animator?) {
|
||||||
visibility = GONE
|
drawDwell = false
|
||||||
resetRippleAlpha()
|
resetDwellAlpha()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
start()
|
start()
|
||||||
@@ -142,101 +164,54 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ripple that moves animates from an outer ripple ring of
|
* Plays a ripple animation that grows to the dwellRadius with distortion.
|
||||||
* startRadius => endRadius => expandedRadius
|
|
||||||
*/
|
*/
|
||||||
fun startDwellRipple(
|
fun startDwellRipple(isDozing: Boolean) {
|
||||||
startRadius: Float,
|
|
||||||
endRadius: Float,
|
|
||||||
expandedRadius: Float,
|
|
||||||
isDozing: Boolean
|
|
||||||
) {
|
|
||||||
if (unlockedRippleInProgress || dwellPulseOutAnimator?.isRunning == true) {
|
if (unlockedRippleInProgress || dwellPulseOutAnimator?.isRunning == true) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// we divide by 4 because the desired startRadius and endRadius is for the ripple's outer
|
updateDwellRippleColor(isDozing)
|
||||||
// ring see RippleShader
|
|
||||||
val startDwellProgress = startRadius / radius / 4f
|
|
||||||
val endInitialDwellProgress = endRadius / radius / 4f
|
|
||||||
val endExpandDwellProgress = expandedRadius / radius / 4f
|
|
||||||
|
|
||||||
val alpha = if (isDozing) aodDwellAlpha else dwellAlpha
|
val dwellPulseOutRippleAnimator = ValueAnimator.ofFloat(0f, .8f).apply {
|
||||||
val pulseOutEndAlpha = (255 * alpha).toInt()
|
interpolator = Interpolators.LINEAR
|
||||||
val expandDwellEndAlpha = kotlin.math.min((255 * (alpha + .25f)).toInt(), 255)
|
duration = dwellPulseDuration
|
||||||
val dwellPulseOutRippleAnimator = ValueAnimator.ofFloat(startDwellProgress,
|
|
||||||
endInitialDwellProgress).apply {
|
|
||||||
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
|
|
||||||
duration = if (isDozing) aodDwellPulseDuration else dwellPulseDuration
|
|
||||||
addUpdateListener { animator ->
|
addUpdateListener { animator ->
|
||||||
val now = animator.currentPlayTime
|
val now = animator.currentPlayTime
|
||||||
rippleShader.progress = animator.animatedValue as Float
|
dwellShader.progress = animator.animatedValue as Float
|
||||||
rippleShader.time = now.toFloat()
|
dwellShader.time = now.toFloat()
|
||||||
|
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val dwellPulseOutAlphaAnimator = ValueAnimator.ofInt(0, pulseOutEndAlpha).apply {
|
|
||||||
interpolator = Interpolators.LINEAR
|
|
||||||
duration = if (isDozing) aodDwellAlphaDuration else dwellAlphaDuration
|
|
||||||
addUpdateListener { animator ->
|
|
||||||
rippleShader.color = ColorUtils.setAlphaComponent(
|
|
||||||
rippleShader.color,
|
|
||||||
animator.animatedValue as Int
|
|
||||||
)
|
|
||||||
invalidate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// slowly animate outwards until we receive a call to retractRipple or startUnlockedRipple
|
// slowly animate outwards until we receive a call to retractRipple or startUnlockedRipple
|
||||||
val expandDwellRippleAnimator = ValueAnimator.ofFloat(endInitialDwellProgress,
|
val expandDwellRippleAnimator = ValueAnimator.ofFloat(.8f, 1f).apply {
|
||||||
endExpandDwellProgress).apply {
|
|
||||||
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
|
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
|
||||||
duration = if (isDozing) aodDwellExpandDuration else dwellExpandDuration
|
duration = dwellExpandDuration
|
||||||
addUpdateListener { animator ->
|
addUpdateListener { animator ->
|
||||||
val now = animator.currentPlayTime
|
val now = animator.currentPlayTime
|
||||||
rippleShader.progress = animator.animatedValue as Float
|
dwellShader.progress = animator.animatedValue as Float
|
||||||
rippleShader.time = now.toFloat()
|
dwellShader.time = now.toFloat()
|
||||||
|
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val expandDwellAlphaAnimator = ValueAnimator.ofInt(pulseOutEndAlpha, expandDwellEndAlpha)
|
|
||||||
.apply {
|
|
||||||
interpolator = Interpolators.LINEAR
|
|
||||||
duration = if (isDozing) aodDwellExpandDuration else dwellExpandDuration
|
|
||||||
addUpdateListener { animator ->
|
|
||||||
rippleShader.color = ColorUtils.setAlphaComponent(
|
|
||||||
rippleShader.color,
|
|
||||||
animator.animatedValue as Int
|
|
||||||
)
|
|
||||||
invalidate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val initialDwellPulseOutAnimator = AnimatorSet().apply {
|
|
||||||
playTogether(dwellPulseOutRippleAnimator, dwellPulseOutAlphaAnimator)
|
|
||||||
}
|
|
||||||
val expandDwellAnimator = AnimatorSet().apply {
|
|
||||||
playTogether(expandDwellRippleAnimator, expandDwellAlphaAnimator)
|
|
||||||
}
|
|
||||||
|
|
||||||
dwellPulseOutAnimator = AnimatorSet().apply {
|
dwellPulseOutAnimator = AnimatorSet().apply {
|
||||||
playSequentially(
|
playSequentially(
|
||||||
initialDwellPulseOutAnimator,
|
dwellPulseOutRippleAnimator,
|
||||||
expandDwellAnimator
|
expandDwellRippleAnimator
|
||||||
)
|
)
|
||||||
addListener(object : AnimatorListenerAdapter() {
|
addListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationStart(animation: Animator?) {
|
override fun onAnimationStart(animation: Animator?) {
|
||||||
retractAnimator?.cancel()
|
retractAnimator?.cancel()
|
||||||
rippleShader.shouldFadeOutRipple = false
|
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
|
drawDwell = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: Animator?) {
|
override fun onAnimationEnd(animation: Animator?) {
|
||||||
visibility = GONE
|
drawDwell = false
|
||||||
resetRippleAlpha()
|
resetRippleAlpha()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -252,16 +227,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
return // Ignore if ripple effect is already playing
|
return // Ignore if ripple effect is already playing
|
||||||
}
|
}
|
||||||
|
|
||||||
var rippleStart = 0f
|
val rippleAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
|
||||||
var alphaDuration = alphaInDuration
|
|
||||||
if (dwellPulseOutAnimator?.isRunning == true || retractAnimator?.isRunning == true) {
|
|
||||||
rippleStart = rippleShader.progress
|
|
||||||
alphaDuration = 0
|
|
||||||
dwellPulseOutAnimator?.cancel()
|
|
||||||
retractAnimator?.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
val rippleAnimator = ValueAnimator.ofFloat(rippleStart, 1f).apply {
|
|
||||||
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
|
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
|
||||||
duration = AuthRippleController.RIPPLE_ANIMATION_DURATION
|
duration = AuthRippleController.RIPPLE_ANIMATION_DURATION
|
||||||
addUpdateListener { animator ->
|
addUpdateListener { animator ->
|
||||||
@@ -274,7 +240,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alphaInAnimator = ValueAnimator.ofInt(0, 255).apply {
|
val alphaInAnimator = ValueAnimator.ofInt(0, 255).apply {
|
||||||
duration = alphaDuration
|
duration = alphaInDuration
|
||||||
addUpdateListener { animator ->
|
addUpdateListener { animator ->
|
||||||
rippleShader.color = ColorUtils.setAlphaComponent(
|
rippleShader.color = ColorUtils.setAlphaComponent(
|
||||||
rippleShader.color,
|
rippleShader.color,
|
||||||
@@ -293,12 +259,14 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
override fun onAnimationStart(animation: Animator?) {
|
override fun onAnimationStart(animation: Animator?) {
|
||||||
unlockedRippleInProgress = true
|
unlockedRippleInProgress = true
|
||||||
rippleShader.shouldFadeOutRipple = true
|
rippleShader.shouldFadeOutRipple = true
|
||||||
|
drawRipple = true
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: Animator?) {
|
override fun onAnimationEnd(animation: Animator?) {
|
||||||
onAnimationEnd?.run()
|
onAnimationEnd?.run()
|
||||||
unlockedRippleInProgress = false
|
unlockedRippleInProgress = false
|
||||||
|
drawRipple = false
|
||||||
visibility = GONE
|
visibility = GONE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -313,17 +281,42 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setColor(color: Int) {
|
fun setLockScreenColor(color: Int) {
|
||||||
rippleShader.color = color
|
lockScreenColorVal = color
|
||||||
|
rippleShader.color = lockScreenColorVal
|
||||||
resetRippleAlpha()
|
resetRippleAlpha()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateDwellRippleColor(isDozing: Boolean) {
|
||||||
|
if (isDozing) {
|
||||||
|
dwellShader.color = Color.WHITE
|
||||||
|
} else {
|
||||||
|
dwellShader.color = lockScreenColorVal
|
||||||
|
}
|
||||||
|
resetDwellAlpha()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resetDwellAlpha() {
|
||||||
|
dwellShader.color = ColorUtils.setAlphaComponent(
|
||||||
|
dwellShader.color,
|
||||||
|
255
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDraw(canvas: Canvas?) {
|
override fun onDraw(canvas: Canvas?) {
|
||||||
// To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover
|
// To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover
|
||||||
// the active effect area. Values here should be kept in sync with the
|
// the active effect area. Values here should be kept in sync with the
|
||||||
// animation implementation in the ripple shader.
|
// animation implementation in the ripple shader.
|
||||||
val maskRadius = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) *
|
if (drawDwell) {
|
||||||
(1 - rippleShader.progress)) * radius * 2f
|
val maskRadius = (1 - (1 - dwellShader.progress) * (1 - dwellShader.progress) *
|
||||||
canvas?.drawCircle(origin.x, origin.y, maskRadius, ripplePaint)
|
(1 - dwellShader.progress)) * dwellRadius * 2f
|
||||||
|
canvas?.drawCircle(dwellOrigin.x, dwellOrigin.y, maskRadius, dwellPaint)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawRipple) {
|
||||||
|
val mask = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) *
|
||||||
|
(1 - rippleShader.progress)) * radius * 2f
|
||||||
|
canvas?.drawCircle(origin.x, origin.y, mask, ripplePaint)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ class DwellRippleShader internal constructor() : RuntimeShader(SHADER, false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec2 distort(vec2 p, float time, float distort_amount_xy, float frequency) {
|
vec2 distort(vec2 p, float time, float distort_amount_xy, float frequency) {
|
||||||
return p + vec2(sin(p.x * frequency + in_phase1),
|
return p + vec2(sin(p.y * frequency + in_phase1),
|
||||||
cos(p.y * frequency * 1.23 + in_phase2)) * distort_amount_xy;
|
cos(p.x * frequency * -1.23 + in_phase2)) * distort_amount_xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 ripple(vec2 p, float distort_xy, float frequency) {
|
vec4 ripple(vec2 p, float distort_xy, float frequency) {
|
||||||
@@ -73,11 +73,11 @@ class DwellRippleShader internal constructor() : RuntimeShader(SHADER, false) {
|
|||||||
"""
|
"""
|
||||||
private const val SHADER_MAIN = """vec4 main(vec2 p) {
|
private const val SHADER_MAIN = """vec4 main(vec2 p) {
|
||||||
vec4 color1 = ripple(p,
|
vec4 color1 = ripple(p,
|
||||||
12 * in_distortion_strength, // distort_xy
|
34 * in_distortion_strength, // distort_xy
|
||||||
0.012 // frequency
|
0.012 // frequency
|
||||||
);
|
);
|
||||||
vec4 color2 = ripple(p,
|
vec4 color2 = ripple(p,
|
||||||
17.5 * in_distortion_strength, // distort_xy
|
49 * in_distortion_strength, // distort_xy
|
||||||
0.018 // frequency
|
0.018 // frequency
|
||||||
);
|
);
|
||||||
// Alpha blend between two layers.
|
// Alpha blend between two layers.
|
||||||
@@ -128,8 +128,8 @@ class DwellRippleShader internal constructor() : RuntimeShader(SHADER, false) {
|
|||||||
set(value) {
|
set(value) {
|
||||||
field = value * 0.001f
|
field = value * 0.001f
|
||||||
setUniform("in_time", field)
|
setUniform("in_time", field)
|
||||||
setUniform("in_phase1", field * 2f + 0.367f)
|
setUniform("in_phase1", field * 3f + 0.367f)
|
||||||
setUniform("in_phase2", field * 5.2f * 1.531f)
|
setUniform("in_phase2", field * 7.2f * 1.531f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
false /* isStrongBiometric */)
|
false /* isStrongBiometric */)
|
||||||
|
|
||||||
// THEN update sensor location and show ripple
|
// THEN update sensor location and show ripple
|
||||||
verify(rippleView).setSensorLocation(fpsLocation)
|
verify(rippleView).setFingerprintSensorLocation(fpsLocation, -1f)
|
||||||
verify(rippleView).startUnlockedRipple(any())
|
verify(rippleView).startUnlockedRipple(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,10 +292,10 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
reset(rippleView)
|
reset(rippleView)
|
||||||
captor.value.onThemeChanged()
|
captor.value.onThemeChanged()
|
||||||
verify(rippleView).setColor(ArgumentMatchers.anyInt())
|
verify(rippleView).setLockScreenColor(ArgumentMatchers.anyInt())
|
||||||
|
|
||||||
reset(rippleView)
|
reset(rippleView)
|
||||||
captor.value.onUiModeChanged()
|
captor.value.onUiModeChanged()
|
||||||
verify(rippleView).setColor(ArgumentMatchers.anyInt())
|
verify(rippleView).setLockScreenColor(ArgumentMatchers.anyInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user