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