OSDN Git Service

am fb535a8e: Merge "Refine fingerprint enrollment experience" into mnc-dev
authorJorim Jaggi <jjaggi@google.com>
Thu, 11 Jun 2015 22:48:51 +0000 (22:48 +0000)
committerAndroid Git Automerger <android-git-automerger@android.com>
Thu, 11 Jun 2015 22:48:51 +0000 (22:48 +0000)
* commit 'fb535a8e497d2e4ea068bb99760b11d3a1b6abf5':
  Refine fingerprint enrollment experience
  Fix crash in battery screen

res/drawable-nodpi/fingerprint_indicator.png [deleted file]
res/drawable/fp_illustration_enrollment.xml [new file with mode: 0644]
res/layout-land/fingerprint_enroll_enrolling.xml
res/layout/fingerprint_enroll_enrolling_base.xml
res/layout/fingerprint_enroll_enrolling_content.xml
res/layout/fingerprint_enroll_finish_base.xml
res/values/colors.xml
res/values/dimens.xml
res/values/strings.xml
src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java

diff --git a/res/drawable-nodpi/fingerprint_indicator.png b/res/drawable-nodpi/fingerprint_indicator.png
deleted file mode 100644 (file)
index fc5ef0f..0000000
Binary files a/res/drawable-nodpi/fingerprint_indicator.png and /dev/null differ
diff --git a/res/drawable/fp_illustration_enrollment.xml b/res/drawable/fp_illustration_enrollment.xml
new file mode 100644 (file)
index 0000000..f9b7ed4
--- /dev/null
@@ -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>
index c60888b..4d02c07 100644 (file)
@@ -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>
 
index 37e10ba..21221cf 100644 (file)
@@ -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>
 
index 9fa503b..b3171a3 100644 (file)
     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"
index 981c9f0..1c66103 100644 (file)
@@ -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
index d0ef652..c874970 100644 (file)
@@ -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>
index 5f162b8..c10e83f 100755 (executable)
     <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>
index 9ca45d0..6a61aa0 100644 (file)
     <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>
index 886cdb2..49c5e82 100644 (file)
 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;
@@ -50,6 +53,12 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
     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.
      */
     private static final long ICON_TOUCH_DURATION_UNTIL_DIALOG_SHOWN = 500;
@@ -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