Refine fingerprint enrollment experience
- Flash fingerprint graphic when enrollment progresses - Show hint message when not progressing for a few seconds - Make sure animation is always working Bug: 21617091 Bug: 21644138 Change-Id: Ic54c10a655e6da914f960cee20f0066b46d87325
This commit is contained in:
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
36
res/drawable/fp_illustration_enrollment.xml
Normal file
36
res/drawable/fp_illustration_enrollment.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
Copyright (C) 2015 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="88.0dp"
|
||||
android:height="88.0dp"
|
||||
android:viewportWidth="88.0"
|
||||
android:viewportHeight="88.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M67.74,11.59c-0.41,0.0 -0.82,-0.1 -1.2,-0.31c-7.44,-4.06 -15.0,-6.04 -23.11,-6.04c-7.92,0.0 -14.67,1.85 -21.88,6.01c-1.2,0.69 -2.73,0.28 -3.42,-0.92s-0.28,-2.72 0.92,-3.41c7.9,-4.55 15.65,-6.68 24.37,-6.68c8.97,0.0 17.32,2.17 25.51,6.65c1.21,0.66 1.66,2.18 1.0,3.39C69.48,11.12 68.62,11.59 67.74,11.59z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M9.25,34.74c-0.48,0.0 -0.96,-0.14 -1.39,-0.42c-1.15,-0.77 -1.45,-2.32 -0.68,-3.47c4.09,-6.09 9.3,-10.89 15.49,-14.27c6.52,-3.55 13.91,-5.43 21.38,-5.43c7.44,0.0 14.8,1.86 21.3,5.39c6.17,3.35 11.38,8.12 15.47,14.16c0.77,1.14 0.47,2.7 -0.67,3.47c-1.14,0.77 -2.7,0.47 -3.47,-0.67c-3.64,-5.38 -8.25,-9.61 -13.71,-12.57c-5.77,-3.13 -12.31,-4.78 -18.92,-4.78c-6.63,0.0 -13.2,1.67 -18.98,4.82c-5.48,2.99 -10.1,7.25 -13.73,12.66C10.85,34.35 10.06,34.74 9.25,34.74z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M34.76,86.82c-0.67,0.0 -1.33,-0.27 -1.82,-0.79c-3.49,-3.72 -5.51,-6.25 -8.26,-11.45c-2.84,-5.35 -4.34,-11.88 -4.34,-18.86c0.0,-13.02 10.59,-23.61 23.61,-23.61c13.02,0.0 23.61,10.59 23.61,23.61c0.0,1.38 -1.12,2.5 -2.5,2.5s-2.5,-1.12 -2.5,-2.5c0.0,-10.26 -8.35,-18.61 -18.61,-18.61c-10.26,0.0 -18.61,8.35 -18.61,18.61c0.0,6.17 1.3,11.89 3.76,16.52c2.62,4.94 4.37,7.04 7.49,10.37c0.94,1.01 0.89,2.59 -0.11,3.53C35.99,86.6 35.38,86.82 34.76,86.82z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M64.28,78.84c-4.99,0.0 -9.35,-1.32 -12.98,-3.92c-6.17,-4.43 -9.86,-11.6 -9.86,-19.19c0.0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5c0.0,5.98 2.91,11.64 7.77,15.13c2.8,2.01 6.09,2.98 10.06,2.98c0.97,0.0 2.57,-0.11 4.17,-0.4c1.36,-0.25 2.66,0.64 2.92,2.0c0.25,1.36 -0.64,2.66 -2.0,2.92C66.93,78.8 64.86,78.84 64.28,78.84z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M55.92,87.75c-0.23,0.0 -0.46,-0.03 -0.7,-0.1c-6.6,-1.91 -10.92,-4.49 -15.4,-9.2c-5.76,-6.06 -8.94,-14.13 -8.94,-22.72c0.0,-7.2 5.86,-13.05 13.05,-13.05c7.2,0.0 13.05,5.86 13.05,13.05c0.0,4.44 3.61,8.05 8.05,8.05s8.05,-3.61 8.05,-8.05c0.0,-16.08 -13.08,-29.16 -29.16,-29.16c-11.43,0.0 -21.86,6.73 -26.58,17.15c-1.57,3.48 -2.37,7.52 -2.37,12.01c0.0,3.36 0.28,8.62 2.71,15.49c0.46,1.3 -0.22,2.73 -1.52,3.19c-1.3,0.46 -2.73,-0.22 -3.19,-1.52c-2.02,-5.7 -3.0,-11.31 -3.0,-17.16c0.0,-5.21 0.95,-9.94 2.82,-14.07c5.52,-12.2 17.74,-20.09 31.13,-20.09c18.83,0.0 34.16,15.32 34.16,34.16c0.0,7.2 -5.86,13.05 -13.05,13.05S52.0,62.92 52.0,55.73c0.0,-4.44 -3.61,-8.05 -8.05,-8.05s-8.05,3.61 -8.05,8.05c0.0,7.3 2.69,14.15 7.56,19.28c3.86,4.06 7.43,6.18 13.17,7.84c1.33,0.38 2.09,1.77 1.71,3.1C58.01,87.04 57.01,87.75 55.92,87.75z"/>
|
||||
</vector>
|
@@ -69,7 +69,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_gravity="center_horizontal|bottom"/>
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
@@ -66,7 +66,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@@ -22,18 +22,14 @@
|
||||
android:layout_marginTop="36dp"
|
||||
android:layout_gravity="center_horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="88dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/fingerprint_indicator" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_animator"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="88dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/enrollment_fingerprint_isolated_animation" />
|
||||
android:background="@drawable/fp_illustration_enrollment"
|
||||
android:backgroundTint="@color/fingerprint_indicator_background_resting"
|
||||
android:src="@drawable/enrollment_fingerprint_isolated_animation"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/fingerprint_progress_bar"
|
||||
|
@@ -63,7 +63,6 @@
|
||||
android:id="@+id/add_another_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/fingerprint_enroll_button_add" />
|
||||
|
||||
<Button
|
||||
|
@@ -66,6 +66,8 @@
|
||||
<color name="fingerprint_message_color">#de000000</color>
|
||||
<color name="fingerprint_progress_ring">?android:attr/colorAccent</color>
|
||||
<color name="fingerprint_progress_ring_bg">#20000000</color>
|
||||
<color name="fingerprint_indicator_background_resting">#12000000</color>
|
||||
<color name="fingerprint_indicator_background_activated">#80009688</color>
|
||||
|
||||
<color name="running_processes_system_ram">#ff384248</color>
|
||||
<color name="running_processes_apps_ram">#ff009587</color>
|
||||
|
@@ -231,6 +231,8 @@
|
||||
<dimen name="fingerprint_find_sensor_graphic_size">200dp</dimen>
|
||||
<item name="fingerprint_illustration_aspect_ratio" format="float" type="dimen">2.6</item>
|
||||
<dimen name="fingerprint_decor_padding_top">0dp</dimen>
|
||||
<dimen name="fingerprint_error_text_appear_distance">16dp</dimen>
|
||||
<dimen name="fingerprint_error_text_disappear_distance">-8dp</dimen>
|
||||
|
||||
<dimen name="confirm_credentials_security_method_margin">48dp</dimen>
|
||||
<dimen name="fab_size">56dp</dimen>
|
||||
|
@@ -806,6 +806,8 @@
|
||||
<string name="security_settings_fingerprint_enroll_disclaimer">In addition to unlocking your phone, you can also use your fingerprint to authorize purchases and app access. <annotation id="url">Learn more</annotation></string>
|
||||
<!-- Text shown in fingerprint settings explaining what the fingerprint can be used for in the case unlocking is disabled [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_disclaimer_lockscreen_disabled">Screen lock option disabled. You can still use your fingerprint to authorize purchases and app access. <annotation id="url">Learn more</annotation></string>
|
||||
<!-- Text shown in fingerprint enroll when we didn't observe progress for a few seconds. [CHAR LIMIT=100] -->
|
||||
<string name="security_settings_fingerprint_enroll_lift_touch_again">Lift finger, then touch sensor again</string>
|
||||
|
||||
<!-- Title of the preferences category for preference items to control encryption -->
|
||||
<string name="crypt_keeper_settings_title">Encryption</string>
|
||||
|
@@ -17,12 +17,15 @@
|
||||
package com.android.settings.fingerprint;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Animatable2;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -49,6 +52,12 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
private static final int PROGRESS_BAR_MAX = 10000;
|
||||
private static final int FINISH_DELAY = 250;
|
||||
|
||||
/**
|
||||
* If we don't see progress during this time, we show an error message to remind the user that
|
||||
* he needs to lift the finger and touch again.
|
||||
*/
|
||||
private static final int HINT_TIMEOUT_DURATION = 2500;
|
||||
|
||||
/**
|
||||
* How long the user needs to touch the icon until we show the dialog.
|
||||
*/
|
||||
@@ -67,10 +76,15 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
private TextView mRepeatMessage;
|
||||
private TextView mErrorText;
|
||||
private Interpolator mFastOutSlowInInterpolator;
|
||||
private Interpolator mLinearOutSlowInInterpolator;
|
||||
private Interpolator mFastOutLinearInInterpolator;
|
||||
private int mIconTouchCount;
|
||||
private FingerprintEnrollSidecar mSidecar;
|
||||
private boolean mAnimationCancelled;
|
||||
private AnimatedVectorDrawable mIconAnimationDrawable;
|
||||
private int mIndicatorBackgroundRestingColor;
|
||||
private int mIndicatorBackgroundActivatedColor;
|
||||
private boolean mRestoring;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -86,6 +100,10 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
mIconAnimationDrawable.registerAnimationCallback(mIconAnimationCallback);
|
||||
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
|
||||
this, android.R.interpolator.fast_out_slow_in);
|
||||
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
|
||||
this, android.R.interpolator.linear_out_slow_in);
|
||||
mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(
|
||||
this, android.R.interpolator.fast_out_linear_in);
|
||||
mFingerprintAnimator.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
@@ -104,6 +122,11 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mIndicatorBackgroundRestingColor
|
||||
= getColor(R.color.fingerprint_indicator_background_resting);
|
||||
mIndicatorBackgroundActivatedColor
|
||||
= getColor(R.color.fingerprint_indicator_background_activated);
|
||||
mRestoring = savedInstanceState != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,6 +140,9 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
mSidecar.setListener(this);
|
||||
updateProgress(false /* animate */);
|
||||
updateDescription();
|
||||
if (mRestoring) {
|
||||
startIconAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,6 +184,34 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
mProgressAnim = anim;
|
||||
}
|
||||
|
||||
private void animateFlash() {
|
||||
ValueAnimator anim = ValueAnimator.ofArgb(mIndicatorBackgroundRestingColor,
|
||||
mIndicatorBackgroundActivatedColor);
|
||||
final ValueAnimator.AnimatorUpdateListener listener =
|
||||
new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
mFingerprintAnimator.setBackgroundTintList(ColorStateList.valueOf(
|
||||
(Integer) animation.getAnimatedValue()));
|
||||
}
|
||||
};
|
||||
anim.addUpdateListener(listener);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
ValueAnimator anim = ValueAnimator.ofArgb(mIndicatorBackgroundActivatedColor,
|
||||
mIndicatorBackgroundRestingColor);
|
||||
anim.addUpdateListener(listener);
|
||||
anim.setDuration(300);
|
||||
anim.setInterpolator(mLinearOutSlowInInterpolator);
|
||||
anim.start();
|
||||
}
|
||||
});
|
||||
anim.setInterpolator(mFastOutSlowInInterpolator);
|
||||
anim.setDuration(300);
|
||||
anim.start();
|
||||
}
|
||||
|
||||
private void launchFinish(byte[] token) {
|
||||
Intent intent = new Intent();
|
||||
intent.setClassName("com.android.settings", FingerprintEnrollFinish.class.getName());
|
||||
@@ -187,7 +241,7 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
|
||||
@Override
|
||||
public void onEnrollmentError(CharSequence errString) {
|
||||
mErrorText.setText(errString);
|
||||
showError(errString);
|
||||
stopIconAnimation();
|
||||
}
|
||||
|
||||
@@ -195,7 +249,10 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
public void onEnrollmentProgressChange(int steps, int remaining) {
|
||||
updateProgress(true /* animate */);
|
||||
updateDescription();
|
||||
mErrorText.setText("");
|
||||
clearError();
|
||||
animateFlash();
|
||||
mErrorText.removeCallbacks(mTouchAgainRunnable);
|
||||
mErrorText.postDelayed(mTouchAgainRunnable, HINT_TIMEOUT_DURATION);
|
||||
}
|
||||
|
||||
private void updateProgress(boolean animate) {
|
||||
@@ -221,6 +278,44 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
new IconTouchDialog().show(getFragmentManager(), null /* tag */);
|
||||
}
|
||||
|
||||
private void showError(CharSequence error) {
|
||||
mErrorText.setText(error);
|
||||
if (mErrorText.getVisibility() == View.INVISIBLE) {
|
||||
mErrorText.setVisibility(View.VISIBLE);
|
||||
mErrorText.setTranslationY(getResources().getDimensionPixelSize(
|
||||
R.dimen.fingerprint_error_text_appear_distance));
|
||||
mErrorText.setAlpha(0f);
|
||||
mErrorText.animate()
|
||||
.alpha(1f)
|
||||
.translationY(0f)
|
||||
.setDuration(200)
|
||||
.setInterpolator(mLinearOutSlowInInterpolator)
|
||||
.start();
|
||||
} else {
|
||||
mErrorText.animate().cancel();
|
||||
mErrorText.setAlpha(1f);
|
||||
mErrorText.setTranslationY(0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearError() {
|
||||
if (mErrorText.getVisibility() == View.VISIBLE) {
|
||||
mErrorText.animate()
|
||||
.alpha(0f)
|
||||
.translationY(getResources().getDimensionPixelSize(
|
||||
R.dimen.fingerprint_error_text_disappear_distance))
|
||||
.setDuration(100)
|
||||
.setInterpolator(mFastOutLinearInInterpolator)
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mErrorText.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
private final Animator.AnimatorListener mProgressAnimationListener
|
||||
= new Animator.AnimatorListener() {
|
||||
|
||||
@@ -274,6 +369,13 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mTouchAgainRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showError(getString(R.string.security_settings_fingerprint_enroll_lift_touch_again));
|
||||
}
|
||||
};
|
||||
|
||||
private static class IconTouchDialog extends DialogFragment {
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user