Home | History | Annotate | Download | only in fingerprint
      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
     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 
     74     protected int getContentView() {
     75         return R.layout.fingerprint_enroll_find_sensor;
     76     }
     77 
     78     @Override
     79     protected void onStart() {
     80         super.onStart();
     81         if (mAnimation != null) {
     82             mAnimation.startAnimation();
     83         }
     84     }
     85 
     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
    116     protected void onStop() {
    117         super.onStop();
    118         if (mAnimation != null) {
    119             mAnimation.pauseAnimation();
    120         }
    121     }
    122 
    123     @Override
    124     protected void onDestroy() {
    125         super.onDestroy();
    126         if (mAnimation != null) {
    127             mAnimation.stopAnimation();
    128         }
    129     }
    130 
    131     @Override
    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
    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 
    149     protected void onSkipButtonClick() {
    150         setResult(RESULT_SKIP);
    151         finish();
    152     }
    153 
    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
    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 
    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
    231     public int getMetricsCategory() {
    232         return MetricsEvent.FINGERPRINT_FIND_SENSOR;
    233     }
    234 }
    235