300 lines
12 KiB
Java
300 lines
12 KiB
Java
/*
|
|
* Copyright (C) 2024 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.hardware.fingerprint;
|
|
|
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
|
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
|
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
|
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR_BASE;
|
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
|
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR_BASE;
|
|
import static android.hardware.fingerprint.FingerprintManager.getAcquiredString;
|
|
import static android.hardware.fingerprint.FingerprintManager.getErrorString;
|
|
|
|
import android.annotation.IntDef;
|
|
import android.content.Context;
|
|
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
|
|
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
|
|
import android.hardware.fingerprint.FingerprintManager.CryptoObject;
|
|
import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
|
|
import android.hardware.fingerprint.FingerprintManager.FingerprintDetectionCallback;
|
|
import android.hardware.fingerprint.FingerprintManager.GenerateChallengeCallback;
|
|
import android.hardware.fingerprint.FingerprintManager.RemovalCallback;
|
|
import android.util.Slog;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
|
|
/**
|
|
* Encapsulates callbacks and client specific information for each fingerprint related request.
|
|
* @hide
|
|
*/
|
|
public class FingerprintCallback {
|
|
private static final String TAG = "FingerprintCallback";
|
|
public static final int REMOVE_SINGLE = 1;
|
|
public static final int REMOVE_ALL = 2;
|
|
@IntDef({REMOVE_SINGLE, REMOVE_ALL})
|
|
public @interface RemoveRequest {}
|
|
@Nullable
|
|
private AuthenticationCallback mAuthenticationCallback;
|
|
@Nullable
|
|
private EnrollmentCallback mEnrollmentCallback;
|
|
@Nullable
|
|
private RemovalCallback mRemovalCallback;
|
|
@Nullable
|
|
private GenerateChallengeCallback mGenerateChallengeCallback;
|
|
@Nullable
|
|
private FingerprintDetectionCallback mFingerprintDetectionCallback;
|
|
@Nullable
|
|
private CryptoObject mCryptoObject;
|
|
@Nullable
|
|
private @RemoveRequest int mRemoveRequest;
|
|
@Nullable
|
|
private Fingerprint mRemoveFingerprint;
|
|
|
|
/**
|
|
* Construction for fingerprint authentication client callback.
|
|
*/
|
|
FingerprintCallback(@NonNull AuthenticationCallback authenticationCallback,
|
|
@Nullable CryptoObject cryptoObject) {
|
|
mAuthenticationCallback = authenticationCallback;
|
|
mCryptoObject = cryptoObject;
|
|
}
|
|
|
|
/**
|
|
* Construction for fingerprint detect client callback.
|
|
*/
|
|
FingerprintCallback(@NonNull FingerprintDetectionCallback fingerprintDetectionCallback) {
|
|
mFingerprintDetectionCallback = fingerprintDetectionCallback;
|
|
}
|
|
|
|
/**
|
|
* Construction for fingerprint enroll client callback.
|
|
*/
|
|
FingerprintCallback(@NonNull EnrollmentCallback enrollmentCallback) {
|
|
mEnrollmentCallback = enrollmentCallback;
|
|
}
|
|
|
|
/**
|
|
* Construction for fingerprint generate challenge client callback.
|
|
*/
|
|
FingerprintCallback(@NonNull GenerateChallengeCallback generateChallengeCallback) {
|
|
mGenerateChallengeCallback = generateChallengeCallback;
|
|
}
|
|
|
|
/**
|
|
* Construction for fingerprint removal client callback.
|
|
*/
|
|
FingerprintCallback(@NonNull RemovalCallback removalCallback, @RemoveRequest int removeRequest,
|
|
@Nullable Fingerprint removeFingerprint) {
|
|
mRemovalCallback = removalCallback;
|
|
mRemoveRequest = removeRequest;
|
|
mRemoveFingerprint = removeFingerprint;
|
|
}
|
|
|
|
/**
|
|
* Propagate enroll progress via the callback.
|
|
* @param remaining number of enrollment steps remaining
|
|
*/
|
|
public void sendEnrollResult(int remaining) {
|
|
if (mEnrollmentCallback != null) {
|
|
mEnrollmentCallback.onEnrollmentProgress(remaining);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Propagate remove face completed via the callback.
|
|
* @param fingerprint removed identifier
|
|
* @param remaining number of face enrollments remaining
|
|
*/
|
|
public void sendRemovedResult(@Nullable Fingerprint fingerprint, int remaining) {
|
|
if (mRemovalCallback == null) {
|
|
return;
|
|
}
|
|
|
|
if (mRemoveRequest == REMOVE_SINGLE) {
|
|
if (fingerprint == null) {
|
|
Slog.e(TAG, "Received MSG_REMOVED, but fingerprint is null");
|
|
return;
|
|
}
|
|
|
|
if (mRemoveFingerprint == null) {
|
|
Slog.e(TAG, "Missing fingerprint");
|
|
return;
|
|
}
|
|
|
|
final int fingerId = fingerprint.getBiometricId();
|
|
int reqFingerId = mRemoveFingerprint.getBiometricId();
|
|
if (reqFingerId != 0 && fingerId != 0 && fingerId != reqFingerId) {
|
|
Slog.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
|
|
return;
|
|
}
|
|
}
|
|
|
|
mRemovalCallback.onRemovalSucceeded(fingerprint, remaining);
|
|
}
|
|
|
|
/**
|
|
* Propagate authentication succeeded via the callback.
|
|
* @param fingerprint matched identifier
|
|
* @param userId id of the corresponding user
|
|
* @param isStrongBiometric if the sensor is strong or not
|
|
*/
|
|
public void sendAuthenticatedSucceeded(@NonNull Fingerprint fingerprint, int userId,
|
|
boolean isStrongBiometric) {
|
|
if (mAuthenticationCallback == null) {
|
|
Slog.e(TAG, "Authentication succeeded but callback is null.");
|
|
return;
|
|
}
|
|
|
|
final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fingerprint,
|
|
userId, isStrongBiometric);
|
|
mAuthenticationCallback.onAuthenticationSucceeded(result);
|
|
}
|
|
|
|
/**
|
|
* Propagate authentication failed via the callback.
|
|
*/
|
|
public void sendAuthenticatedFailed() {
|
|
if (mAuthenticationCallback != null) {
|
|
mAuthenticationCallback.onAuthenticationFailed();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Propagate acquired result via the callback.
|
|
* @param context corresponding context
|
|
* @param acquireInfo represents the framework acquired id
|
|
* @param vendorCode represents the vendor acquired code
|
|
*/
|
|
public void sendAcquiredResult(@NonNull Context context, int acquireInfo, int vendorCode) {
|
|
if (mAuthenticationCallback != null) {
|
|
mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
|
|
}
|
|
if (mEnrollmentCallback != null && acquireInfo != FINGERPRINT_ACQUIRED_START) {
|
|
mEnrollmentCallback.onAcquired(acquireInfo == FINGERPRINT_ACQUIRED_GOOD);
|
|
}
|
|
final String msg = getAcquiredString(context, acquireInfo, vendorCode);
|
|
if (msg == null) {
|
|
return;
|
|
}
|
|
// emulate HAL 2.1 behavior and send real acquiredInfo
|
|
final int clientInfo = acquireInfo == FINGERPRINT_ACQUIRED_VENDOR
|
|
? (vendorCode + FINGERPRINT_ACQUIRED_VENDOR_BASE) : acquireInfo;
|
|
if (mEnrollmentCallback != null) {
|
|
mEnrollmentCallback.onEnrollmentHelp(clientInfo, msg);
|
|
} else if (mAuthenticationCallback != null) {
|
|
if (acquireInfo != FINGERPRINT_ACQUIRED_START) {
|
|
mAuthenticationCallback.onAuthenticationHelp(clientInfo, msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Propagate errors via the callback.
|
|
* @param context corresponding context
|
|
* @param errMsgId represents the framework error id
|
|
* @param vendorCode represents the vendor error code
|
|
*/
|
|
public void sendErrorResult(@NonNull Context context, int errMsgId, int vendorCode) {
|
|
// emulate HAL 2.1 behavior and send real errMsgId
|
|
final int clientErrMsgId = errMsgId == FINGERPRINT_ERROR_VENDOR
|
|
? (vendorCode + FINGERPRINT_ERROR_VENDOR_BASE) : errMsgId;
|
|
if (mEnrollmentCallback != null) {
|
|
mEnrollmentCallback.onEnrollmentError(clientErrMsgId,
|
|
getErrorString(context, errMsgId, vendorCode));
|
|
} else if (mAuthenticationCallback != null) {
|
|
mAuthenticationCallback.onAuthenticationError(clientErrMsgId,
|
|
getErrorString(context, errMsgId, vendorCode));
|
|
} else if (mRemovalCallback != null) {
|
|
mRemovalCallback.onRemovalError(mRemoveFingerprint, clientErrMsgId,
|
|
getErrorString(context, errMsgId, vendorCode));
|
|
} else if (mFingerprintDetectionCallback != null) {
|
|
mFingerprintDetectionCallback.onDetectionError(errMsgId);
|
|
mFingerprintDetectionCallback = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Propagate challenge generated completed via the callback.
|
|
* @param sensorId id of the corresponding sensor
|
|
* @param userId id of the corresponding sensor
|
|
* @param challenge value of the challenge generated
|
|
*/
|
|
public void sendChallengeGenerated(long challenge, int sensorId, int userId) {
|
|
if (mGenerateChallengeCallback == null) {
|
|
Slog.e(TAG, "sendChallengeGenerated, callback null");
|
|
return;
|
|
}
|
|
mGenerateChallengeCallback.onChallengeGenerated(sensorId, userId, challenge);
|
|
}
|
|
|
|
/**
|
|
* Propagate fingerprint detected completed via the callback.
|
|
* @param sensorId id of the corresponding sensor
|
|
* @param userId id of the corresponding user
|
|
* @param isStrongBiometric if the sensor is strong or not
|
|
*/
|
|
public void sendFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric) {
|
|
if (mFingerprintDetectionCallback == null) {
|
|
Slog.e(TAG, "sendFingerprintDetected, callback null");
|
|
return;
|
|
}
|
|
mFingerprintDetectionCallback.onFingerprintDetected(sensorId, userId, isStrongBiometric);
|
|
}
|
|
|
|
/**
|
|
* Propagate udfps pointer down via the callback.
|
|
* @param sensorId id of the corresponding sensor
|
|
*/
|
|
public void sendUdfpsPointerDown(int sensorId) {
|
|
if (mAuthenticationCallback == null) {
|
|
Slog.e(TAG, "sendUdfpsPointerDown, callback null");
|
|
} else {
|
|
mAuthenticationCallback.onUdfpsPointerDown(sensorId);
|
|
}
|
|
|
|
if (mEnrollmentCallback != null) {
|
|
mEnrollmentCallback.onUdfpsPointerDown(sensorId);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Propagate udfps pointer up via the callback.
|
|
* @param sensorId id of the corresponding sensor
|
|
*/
|
|
public void sendUdfpsPointerUp(int sensorId) {
|
|
if (mAuthenticationCallback == null) {
|
|
Slog.e(TAG, "sendUdfpsPointerUp, callback null");
|
|
} else {
|
|
mAuthenticationCallback.onUdfpsPointerUp(sensorId);
|
|
}
|
|
if (mEnrollmentCallback != null) {
|
|
mEnrollmentCallback.onUdfpsPointerUp(sensorId);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Propagate udfps overlay shown via the callback.
|
|
*/
|
|
public void sendUdfpsOverlayShown() {
|
|
if (mEnrollmentCallback != null) {
|
|
mEnrollmentCallback.onUdfpsOverlayShown();
|
|
}
|
|
}
|
|
}
|