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.android.settings.fingerprint;
18 
19 import android.annotation.Nullable;
20 import android.app.Activity;
21 import android.content.Intent;
22 import android.hardware.fingerprint.FingerprintManager;
23 import android.os.Bundle;
24 import android.os.CancellationSignal;
25 import android.os.Handler;
26 import android.os.UserHandle;
27 
28 import com.android.internal.logging.MetricsProto.MetricsEvent;
29 import com.android.settings.ChooseLockSettingsHelper;
30 import com.android.settings.InstrumentedFragment;
31 
32 /**
33  * Sidecar fragment to handle the state around fingerprint enrollment.
34  */
35 public class FingerprintEnrollSidecar extends InstrumentedFragment {
36 
37     private int mEnrollmentSteps = -1;
38     private int mEnrollmentRemaining = 0;
39     private Listener mListener;
40     private boolean mEnrolling;
41     private CancellationSignal mEnrollmentCancel;
42     private Handler mHandler = new Handler();
43     private byte[] mToken;
44     private boolean mDone;
45     private int mUserId;
46     private FingerprintManager mFingerprintManager;
47 
48     @Override
onCreate(@ullable Bundle savedInstanceState)49     public void onCreate(@Nullable Bundle savedInstanceState) {
50         super.onCreate(savedInstanceState);
51         setRetainInstance(true);
52     }
53 
54     @Override
onAttach(Activity activity)55     public void onAttach(Activity activity) {
56         super.onAttach(activity);
57         mFingerprintManager = activity.getSystemService(FingerprintManager.class);
58         mToken = activity.getIntent().getByteArrayExtra(
59                 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
60         mUserId = activity.getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
61     }
62 
63     @Override
onStart()64     public void onStart() {
65         super.onStart();
66         if (!mEnrolling) {
67             startEnrollment();
68         }
69     }
70 
71     @Override
onStop()72     public void onStop() {
73         super.onStop();
74         if (!getActivity().isChangingConfigurations()) {
75             cancelEnrollment();
76         }
77     }
78 
startEnrollment()79     private void startEnrollment() {
80         mHandler.removeCallbacks(mTimeoutRunnable);
81         mEnrollmentSteps = -1;
82         mEnrollmentCancel = new CancellationSignal();
83         if (mUserId != UserHandle.USER_NULL) {
84             mFingerprintManager.setActiveUser(mUserId);
85         }
86         mFingerprintManager.enroll(mToken, mEnrollmentCancel,
87                 0 /* flags */, mUserId, mEnrollmentCallback);
88         mEnrolling = true;
89     }
90 
cancelEnrollment()91     boolean cancelEnrollment() {
92         mHandler.removeCallbacks(mTimeoutRunnable);
93         if (mEnrolling) {
94             mEnrollmentCancel.cancel();
95             mEnrolling = false;
96             mEnrollmentSteps = -1;
97             return true;
98         }
99         return false;
100     }
101 
setListener(Listener listener)102     public void setListener(Listener listener) {
103         mListener = listener;
104     }
105 
getEnrollmentSteps()106     public int getEnrollmentSteps() {
107         return mEnrollmentSteps;
108     }
109 
getEnrollmentRemaining()110     public int getEnrollmentRemaining() {
111         return mEnrollmentRemaining;
112     }
113 
isDone()114     public boolean isDone() {
115         return mDone;
116     }
117 
118     private FingerprintManager.EnrollmentCallback mEnrollmentCallback
119             = new FingerprintManager.EnrollmentCallback() {
120 
121         @Override
122         public void onEnrollmentProgress(int remaining) {
123             if (mEnrollmentSteps == -1) {
124                 mEnrollmentSteps = remaining;
125             }
126             mEnrollmentRemaining = remaining;
127             mDone = remaining == 0;
128             if (mListener != null) {
129                 mListener.onEnrollmentProgressChange(mEnrollmentSteps, remaining);
130             }
131         }
132 
133         @Override
134         public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
135             if (mListener != null) {
136                 mListener.onEnrollmentHelp(helpString);
137             }
138         }
139 
140         @Override
141         public void onEnrollmentError(int errMsgId, CharSequence errString) {
142             if (mListener != null) {
143                 mListener.onEnrollmentError(errMsgId, errString);
144             }
145             mEnrolling = false;
146         }
147     };
148 
149     private final Runnable mTimeoutRunnable = new Runnable() {
150         @Override
151         public void run() {
152             cancelEnrollment();
153         }
154     };
155 
156     @Override
getMetricsCategory()157     protected int getMetricsCategory() {
158         return MetricsEvent.FINGERPRINT_ENROLL_SIDECAR;
159     }
160 
161     public interface Listener {
onEnrollmentHelp(CharSequence helpString)162         void onEnrollmentHelp(CharSequence helpString);
onEnrollmentError(int errMsgId, CharSequence errString)163         void onEnrollmentError(int errMsgId, CharSequence errString);
onEnrollmentProgressChange(int steps, int remaining)164         void onEnrollmentProgressChange(int steps, int remaining);
165     }
166 
isEnrolling()167     public boolean isEnrolling() {
168         return mEnrolling;
169     }
170 }
171