1 /*
2  * Copyright (C) 2022 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.fingerprint;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.hardware.fingerprint.Fingerprint;
22 import android.hardware.fingerprint.FingerprintEnrollOptions;
23 import android.hardware.fingerprint.FingerprintManager;
24 import android.os.CancellationSignal;
25 
26 import androidx.annotation.Nullable;
27 
28 import com.android.settings.Utils;
29 import com.android.settings.biometrics.BiometricUtils;
30 import com.android.settings.safetycenter.BiometricsSafetySource;
31 
32 /**
33  * Responsible for making {@link FingerprintManager#enroll} and {@link FingerprintManager#remove}
34  * calls and thus updating the fingerprint setting.
35  */
36 public class FingerprintUpdater {
37 
38     private final Context mContext;
39     private final FingerprintManager mFingerprintManager;
40 
FingerprintUpdater(Context context)41     public FingerprintUpdater(Context context) {
42         mContext = context;
43         mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
44     }
45 
FingerprintUpdater(Context context, FingerprintManager fingerprintManager)46     public FingerprintUpdater(Context context, FingerprintManager fingerprintManager) {
47         mContext = context;
48         mFingerprintManager = fingerprintManager;
49     }
50 
51     /** Wrapper around the {@link FingerprintManager#enroll} method. */
enroll(byte [] hardwareAuthToken, CancellationSignal cancel, int userId, FingerprintManager.EnrollmentCallback callback, @FingerprintManager.EnrollReason int enrollReason, Intent intent)52     public void enroll(byte [] hardwareAuthToken, CancellationSignal cancel, int userId,
53             FingerprintManager.EnrollmentCallback callback,
54             @FingerprintManager.EnrollReason int enrollReason, Intent intent) {
55         mFingerprintManager.enroll(hardwareAuthToken, cancel, userId,
56                 new NotifyingEnrollmentCallback(mContext, callback), enrollReason,
57                 toFingerprintEnrollOptions(intent));
58     }
59 
60     /** Wrapper around the {@link FingerprintManager#remove} method. */
remove(Fingerprint fp, int userId, FingerprintManager.RemovalCallback callback)61     public void remove(Fingerprint fp, int userId, FingerprintManager.RemovalCallback callback) {
62         mFingerprintManager.remove(fp, userId, new NotifyingRemovalCallback(mContext, callback));
63     }
64 
65     /**
66      * Decorator of the {@link FingerprintManager.EnrollmentCallback} class that notifies other
67      * interested parties that a fingerprint setting has changed.
68      */
69     private static class NotifyingEnrollmentCallback
70             extends FingerprintManager.EnrollmentCallback {
71 
72         private final Context mContext;
73         private final FingerprintManager.EnrollmentCallback mCallback;
74 
NotifyingEnrollmentCallback(Context context, FingerprintManager.EnrollmentCallback callback)75         NotifyingEnrollmentCallback(Context context,
76                 FingerprintManager.EnrollmentCallback callback) {
77             mContext = context;
78             mCallback = callback;
79         }
80 
81         @Override
onEnrollmentError(int errMsgId, CharSequence errString)82         public void onEnrollmentError(int errMsgId, CharSequence errString) {
83             mCallback.onEnrollmentError(errMsgId, errString);
84         }
85 
86         @Override
onEnrollmentHelp(int helpMsgId, CharSequence helpString)87         public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
88             mCallback.onEnrollmentHelp(helpMsgId, helpString);
89         }
90 
91         @Override
onEnrollmentProgress(int remaining)92         public void onEnrollmentProgress(int remaining) {
93             mCallback.onEnrollmentProgress(remaining);
94             if (remaining == 0) {
95                 BiometricsSafetySource.onBiometricsChanged(mContext); // biometrics data changed
96             }
97         }
98 
99         @Override
onAcquired(boolean isAcquiredGood)100         public void onAcquired(boolean isAcquiredGood) {
101             mCallback.onAcquired(isAcquiredGood);
102         }
103 
104         @Override
onUdfpsPointerDown(int sensorId)105         public void onUdfpsPointerDown(int sensorId) {
106             mCallback.onUdfpsPointerDown(sensorId);
107         }
108 
109         @Override
onUdfpsPointerUp(int sensorId)110         public void onUdfpsPointerUp(int sensorId) {
111             mCallback.onUdfpsPointerUp(sensorId);
112         }
113 
114         @Override
onUdfpsOverlayShown()115         public void onUdfpsOverlayShown() {
116             mCallback.onUdfpsOverlayShown();
117         }
118     }
119 
120     /**
121      * Decorator of the {@link FingerprintManager.RemovalCallback} class that notifies other
122      * interested parties that a fingerprint setting has changed.
123      */
124     private static class NotifyingRemovalCallback extends FingerprintManager.RemovalCallback {
125 
126         private final Context mContext;
127         private final FingerprintManager.RemovalCallback mCallback;
128 
NotifyingRemovalCallback(Context context, FingerprintManager.RemovalCallback callback)129         NotifyingRemovalCallback(Context context, FingerprintManager.RemovalCallback callback) {
130             mContext = context;
131             mCallback = callback;
132         }
133 
134         @Override
onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString)135         public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) {
136             mCallback.onRemovalError(fp, errMsgId, errString);
137         }
138 
139         @Override
onRemovalSucceeded(@ullable Fingerprint fp, int remaining)140         public void onRemovalSucceeded(@Nullable Fingerprint fp, int remaining) {
141             mCallback.onRemovalSucceeded(fp, remaining);
142             BiometricsSafetySource.onBiometricsChanged(mContext); // biometrics data changed
143         }
144     }
145 
toFingerprintEnrollOptions(Intent intent)146     private FingerprintEnrollOptions toFingerprintEnrollOptions(Intent intent) {
147         final int reason = intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1);
148         final FingerprintEnrollOptions.Builder builder = new FingerprintEnrollOptions.Builder();
149         builder.setEnrollReason(FingerprintEnrollOptions.ENROLL_REASON_UNKNOWN);
150         if (reason != -1) {
151             builder.setEnrollReason(reason);
152         }
153         return builder.build();
154     }
155 }
156