• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.example.android.fingerprintdialog;
18 
19 import android.hardware.fingerprint.FingerprintManager;
20 import android.os.CancellationSignal;
21 import android.widget.ImageView;
22 import android.widget.TextView;
23 
24 /**
25  * Small helper class to manage text/icon around fingerprint authentication UI.
26  */
27 public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
28 
29     private static final long ERROR_TIMEOUT_MILLIS = 1600;
30     private static final long SUCCESS_DELAY_MILLIS = 1300;
31 
32     private final FingerprintManager mFingerprintManager;
33     private final ImageView mIcon;
34     private final TextView mErrorTextView;
35     private final Callback mCallback;
36     private CancellationSignal mCancellationSignal;
37 
38     private boolean mSelfCancelled;
39 
40     /**
41      * Constructor for {@link FingerprintUiHelper}.
42      */
FingerprintUiHelper(FingerprintManager fingerprintManager, ImageView icon, TextView errorTextView, Callback callback)43     FingerprintUiHelper(FingerprintManager fingerprintManager,
44             ImageView icon, TextView errorTextView, Callback callback) {
45         mFingerprintManager = fingerprintManager;
46         mIcon = icon;
47         mErrorTextView = errorTextView;
48         mCallback = callback;
49     }
50 
isFingerprintAuthAvailable()51     public boolean isFingerprintAuthAvailable() {
52         // The line below prevents the false positive inspection from Android Studio
53         // noinspection ResourceType
54         return mFingerprintManager.isHardwareDetected()
55                 && mFingerprintManager.hasEnrolledFingerprints();
56     }
57 
startListening(FingerprintManager.CryptoObject cryptoObject)58     public void startListening(FingerprintManager.CryptoObject cryptoObject) {
59         if (!isFingerprintAuthAvailable()) {
60             return;
61         }
62         mCancellationSignal = new CancellationSignal();
63         mSelfCancelled = false;
64         // The line below prevents the false positive inspection from Android Studio
65         // noinspection ResourceType
66         mFingerprintManager
67                 .authenticate(cryptoObject, mCancellationSignal, 0 /* flags */, this, null);
68         mIcon.setImageResource(R.drawable.ic_fp_40px);
69     }
70 
stopListening()71     public void stopListening() {
72         if (mCancellationSignal != null) {
73             mSelfCancelled = true;
74             mCancellationSignal.cancel();
75             mCancellationSignal = null;
76         }
77     }
78 
79     @Override
onAuthenticationError(int errMsgId, CharSequence errString)80     public void onAuthenticationError(int errMsgId, CharSequence errString) {
81         if (!mSelfCancelled) {
82             showError(errString);
83             mIcon.postDelayed(new Runnable() {
84                 @Override
85                 public void run() {
86                     mCallback.onError();
87                 }
88             }, ERROR_TIMEOUT_MILLIS);
89         }
90     }
91 
92     @Override
onAuthenticationHelp(int helpMsgId, CharSequence helpString)93     public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
94         showError(helpString);
95     }
96 
97     @Override
onAuthenticationFailed()98     public void onAuthenticationFailed() {
99         showError(mIcon.getResources().getString(
100                 R.string.fingerprint_not_recognized));
101     }
102 
103     @Override
onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result)104     public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
105         mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
106         mIcon.setImageResource(R.drawable.ic_fingerprint_success);
107         mErrorTextView.setTextColor(
108                 mErrorTextView.getResources().getColor(R.color.success_color, null));
109         mErrorTextView.setText(
110                 mErrorTextView.getResources().getString(R.string.fingerprint_success));
111         mIcon.postDelayed(new Runnable() {
112             @Override
113             public void run() {
114                 mCallback.onAuthenticated();
115             }
116         }, SUCCESS_DELAY_MILLIS);
117     }
118 
showError(CharSequence error)119     private void showError(CharSequence error) {
120         mIcon.setImageResource(R.drawable.ic_fingerprint_error);
121         mErrorTextView.setText(error);
122         mErrorTextView.setTextColor(
123                 mErrorTextView.getResources().getColor(R.color.warning_color, null));
124         mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
125         mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT_MILLIS);
126     }
127 
128     private Runnable mResetErrorTextRunnable = new Runnable() {
129         @Override
130         public void run() {
131             mErrorTextView.setTextColor(
132                     mErrorTextView.getResources().getColor(R.color.hint_color, null));
133             mErrorTextView.setText(
134                     mErrorTextView.getResources().getString(R.string.fingerprint_hint));
135             mIcon.setImageResource(R.drawable.ic_fp_40px);
136         }
137     };
138 
139     public interface Callback {
140 
onAuthenticated()141         void onAuthenticated();
142 
onError()143         void onError();
144     }
145 }
146