Update udfps icon on lockscreen and AOD
Use lottie to render udfps icons on AOD and lockscreen. On AOD, this allows us to step through a dashed pattern to decrease burn-in. On lockscreen, we use the lottie to animate the stroke width of the icon. Test: manual, atest SystemUITest Bug: 178418596 Change-Id: Ie74c460c23b4283b9c6029b29b17ec9d0dd9b09f
This commit is contained in:
@@ -94,6 +94,7 @@ android_library {
|
||||
"SystemUI-proto",
|
||||
"dagger2",
|
||||
"jsr330",
|
||||
"lottie",
|
||||
],
|
||||
manifest: "AndroidManifest.xml",
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
-->
|
||||
<com.android.systemui.biometrics.UdfpsKeyguardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/udfps_animation_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
@@ -29,8 +30,28 @@
|
||||
android:visibility="gone"/>
|
||||
|
||||
<!-- Fingerprint -->
|
||||
<ImageView
|
||||
android:id="@+id/udfps_keyguard_animation_fp_view"
|
||||
|
||||
<!-- AOD dashed fingerprint icon with moving dashes -->
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/udfps_aod_fp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
app:lottie_autoPlay="false"
|
||||
android:padding="16dp"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_rawRes="@raw/udfps_aod_fp"/>
|
||||
|
||||
<!-- LockScreen fingerprint icon from 0 stroke width to full width -->
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/udfps_lockscreen_fp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
app:lottie_autoPlay="false"
|
||||
app:lottie_loop="false"
|
||||
android:padding="16dp"
|
||||
app:lottie_rawRes="@raw/udfps_lockscreen_fp"/>
|
||||
</com.android.systemui.biometrics.UdfpsKeyguardView>
|
||||
|
||||
2445
packages/SystemUI/res/raw/udfps_aod_fp.json
Normal file
2445
packages/SystemUI/res/raw/udfps_aod_fp.json
Normal file
File diff suppressed because it is too large
Load Diff
1017
packages/SystemUI/res/raw/udfps_lockscreen_fp.json
Normal file
1017
packages/SystemUI/res/raw/udfps_lockscreen_fp.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -74,7 +74,10 @@ abstract class UdfpsAnimationView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void updateAlpha() {
|
||||
/**
|
||||
* @return current alpha
|
||||
*/
|
||||
protected int updateAlpha() {
|
||||
int alpha = calculateAlpha();
|
||||
getDrawable().setAlpha(alpha);
|
||||
|
||||
@@ -84,6 +87,8 @@ abstract class UdfpsAnimationView extends FrameLayout {
|
||||
} else {
|
||||
((ViewGroup) getParent()).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
int calculateAlpha() {
|
||||
|
||||
@@ -42,11 +42,6 @@ public class UdfpsEnrollView extends UdfpsAnimationView {
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateAlpha() {
|
||||
super.updateAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
mFingerprintView = findViewById(R.id.udfps_enroll_animation_fp_view);
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.util.MathUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.graphics.ColorUtils;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.doze.DozeReceiver;
|
||||
|
||||
/**
|
||||
* UDFPS animations that should be shown when authenticating on keyguard.
|
||||
*/
|
||||
public class UdfpsKeyguardDrawable extends UdfpsDrawable implements DozeReceiver {
|
||||
|
||||
private static final String TAG = "UdfpsAnimationKeyguard";
|
||||
private final int mAmbientDisplayColor;
|
||||
static final float DEFAULT_AOD_STROKE_WIDTH = 1f;
|
||||
|
||||
@NonNull private final Context mContext;
|
||||
private int mLockScreenColor;
|
||||
|
||||
// AOD anti-burn-in offsets
|
||||
private final int mMaxBurnInOffsetX;
|
||||
private final int mMaxBurnInOffsetY;
|
||||
private float mInterpolatedDarkAmount;
|
||||
private float mBurnInOffsetX;
|
||||
private float mBurnInOffsetY;
|
||||
|
||||
private final ValueAnimator mHintAnimator = ValueAnimator.ofFloat(
|
||||
UdfpsKeyguardDrawable.DEFAULT_STROKE_WIDTH,
|
||||
.5f,
|
||||
UdfpsKeyguardDrawable.DEFAULT_STROKE_WIDTH);
|
||||
|
||||
UdfpsKeyguardDrawable(@NonNull Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
|
||||
mMaxBurnInOffsetX = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
|
||||
mMaxBurnInOffsetY = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
|
||||
|
||||
mHintAnimator.setDuration(2000);
|
||||
mHintAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
mHintAnimator.addUpdateListener(anim -> setStrokeWidth((float) anim.getAnimatedValue()));
|
||||
|
||||
mLockScreenColor = Utils.getColorAttrDefaultColor(mContext,
|
||||
R.attr.wallpaperTextColorAccent);
|
||||
mAmbientDisplayColor = Color.WHITE;
|
||||
|
||||
updateIcon();
|
||||
}
|
||||
|
||||
private void updateIcon() {
|
||||
mBurnInOffsetX = MathUtils.lerp(0f,
|
||||
getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
|
||||
- mMaxBurnInOffsetX,
|
||||
mInterpolatedDarkAmount);
|
||||
mBurnInOffsetY = MathUtils.lerp(0f,
|
||||
getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
|
||||
- mMaxBurnInOffsetY,
|
||||
mInterpolatedDarkAmount);
|
||||
|
||||
mFingerprintDrawable.setTint(ColorUtils.blendARGB(mLockScreenColor,
|
||||
mAmbientDisplayColor, mInterpolatedDarkAmount));
|
||||
setStrokeWidth(MathUtils.lerp(DEFAULT_STROKE_WIDTH, DEFAULT_AOD_STROKE_WIDTH,
|
||||
mInterpolatedDarkAmount));
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dozeTimeTick() {
|
||||
updateIcon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
if (isIlluminationShowing()) {
|
||||
return;
|
||||
}
|
||||
canvas.save();
|
||||
canvas.translate(mBurnInOffsetX, mBurnInOffsetY);
|
||||
mFingerprintDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
void animateHint() {
|
||||
mHintAnimator.start();
|
||||
}
|
||||
|
||||
void onDozeAmountChanged(float linear, float eased) {
|
||||
mHintAnimator.cancel();
|
||||
mInterpolatedDarkAmount = eased;
|
||||
updateIcon();
|
||||
}
|
||||
|
||||
void setLockScreenColor(int color) {
|
||||
if (mLockScreenColor == color) return;
|
||||
mLockScreenColor = color;
|
||||
updateIcon();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
||||
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -23,7 +26,10 @@ import android.animation.ArgbEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.MathUtils;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
@@ -34,12 +40,17 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
import com.airbnb.lottie.LottieProperty;
|
||||
import com.airbnb.lottie.model.KeyPath;
|
||||
/**
|
||||
* View corresponding with udfps_keyguard_view.xml
|
||||
*/
|
||||
public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
private final UdfpsKeyguardDrawable mFingerprintDrawable;
|
||||
private ImageView mFingerprintView;
|
||||
private UdfpsDrawable mFingerprintDrawable; // placeholder
|
||||
private LottieAnimationView mAodFp;
|
||||
private LottieAnimationView mLockScreenFp;
|
||||
private int mUdfpsBouncerColor;
|
||||
private int mWallpaperTextColor;
|
||||
private int mStatusBarState;
|
||||
|
||||
@@ -52,16 +63,31 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
private AnimatorSet mAnimatorSet;
|
||||
private int mAlpha; // 0-255
|
||||
|
||||
// AOD anti-burn-in offsets
|
||||
private final int mMaxBurnInOffsetX;
|
||||
private final int mMaxBurnInOffsetY;
|
||||
private float mBurnInOffsetX;
|
||||
private float mBurnInOffsetY;
|
||||
private float mBurnInProgress;
|
||||
private float mInterpolatedDarkAmount;
|
||||
|
||||
private ValueAnimator mHintAnimator;
|
||||
|
||||
public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mFingerprintDrawable = new UdfpsKeyguardDrawable(mContext);
|
||||
mFingerprintDrawable = new UdfpsFpDrawable(context);
|
||||
|
||||
mMaxBurnInOffsetX = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
|
||||
mMaxBurnInOffsetY = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mFingerprintView = findViewById(R.id.udfps_keyguard_animation_fp_view);
|
||||
mFingerprintView.setForeground(mFingerprintDrawable);
|
||||
mAodFp = findViewById(R.id.udfps_aod_fp);
|
||||
mLockScreenFp = findViewById(R.id.udfps_lockscreen_fp);
|
||||
|
||||
mBgProtection = findViewById(R.id.udfps_keyguard_fp_bg);
|
||||
|
||||
@@ -69,7 +95,16 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
R.attr.wallpaperTextColorAccent);
|
||||
mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
|
||||
android.R.attr.textColorPrimary);
|
||||
|
||||
// requires call to invalidate to update the color (see #updateColor)
|
||||
mLockScreenFp.addValueCallback(
|
||||
new KeyPath("**"), LottieProperty.COLOR_FILTER,
|
||||
frameInfo -> new PorterDuffColorFilter(getColor(), PorterDuff.Mode.SRC_ATOP)
|
||||
);
|
||||
mUdfpsRequested = false;
|
||||
|
||||
mHintAnimator = ObjectAnimator.ofFloat(mLockScreenFp, "progress", 1f, 0f, 1f);
|
||||
mHintAnimator.setDuration(4000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,10 +124,27 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
|
||||
@Override
|
||||
public boolean dozeTimeTick() {
|
||||
mFingerprintDrawable.dozeTimeTick();
|
||||
updateBurnInOffsets();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateBurnInOffsets() {
|
||||
mBurnInOffsetX = MathUtils.lerp(0f,
|
||||
getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
|
||||
- mMaxBurnInOffsetX, mInterpolatedDarkAmount);
|
||||
mBurnInOffsetY = MathUtils.lerp(0f,
|
||||
getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
|
||||
- mMaxBurnInOffsetY, mInterpolatedDarkAmount);
|
||||
mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);
|
||||
|
||||
mAodFp.setTranslationX(mBurnInOffsetX);
|
||||
mAodFp.setTranslationY(mBurnInOffsetY);
|
||||
mAodFp.setProgress(mBurnInProgress);
|
||||
|
||||
mLockScreenFp.setTranslationX(mBurnInOffsetX);
|
||||
mLockScreenFp.setTranslationY(mBurnInOffsetY);
|
||||
}
|
||||
|
||||
void requestUdfps(boolean request, int color) {
|
||||
if (request) {
|
||||
mUdfpsRequestedColor = color;
|
||||
@@ -105,22 +157,31 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
|
||||
void setStatusBarState(int statusBarState) {
|
||||
mStatusBarState = statusBarState;
|
||||
updateColor();
|
||||
}
|
||||
|
||||
void updateColor() {
|
||||
mFingerprintView.setAlpha(1f);
|
||||
mFingerprintDrawable.setLockScreenColor(getColor());
|
||||
mLockScreenFp.invalidate();
|
||||
}
|
||||
|
||||
private boolean showingUdfpsBouncer() {
|
||||
return mBgProtection.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
|
||||
private int getColor() {
|
||||
if (mUdfpsRequested && mUdfpsRequestedColor != -1) {
|
||||
if (isUdfpsColorRequested()) {
|
||||
return mUdfpsRequestedColor;
|
||||
} else if (showingUdfpsBouncer()) {
|
||||
return mUdfpsBouncerColor;
|
||||
} else {
|
||||
return mWallpaperTextColor;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUdfpsColorRequested() {
|
||||
return mUdfpsRequested && mUdfpsRequestedColor != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alpha between 0 and 255
|
||||
*/
|
||||
@@ -129,6 +190,13 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
updateAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int updateAlpha() {
|
||||
int alpha = super.updateAlpha();
|
||||
mLockScreenFp.setImageAlpha(alpha);
|
||||
return alpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
int calculateAlpha() {
|
||||
if (mPauseAuth) {
|
||||
@@ -138,18 +206,31 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
}
|
||||
|
||||
void onDozeAmountChanged(float linear, float eased) {
|
||||
mFingerprintDrawable.onDozeAmountChanged(linear, eased);
|
||||
mHintAnimator.cancel();
|
||||
mInterpolatedDarkAmount = eased;
|
||||
updateBurnInOffsets();
|
||||
mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
|
||||
mAodFp.setAlpha(mInterpolatedDarkAmount);
|
||||
|
||||
if (linear == 1f) {
|
||||
mLockScreenFp.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
mLockScreenFp.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
void animateHint() {
|
||||
mFingerprintDrawable.animateHint();
|
||||
if (!isShadeLocked() && !mUdfpsRequested && mAlpha == 255
|
||||
&& mLockScreenFp.isVisibleToUser()) {
|
||||
mHintAnimator.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates in the bg protection circle behind the fp icon to highlight the icon.
|
||||
*/
|
||||
void animateUdfpsBouncer(Runnable onEndAnimation) {
|
||||
if (mBgProtection.getVisibility() == View.VISIBLE && mBgProtection.getAlpha() == 1f) {
|
||||
if (showingUdfpsBouncer() && mBgProtection.getAlpha() == 1f) {
|
||||
// already fully highlighted, don't re-animate
|
||||
return;
|
||||
}
|
||||
@@ -157,19 +238,6 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
if (mAnimatorSet != null) {
|
||||
mAnimatorSet.cancel();
|
||||
}
|
||||
ValueAnimator fpIconAnim;
|
||||
if (isShadeLocked()) {
|
||||
// set color and fade in since we weren't showing before
|
||||
mFingerprintDrawable.setLockScreenColor(mTextColorPrimary);
|
||||
fpIconAnim = ObjectAnimator.ofFloat(mFingerprintView, View.ALPHA, 0f, 1f);
|
||||
} else {
|
||||
// update icon color
|
||||
fpIconAnim = new ValueAnimator();
|
||||
fpIconAnim.setIntValues(getColor(), mTextColorPrimary);
|
||||
fpIconAnim.setEvaluator(new ArgbEvaluator());
|
||||
fpIconAnim.addUpdateListener(valueAnimator -> mFingerprintDrawable.setLockScreenColor(
|
||||
(Integer) valueAnimator.getAnimatedValue()));
|
||||
}
|
||||
|
||||
mAnimatorSet = new AnimatorSet();
|
||||
mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
@@ -181,11 +249,31 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
}
|
||||
});
|
||||
|
||||
ValueAnimator fpIconColorAnim;
|
||||
if (isShadeLocked()) {
|
||||
// set color and fade in since we weren't showing before
|
||||
mUdfpsBouncerColor = mTextColorPrimary;
|
||||
fpIconColorAnim = ValueAnimator.ofInt(0, 255);
|
||||
fpIconColorAnim.addUpdateListener(valueAnimator ->
|
||||
mLockScreenFp.setImageAlpha((int) valueAnimator.getAnimatedValue()));
|
||||
} else {
|
||||
// update icon color
|
||||
fpIconColorAnim = new ValueAnimator();
|
||||
fpIconColorAnim.setIntValues(
|
||||
isUdfpsColorRequested() ? mUdfpsRequestedColor : mWallpaperTextColor,
|
||||
mTextColorPrimary);
|
||||
fpIconColorAnim.setEvaluator(ArgbEvaluator.getInstance());
|
||||
fpIconColorAnim.addUpdateListener(valueAnimator -> {
|
||||
mUdfpsBouncerColor = (int) valueAnimator.getAnimatedValue();
|
||||
updateColor();
|
||||
});
|
||||
}
|
||||
|
||||
mAnimatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 0f, 1f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 0f, 1f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 0f, 1f),
|
||||
fpIconAnim);
|
||||
fpIconColorAnim);
|
||||
mAnimatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
@@ -197,15 +285,11 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
mAnimatorSet.start();
|
||||
}
|
||||
|
||||
private boolean isShadeLocked() {
|
||||
return mStatusBarState == StatusBarState.SHADE_LOCKED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates out the bg protection circle behind the fp icon to unhighlight the icon.
|
||||
*/
|
||||
void animateAwayUdfpsBouncer(@Nullable Runnable onEndAnimation) {
|
||||
if (mBgProtection.getVisibility() == View.GONE) {
|
||||
if (!showingUdfpsBouncer()) {
|
||||
// already hidden
|
||||
return;
|
||||
}
|
||||
@@ -213,17 +297,25 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
if (mAnimatorSet != null) {
|
||||
mAnimatorSet.cancel();
|
||||
}
|
||||
ValueAnimator fpIconAnim;
|
||||
|
||||
ValueAnimator fpIconColorAnim;
|
||||
if (isShadeLocked()) {
|
||||
// fade out
|
||||
fpIconAnim = ObjectAnimator.ofFloat(mFingerprintView, View.ALPHA, 1f, 0f);
|
||||
mUdfpsBouncerColor = mTextColorPrimary;
|
||||
fpIconColorAnim = ValueAnimator.ofInt(255, 0);
|
||||
fpIconColorAnim.addUpdateListener(valueAnimator ->
|
||||
mLockScreenFp.setImageAlpha((int) valueAnimator.getAnimatedValue()));
|
||||
} else {
|
||||
// update icon color
|
||||
fpIconAnim = new ValueAnimator();
|
||||
fpIconAnim.setIntValues(mTextColorPrimary, getColor());
|
||||
fpIconAnim.setEvaluator(new ArgbEvaluator());
|
||||
fpIconAnim.addUpdateListener(valueAnimator -> mFingerprintDrawable.setLockScreenColor(
|
||||
(Integer) valueAnimator.getAnimatedValue()));
|
||||
fpIconColorAnim = new ValueAnimator();
|
||||
fpIconColorAnim.setIntValues(
|
||||
mTextColorPrimary,
|
||||
isUdfpsColorRequested() ? mUdfpsRequestedColor : mWallpaperTextColor);
|
||||
fpIconColorAnim.setEvaluator(ArgbEvaluator.getInstance());
|
||||
fpIconColorAnim.addUpdateListener(valueAnimator -> {
|
||||
mUdfpsBouncerColor = (int) valueAnimator.getAnimatedValue();
|
||||
updateColor();
|
||||
});
|
||||
}
|
||||
|
||||
mAnimatorSet = new AnimatorSet();
|
||||
@@ -231,7 +323,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 1f, 0f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 1f, 0f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 1f, 0f),
|
||||
fpIconAnim);
|
||||
fpIconColorAnim);
|
||||
mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
mAnimatorSet.setDuration(500);
|
||||
|
||||
@@ -244,10 +336,15 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mAnimatorSet.start();
|
||||
}
|
||||
|
||||
boolean isAnimating() {
|
||||
return mAnimatorSet != null && mAnimatorSet.isRunning();
|
||||
}
|
||||
|
||||
private boolean isShadeLocked() {
|
||||
return mStatusBarState == StatusBarState.SHADE_LOCKED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,6 +316,14 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
|
||||
}
|
||||
}
|
||||
|
||||
public void onBiometricError(int msgId, String errString,
|
||||
BiometricSourceType biometricSourceType) {
|
||||
if (biometricSourceType == BiometricSourceType.FACE) {
|
||||
// show udfps hint when face auth fails
|
||||
showHint(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBiometricAuthenticated(int userId,
|
||||
BiometricSourceType biometricSourceType, boolean isStrongBiometric) {
|
||||
if (biometricSourceType == BiometricSourceType.FACE) {
|
||||
|
||||
@@ -22,6 +22,7 @@ private const val MILLIS_PER_MINUTES = 1000 * 60f
|
||||
private const val BURN_IN_PREVENTION_PERIOD_Y = 521f
|
||||
private const val BURN_IN_PREVENTION_PERIOD_X = 83f
|
||||
private const val BURN_IN_PREVENTION_PERIOD_SCALE = 180f
|
||||
private const val BURN_IN_PREVENTION_PERIOD_PROGRESS = 120f
|
||||
|
||||
/**
|
||||
* Returns the translation offset that should be used to avoid burn in at
|
||||
@@ -36,6 +37,15 @@ fun getBurnInOffset(amplitude: Int, xAxis: Boolean): Int {
|
||||
if (xAxis) BURN_IN_PREVENTION_PERIOD_X else BURN_IN_PREVENTION_PERIOD_Y).toInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a progress offset (between 0f and 1.0f) that should be used to avoid burn in at
|
||||
* the current time.
|
||||
*/
|
||||
fun getBurnInProgressOffset(): Float {
|
||||
return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
|
||||
1f, BURN_IN_PREVENTION_PERIOD_PROGRESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value to scale a view in order to avoid burn in.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user