Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 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 | |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 19 | import android.app.PendingIntent; |
| 20 | import android.content.Intent; |
| 21 | import android.hardware.face.FaceManager; |
| 22 | import android.hardware.fingerprint.FingerprintManager; |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 23 | |
| 24 | import androidx.annotation.NonNull; |
Curtis Belmonte | 5f1d13e | 2021-04-16 15:09:03 -0700 | [diff] [blame] | 25 | import androidx.fragment.app.FragmentActivity; |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 26 | |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 27 | import com.android.internal.annotations.VisibleForTesting; |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 28 | import com.android.settings.password.ChooseLockSettingsHelper; |
| 29 | |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 30 | import java.util.function.Function; |
| 31 | |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 32 | /** |
| 33 | * Helper for {@link BiometricEnrollActivity} when multiple sensors exist on a device. |
| 34 | */ |
| 35 | public class MultiBiometricEnrollHelper { |
| 36 | |
| 37 | private static final String TAG = "MultiBiometricEnrollHelper"; |
| 38 | |
| 39 | private static final int REQUEST_FACE_ENROLL = 3000; |
| 40 | private static final int REQUEST_FINGERPRINT_ENROLL = 3001; |
| 41 | |
| 42 | public static final String EXTRA_ENROLL_AFTER_FACE = "enroll_after_face"; |
Joshua McCloskey | 1dd4f54 | 2022-04-18 19:16:10 +0000 | [diff] [blame] | 43 | public static final String EXTRA_ENROLL_AFTER_FINGERPRINT = "enroll_after_finger"; |
Curtis Belmonte | b61478c | 2021-07-15 16:04:47 -0700 | [diff] [blame] | 44 | public static final String EXTRA_SKIP_PENDING_ENROLL = "skip_pending_enroll"; |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 45 | |
Curtis Belmonte | 5f1d13e | 2021-04-16 15:09:03 -0700 | [diff] [blame] | 46 | @NonNull private final FragmentActivity mActivity; |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 47 | private final long mGkPwHandle; |
| 48 | private final int mUserId; |
| 49 | private final boolean mRequestEnrollFace; |
| 50 | private final boolean mRequestEnrollFingerprint; |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 51 | private final FingerprintManager mFingerprintManager; |
| 52 | private final FaceManager mFaceManager; |
| 53 | private final Intent mFingerprintEnrollIntroductionIntent; |
| 54 | private final Intent mFaceEnrollIntroductionIntent; |
| 55 | private Function<Long, byte[]> mGatekeeperHatSupplier; |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 56 | |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 57 | @VisibleForTesting |
Curtis Belmonte | 5f1d13e | 2021-04-16 15:09:03 -0700 | [diff] [blame] | 58 | MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 59 | boolean enrollFace, boolean enrollFingerprint, long gkPwHandle, |
| 60 | FingerprintManager fingerprintManager, |
| 61 | FaceManager faceManager, Intent fingerprintEnrollIntroductionIntent, |
| 62 | Intent faceEnrollIntroductionIntent, Function<Long, byte[]> gatekeeperHatSupplier) { |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 63 | mActivity = activity; |
| 64 | mUserId = userId; |
| 65 | mGkPwHandle = gkPwHandle; |
| 66 | mRequestEnrollFace = enrollFace; |
| 67 | mRequestEnrollFingerprint = enrollFingerprint; |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 68 | mFingerprintManager = fingerprintManager; |
| 69 | mFaceManager = faceManager; |
| 70 | mFingerprintEnrollIntroductionIntent = fingerprintEnrollIntroductionIntent; |
| 71 | mFaceEnrollIntroductionIntent = faceEnrollIntroductionIntent; |
| 72 | mGatekeeperHatSupplier = gatekeeperHatSupplier; |
| 73 | } |
| 74 | |
| 75 | MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, |
| 76 | boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) { |
| 77 | this(activity, userId, enrollFace, enrollFingerprint, gkPwHandle, |
| 78 | activity.getSystemService(FingerprintManager.class), |
| 79 | activity.getSystemService(FaceManager.class), |
| 80 | BiometricUtils.getFingerprintIntroIntent(activity, activity.getIntent()), |
| 81 | BiometricUtils.getFaceIntroIntent(activity, activity.getIntent()), |
| 82 | (challenge) -> BiometricUtils.requestGatekeeperHat(activity, gkPwHandle, |
| 83 | userId, challenge)); |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | void startNextStep() { |
Joshua McCloskey | 1dd4f54 | 2022-04-18 19:16:10 +0000 | [diff] [blame] | 87 | if (mRequestEnrollFingerprint) { |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 88 | launchFingerprintEnroll(); |
Joshua McCloskey | 1dd4f54 | 2022-04-18 19:16:10 +0000 | [diff] [blame] | 89 | } else if (mRequestEnrollFace) { |
| 90 | launchFaceEnroll(); |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 91 | } else { |
| 92 | mActivity.setResult(BiometricEnrollIntroduction.RESULT_SKIP); |
| 93 | mActivity.finish(); |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | private void launchFaceEnroll() { |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 98 | mFaceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> { |
| 99 | final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); |
| 100 | mFaceEnrollIntroductionIntent.putExtra( |
| 101 | BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); |
| 102 | mFaceEnrollIntroductionIntent.putExtra( |
| 103 | BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); |
| 104 | BiometricUtils.launchEnrollForResult(mActivity, mFaceEnrollIntroductionIntent, |
| 105 | REQUEST_FACE_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 106 | }); |
| 107 | } |
| 108 | |
| 109 | private void launchFingerprintEnroll() { |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 110 | mFingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> { |
| 111 | final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); |
| 112 | mFingerprintEnrollIntroductionIntent.putExtra( |
| 113 | BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); |
| 114 | mFingerprintEnrollIntroductionIntent.putExtra( |
| 115 | BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); |
Joshua McCloskey | 1dd4f54 | 2022-04-18 19:16:10 +0000 | [diff] [blame] | 116 | if (mRequestEnrollFace) { |
| 117 | // Give FingerprintEnroll a pendingIntent pointing to face enrollment, so that it |
| 118 | // can be started when user skips or finishes fingerprint enrollment. |
| 119 | // FLAG_UPDATE_CURRENT ensures it is launched with the most recent values. |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 120 | mFaceEnrollIntroductionIntent.putExtra(Intent.EXTRA_USER_ID, mUserId); |
| 121 | mFaceEnrollIntroductionIntent.putExtra( |
| 122 | ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle); |
Joshua McCloskey | 1dd4f54 | 2022-04-18 19:16:10 +0000 | [diff] [blame] | 123 | final PendingIntent faceAfterFp = PendingIntent.getActivity(mActivity, |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 124 | 0 /* requestCode */, mFaceEnrollIntroductionIntent, |
Joshua McCloskey | 1dd4f54 | 2022-04-18 19:16:10 +0000 | [diff] [blame] | 125 | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 126 | mFingerprintEnrollIntroductionIntent.putExtra(EXTRA_ENROLL_AFTER_FINGERPRINT, |
| 127 | faceAfterFp); |
Diya Bera | a26c2d6 | 2022-11-02 17:48:37 +0000 | [diff] [blame] | 128 | } |
Diya Bera | 1021b58 | 2023-01-12 18:18:09 +0000 | [diff] [blame] | 129 | BiometricUtils.launchEnrollForResult(mActivity, mFingerprintEnrollIntroductionIntent, |
| 130 | REQUEST_FINGERPRINT_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 131 | })); |
| 132 | } |
Kevin Chyn | 87bb772 | 2020-09-09 13:28:28 -0700 | [diff] [blame] | 133 | } |