• 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.android.settings.fingerprint;
18 
19 import android.content.Intent;
20 import android.hardware.fingerprint.FingerprintManager;
21 import android.os.Bundle;
22 import android.os.UserHandle;
23 import android.support.annotation.Nullable;
24 import android.view.View;
25 import android.widget.Button;
26 
27 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
28 import com.android.settings.R;
29 import com.android.settings.Utils;
30 import com.android.settings.fingerprint.FingerprintEnrollSidecar.Listener;
31 import com.android.settings.password.ChooseLockSettingsHelper;
32 
33 /**
34  * Activity explaining the fingerprint sensor location for fingerprint enrollment.
35  */
36 public class FingerprintEnrollFindSensor extends FingerprintEnrollBase {
37 
38     private static final int CONFIRM_REQUEST = 1;
39     private static final int ENROLLING = 2;
40     public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock";
41 
42     @Nullable
43     private FingerprintFindSensorAnimation mAnimation;
44     private boolean mLaunchedConfirmLock;
45     private FingerprintEnrollSidecar mSidecar;
46     private boolean mNextClicked;
47 
48     @Override
onCreate(Bundle savedInstanceState)49     protected void onCreate(Bundle savedInstanceState) {
50         super.onCreate(savedInstanceState);
51         setContentView(getContentView());
52         Button skipButton = findViewById(R.id.skip_button);
53         skipButton.setOnClickListener(this);
54 
55         setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
56         if (savedInstanceState != null) {
57             mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM);
58             mToken = savedInstanceState.getByteArray(
59                     ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
60         }
61         if (mToken == null && !mLaunchedConfirmLock) {
62             launchConfirmLock();
63         } else if (mToken != null) {
64             startLookingForFingerprint(); // already confirmed, so start looking for fingerprint
65         }
66         View animationView = findViewById(R.id.fingerprint_sensor_location_animation);
67         if (animationView instanceof FingerprintFindSensorAnimation) {
68             mAnimation = (FingerprintFindSensorAnimation) animationView;
69         } else {
70             mAnimation = null;
71         }
72     }
73 
getContentView()74     protected int getContentView() {
75         return R.layout.fingerprint_enroll_find_sensor;
76     }
77 
78     @Override
onStart()79     protected void onStart() {
80         super.onStart();
81         if (mAnimation != null) {
82             mAnimation.startAnimation();
83         }
84     }
85 
startLookingForFingerprint()86     private void startLookingForFingerprint() {
87         mSidecar = (FingerprintEnrollSidecar) getFragmentManager().findFragmentByTag(
88                 FingerprintEnrollEnrolling.TAG_SIDECAR);
89         if (mSidecar == null) {
90             mSidecar = new FingerprintEnrollSidecar();
91             getFragmentManager().beginTransaction()
92                     .add(mSidecar, FingerprintEnrollEnrolling.TAG_SIDECAR).commit();
93         }
94         mSidecar.setListener(new Listener() {
95             @Override
96             public void onEnrollmentProgressChange(int steps, int remaining) {
97                 mNextClicked = true;
98                 proceedToEnrolling(true /* cancelEnrollment */);
99             }
100 
101             @Override
102             public void onEnrollmentHelp(CharSequence helpString) {
103             }
104 
105             @Override
106             public void onEnrollmentError(int errMsgId, CharSequence errString) {
107                 if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
108                     mNextClicked = false;
109                     proceedToEnrolling(false /* cancelEnrollment */);
110                 }
111             }
112         });
113     }
114 
115     @Override
onStop()116     protected void onStop() {
117         super.onStop();
118         if (mAnimation != null) {
119             mAnimation.pauseAnimation();
120         }
121     }
122 
123     @Override
onDestroy()124     protected void onDestroy() {
125         super.onDestroy();
126         if (mAnimation != null) {
127             mAnimation.stopAnimation();
128         }
129     }
130 
131     @Override
onSaveInstanceState(Bundle outState)132     public void onSaveInstanceState(Bundle outState) {
133         super.onSaveInstanceState(outState);
134         outState.putBoolean(EXTRA_KEY_LAUNCHED_CONFIRM, mLaunchedConfirmLock);
135         outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
136     }
137 
138     @Override
onClick(View v)139     public void onClick(View v) {
140         switch (v.getId()) {
141             case R.id.skip_button:
142                 onSkipButtonClick();
143                 break;
144             default:
145                 super.onClick(v);
146         }
147     }
148 
onSkipButtonClick()149     protected void onSkipButtonClick() {
150         setResult(RESULT_SKIP);
151         finish();
152     }
153 
proceedToEnrolling(boolean cancelEnrollment)154     private void proceedToEnrolling(boolean cancelEnrollment) {
155         if (mSidecar != null) {
156             if (cancelEnrollment) {
157                 if (mSidecar.cancelEnrollment()) {
158                     // Enrollment cancel requested. When the cancellation is successful,
159                     // onEnrollmentError will be called with FINGERPRINT_ERROR_CANCELED, calling
160                     // this again.
161                     return;
162                 }
163             }
164             getFragmentManager().beginTransaction().remove(mSidecar).commitAllowingStateLoss();
165             mSidecar = null;
166             startActivityForResult(getEnrollingIntent(), ENROLLING);
167         }
168     }
169 
170     @Override
onActivityResult(int requestCode, int resultCode, Intent data)171     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
172         if (requestCode == CONFIRM_REQUEST) {
173             if (resultCode == RESULT_OK) {
174                 mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
175                 overridePendingTransition(R.anim.suw_slide_next_in, R.anim.suw_slide_next_out);
176                 getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
177                 startLookingForFingerprint();
178             } else {
179                 finish();
180             }
181         } else if (requestCode == ENROLLING) {
182             if (resultCode == RESULT_FINISHED) {
183                 setResult(RESULT_FINISHED);
184                 finish();
185             } else if (resultCode == RESULT_SKIP) {
186                 setResult(RESULT_SKIP);
187                 finish();
188             } else if (resultCode == RESULT_TIMEOUT) {
189                 setResult(RESULT_TIMEOUT);
190                 finish();
191             } else {
192                 FingerprintManager fpm = Utils.getFingerprintManagerOrNull(this);
193                 int enrolled = fpm.getEnrolledFingerprints().size();
194                 int max = getResources().getInteger(
195                         com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
196                 if (enrolled >= max) {
197                     finish();
198                 } else {
199                     // We came back from enrolling but it wasn't completed, start again.
200                     startLookingForFingerprint();
201                 }
202             }
203         } else {
204             super.onActivityResult(requestCode, resultCode, data);
205         }
206     }
207 
launchConfirmLock()208     private void launchConfirmLock() {
209         long challenge = Utils.getFingerprintManagerOrNull(this).preEnroll();
210         ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this);
211         boolean launchedConfirmationActivity = false;
212         if (mUserId == UserHandle.USER_NULL) {
213             launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST,
214                 getString(R.string.security_settings_fingerprint_preference_title),
215                 null, null, challenge);
216         } else {
217             launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST,
218                     getString(R.string.security_settings_fingerprint_preference_title),
219                     null, null, challenge, mUserId);
220         }
221         if (!launchedConfirmationActivity) {
222             // This shouldn't happen, as we should only end up at this step if a lock thingy is
223             // already set.
224             finish();
225         } else {
226             mLaunchedConfirmLock = true;
227         }
228     }
229 
230     @Override
getMetricsCategory()231     public int getMetricsCategory() {
232         return MetricsEvent.FINGERPRINT_FIND_SENSOR;
233     }
234 }
235