• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 android.hardware.fingerprint;
18 
19 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
20 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
21 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
22 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR_BASE;
23 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
24 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR_BASE;
25 import static android.hardware.fingerprint.FingerprintManager.getAcquiredString;
26 import static android.hardware.fingerprint.FingerprintManager.getErrorString;
27 
28 import android.annotation.IntDef;
29 import android.content.Context;
30 import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
31 import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
32 import android.hardware.fingerprint.FingerprintManager.CryptoObject;
33 import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
34 import android.hardware.fingerprint.FingerprintManager.FingerprintDetectionCallback;
35 import android.hardware.fingerprint.FingerprintManager.GenerateChallengeCallback;
36 import android.hardware.fingerprint.FingerprintManager.RemovalCallback;
37 import android.util.Slog;
38 
39 import androidx.annotation.NonNull;
40 import androidx.annotation.Nullable;
41 
42 /**
43  * Encapsulates callbacks and client specific information for each fingerprint related request.
44  * @hide
45  */
46 public class FingerprintCallback {
47     private static final String TAG = "FingerprintCallback";
48     public static final int REMOVE_SINGLE = 1;
49     public static final int REMOVE_ALL = 2;
50     @IntDef({REMOVE_SINGLE, REMOVE_ALL})
51     public @interface RemoveRequest {}
52     @Nullable
53     private AuthenticationCallback mAuthenticationCallback;
54     @Nullable
55     private EnrollmentCallback mEnrollmentCallback;
56     @Nullable
57     private RemovalCallback mRemovalCallback;
58     @Nullable
59     private GenerateChallengeCallback mGenerateChallengeCallback;
60     @Nullable
61     private FingerprintDetectionCallback mFingerprintDetectionCallback;
62     @Nullable
63     private CryptoObject mCryptoObject;
64     @Nullable
65     private @RemoveRequest int mRemoveRequest;
66     @Nullable
67     private Fingerprint mRemoveFingerprint;
68 
69     /**
70      * Construction for fingerprint authentication client callback.
71      */
FingerprintCallback(@onNull AuthenticationCallback authenticationCallback, @Nullable CryptoObject cryptoObject)72     FingerprintCallback(@NonNull AuthenticationCallback authenticationCallback,
73             @Nullable CryptoObject cryptoObject) {
74         mAuthenticationCallback = authenticationCallback;
75         mCryptoObject = cryptoObject;
76     }
77 
78     /**
79      * Construction for fingerprint detect client callback.
80      */
FingerprintCallback(@onNull FingerprintDetectionCallback fingerprintDetectionCallback)81     FingerprintCallback(@NonNull FingerprintDetectionCallback fingerprintDetectionCallback) {
82         mFingerprintDetectionCallback = fingerprintDetectionCallback;
83     }
84 
85     /**
86      * Construction for fingerprint enroll client callback.
87      */
FingerprintCallback(@onNull EnrollmentCallback enrollmentCallback)88     FingerprintCallback(@NonNull EnrollmentCallback enrollmentCallback) {
89         mEnrollmentCallback = enrollmentCallback;
90     }
91 
92     /**
93      * Construction for fingerprint generate challenge client callback.
94      */
FingerprintCallback(@onNull GenerateChallengeCallback generateChallengeCallback)95     FingerprintCallback(@NonNull GenerateChallengeCallback generateChallengeCallback) {
96         mGenerateChallengeCallback = generateChallengeCallback;
97     }
98 
99     /**
100      * Construction for fingerprint removal client callback.
101      */
FingerprintCallback(@onNull RemovalCallback removalCallback, @RemoveRequest int removeRequest, @Nullable Fingerprint removeFingerprint)102     FingerprintCallback(@NonNull RemovalCallback removalCallback, @RemoveRequest int removeRequest,
103             @Nullable Fingerprint removeFingerprint) {
104         mRemovalCallback = removalCallback;
105         mRemoveRequest = removeRequest;
106         mRemoveFingerprint = removeFingerprint;
107     }
108 
109     /**
110      * Propagate enroll progress via the callback.
111      * @param remaining number of enrollment steps remaining
112      */
sendEnrollResult(int remaining)113     public void sendEnrollResult(int remaining) {
114         if (mEnrollmentCallback != null) {
115             mEnrollmentCallback.onEnrollmentProgress(remaining);
116         }
117     }
118 
119     /**
120      * Propagate remove face completed via the callback.
121      * @param fingerprint removed identifier
122      * @param remaining number of face enrollments remaining
123      */
sendRemovedResult(@ullable Fingerprint fingerprint, int remaining)124     public void sendRemovedResult(@Nullable Fingerprint fingerprint, int remaining) {
125         if (mRemovalCallback == null) {
126             return;
127         }
128 
129         if (mRemoveRequest == REMOVE_SINGLE) {
130             if (fingerprint == null) {
131                 Slog.e(TAG, "Received MSG_REMOVED, but fingerprint is null");
132                 return;
133             }
134 
135             if (mRemoveFingerprint == null) {
136                 Slog.e(TAG, "Missing fingerprint");
137                 return;
138             }
139 
140             final int fingerId = fingerprint.getBiometricId();
141             int reqFingerId = mRemoveFingerprint.getBiometricId();
142             if (reqFingerId != 0 && fingerId != 0 && fingerId != reqFingerId) {
143                 Slog.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
144                 return;
145             }
146         }
147 
148         mRemovalCallback.onRemovalSucceeded(fingerprint, remaining);
149     }
150 
151     /**
152      * Propagate authentication succeeded via the callback.
153      * @param fingerprint matched identifier
154      * @param userId id of the corresponding user
155      * @param isStrongBiometric if the sensor is strong or not
156      */
sendAuthenticatedSucceeded(@onNull Fingerprint fingerprint, int userId, boolean isStrongBiometric)157     public void sendAuthenticatedSucceeded(@NonNull Fingerprint fingerprint, int userId,
158             boolean isStrongBiometric) {
159         if (mAuthenticationCallback == null) {
160             Slog.e(TAG, "Authentication succeeded but callback is null.");
161             return;
162         }
163 
164         final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fingerprint,
165                 userId, isStrongBiometric);
166         mAuthenticationCallback.onAuthenticationSucceeded(result);
167     }
168 
169     /**
170      * Propagate authentication failed via the callback.
171      */
sendAuthenticatedFailed()172     public void sendAuthenticatedFailed() {
173         if (mAuthenticationCallback != null) {
174             mAuthenticationCallback.onAuthenticationFailed();
175         }
176     }
177 
178     /**
179      * Propagate acquired result via the callback.
180      * @param context corresponding context
181      * @param acquireInfo represents the framework acquired id
182      * @param vendorCode represents the vendor acquired code
183      */
sendAcquiredResult(@onNull Context context, int acquireInfo, int vendorCode)184     public void sendAcquiredResult(@NonNull Context context, int acquireInfo, int vendorCode) {
185         if (mAuthenticationCallback != null) {
186             mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
187         }
188         if (mEnrollmentCallback != null && acquireInfo != FINGERPRINT_ACQUIRED_START) {
189             mEnrollmentCallback.onAcquired(acquireInfo == FINGERPRINT_ACQUIRED_GOOD);
190         }
191         final String msg = getAcquiredString(context, acquireInfo, vendorCode);
192         if (msg == null) {
193             return;
194         }
195         // emulate HAL 2.1 behavior and send real acquiredInfo
196         final int clientInfo = acquireInfo == FINGERPRINT_ACQUIRED_VENDOR
197                 ? (vendorCode + FINGERPRINT_ACQUIRED_VENDOR_BASE) : acquireInfo;
198         if (mEnrollmentCallback != null) {
199             mEnrollmentCallback.onEnrollmentHelp(clientInfo, msg);
200         } else if (mAuthenticationCallback != null) {
201             if (acquireInfo != FINGERPRINT_ACQUIRED_START) {
202                 mAuthenticationCallback.onAuthenticationHelp(clientInfo, msg);
203             }
204         }
205     }
206 
207     /**
208      * Propagate errors via the callback.
209      * @param context corresponding context
210      * @param errMsgId represents the framework error id
211      * @param vendorCode represents the vendor error code
212      */
sendErrorResult(@onNull Context context, int errMsgId, int vendorCode)213     public void sendErrorResult(@NonNull Context context, int errMsgId, int vendorCode) {
214         // emulate HAL 2.1 behavior and send real errMsgId
215         final int clientErrMsgId = errMsgId == FINGERPRINT_ERROR_VENDOR
216                 ? (vendorCode + FINGERPRINT_ERROR_VENDOR_BASE) : errMsgId;
217         if (mEnrollmentCallback != null) {
218             mEnrollmentCallback.onEnrollmentError(clientErrMsgId,
219                     getErrorString(context, errMsgId, vendorCode));
220         } else if (mAuthenticationCallback != null) {
221             mAuthenticationCallback.onAuthenticationError(clientErrMsgId,
222                     getErrorString(context, errMsgId, vendorCode));
223         } else if (mRemovalCallback != null) {
224             mRemovalCallback.onRemovalError(mRemoveFingerprint, clientErrMsgId,
225                     getErrorString(context, errMsgId, vendorCode));
226         } else if (mFingerprintDetectionCallback != null) {
227             mFingerprintDetectionCallback.onDetectionError(errMsgId);
228             mFingerprintDetectionCallback = null;
229         }
230     }
231 
232     /**
233      * Propagate challenge generated completed via the callback.
234      * @param sensorId id of the corresponding sensor
235      * @param userId id of the corresponding sensor
236      * @param challenge value of the challenge generated
237      */
sendChallengeGenerated(long challenge, int sensorId, int userId)238     public void sendChallengeGenerated(long challenge, int sensorId, int userId) {
239         if (mGenerateChallengeCallback == null) {
240             Slog.e(TAG, "sendChallengeGenerated, callback null");
241             return;
242         }
243         mGenerateChallengeCallback.onChallengeGenerated(sensorId, userId, challenge);
244     }
245 
246     /**
247      * Propagate fingerprint detected completed via the callback.
248      * @param sensorId id of the corresponding sensor
249      * @param userId id of the corresponding user
250      * @param isStrongBiometric if the sensor is strong or not
251      */
sendFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric)252     public void sendFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric) {
253         if (mFingerprintDetectionCallback == null) {
254             Slog.e(TAG, "sendFingerprintDetected, callback null");
255             return;
256         }
257         mFingerprintDetectionCallback.onFingerprintDetected(sensorId, userId, isStrongBiometric);
258     }
259 
260     /**
261      * Propagate udfps pointer down via the callback.
262      * @param sensorId id of the corresponding sensor
263      */
sendUdfpsPointerDown(int sensorId)264     public void sendUdfpsPointerDown(int sensorId) {
265         if (mAuthenticationCallback == null) {
266             Slog.e(TAG, "sendUdfpsPointerDown, callback null");
267         } else {
268             mAuthenticationCallback.onUdfpsPointerDown(sensorId);
269         }
270 
271         if (mEnrollmentCallback != null) {
272             mEnrollmentCallback.onUdfpsPointerDown(sensorId);
273         }
274     }
275 
276     /**
277      * Propagate udfps pointer up via the callback.
278      * @param sensorId id of the corresponding sensor
279      */
sendUdfpsPointerUp(int sensorId)280     public void sendUdfpsPointerUp(int sensorId) {
281         if (mAuthenticationCallback == null) {
282             Slog.e(TAG, "sendUdfpsPointerUp, callback null");
283         } else {
284             mAuthenticationCallback.onUdfpsPointerUp(sensorId);
285         }
286         if (mEnrollmentCallback != null) {
287             mEnrollmentCallback.onUdfpsPointerUp(sensorId);
288         }
289     }
290 
291     /**
292      * Propagate udfps overlay shown via the callback.
293      */
sendUdfpsOverlayShown()294     public void sendUdfpsOverlayShown() {
295         if (mEnrollmentCallback != null) {
296             mEnrollmentCallback.onUdfpsOverlayShown();
297         }
298     }
299 }
300