• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.biometrics;
18 
19 import android.app.PendingIntent;
20 import android.content.Intent;
21 import android.hardware.face.FaceManager;
22 import android.hardware.fingerprint.FingerprintManager;
23 
24 import androidx.annotation.NonNull;
25 import androidx.fragment.app.FragmentActivity;
26 
27 import com.android.settings.password.ChooseLockSettingsHelper;
28 
29 /**
30  * Helper for {@link BiometricEnrollActivity} when multiple sensors exist on a device.
31  */
32 public class MultiBiometricEnrollHelper {
33 
34     private static final String TAG = "MultiBiometricEnrollHelper";
35 
36     private static final int REQUEST_FACE_ENROLL = 3000;
37     private static final int REQUEST_FINGERPRINT_ENROLL = 3001;
38 
39     public static final String EXTRA_ENROLL_AFTER_FACE = "enroll_after_face";
40     public static final String EXTRA_SKIP_PENDING_ENROLL = "skip_pending_enroll";
41 
42     @NonNull private final FragmentActivity mActivity;
43     private final long mGkPwHandle;
44     private final int mUserId;
45     private final boolean mRequestEnrollFace;
46     private final boolean mRequestEnrollFingerprint;
47 
MultiBiometricEnrollHelper(@onNull FragmentActivity activity, int userId, boolean enrollFace, boolean enrollFingerprint, long gkPwHandle)48     MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId,
49             boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) {
50         mActivity = activity;
51         mUserId = userId;
52         mGkPwHandle = gkPwHandle;
53         mRequestEnrollFace = enrollFace;
54         mRequestEnrollFingerprint = enrollFingerprint;
55     }
56 
startNextStep()57     void startNextStep() {
58         if (mRequestEnrollFace) {
59             launchFaceEnroll();
60         } else if (mRequestEnrollFingerprint) {
61             launchFingerprintEnroll();
62         } else {
63             mActivity.setResult(BiometricEnrollIntroduction.RESULT_SKIP);
64             mActivity.finish();
65         }
66     }
67 
launchFaceEnroll()68     private void launchFaceEnroll() {
69         final FaceManager faceManager = mActivity.getSystemService(FaceManager.class);
70         faceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> {
71             final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity,
72                     mGkPwHandle, mUserId, challenge);
73             final Intent faceIntent = BiometricUtils.getFaceIntroIntent(mActivity,
74                     mActivity.getIntent());
75             faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId);
76             faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge);
77 
78             if (mRequestEnrollFingerprint) {
79                 // Give FaceEnroll a pendingIntent pointing to fingerprint enrollment, so that it
80                 // can be started when user skips or finishes face enrollment. FLAG_UPDATE_CURRENT
81                 // ensures it is launched with the most recent values.
82                 final Intent fpIntent = BiometricUtils.getFingerprintIntroIntent(mActivity,
83                         mActivity.getIntent());
84                 fpIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle);
85                 final PendingIntent fpAfterFaceIntent = PendingIntent.getActivity(mActivity,
86                         0 /* requestCode */, fpIntent,
87                         PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
88                 faceIntent.putExtra(EXTRA_ENROLL_AFTER_FACE, fpAfterFaceIntent);
89             }
90 
91             BiometricUtils.launchEnrollForResult(mActivity, faceIntent, REQUEST_FACE_ENROLL,
92                     hardwareAuthToken, mGkPwHandle, mUserId);
93         });
94     }
95 
launchFingerprintEnroll()96     private void launchFingerprintEnroll() {
97         final FingerprintManager fingerprintManager = mActivity
98                 .getSystemService(FingerprintManager.class);
99         fingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> {
100             final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity,
101                     mGkPwHandle, mUserId, challenge);
102             final Intent intent = BiometricUtils.getFingerprintIntroIntent(mActivity,
103                     mActivity.getIntent());
104             intent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId);
105             intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge);
106             BiometricUtils.launchEnrollForResult(mActivity, intent, REQUEST_FINGERPRINT_ENROLL,
107                     hardwareAuthToken, mGkPwHandle, mUserId);
108         }));
109     }
110 }
111