mCurrentUserId, 0 /* groupId */, opId, restricted, opPackageName,
0 /* cookie /, false / requireConfirmation */);
/重点关注/
authenticateInternal(client, opId, opPackageName);
}
frameworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
protected void authenticateInternal(AuthenticationClientImpl client, long opId,
String opPackageName) {
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
final int callingUserId = UserHandle.getCallingUserId();
authenticateInternal(client, opId, opPackageName, callingUid, callingPid, callingUserId);
}
frameworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
protected void authenticateInternal(AuthenticationClientImpl client, long opId,
String opPackageName, int callingUid, int callingPid, int callingUserId) {
if (!canUseBiometric(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
callingUserId)) {
if (DEBUG) Slog.v(getTag(), "authenticate(): reject " + opPackageName);
return;
}
mHandler.post(() -> {
mMetricsLogger.histogram(getConstants().tagAuthToken(), opId != 0L ? 1 : 0);
// Get performance stats object for this user.
HashMap<Integer, PerformanceStats> pmap
= (opId == 0) ? mPerformanceMap : mCryptoPerformanceMap;
PerformanceStats stats = pmap.get(mCurrentUserId);
if (stats == null) {
stats = new PerformanceStats();
pmap.put(mCurrentUserId, stats);
}
mPerformanceStats = stats;
mIsCrypto = (opId != 0);
/重点关注/
startAuthentication(client, opPackageName);
});
}
startAuthentication(client, opPackageName);
private void startAuthentication(AuthenticationClientImpl client, String opPackageName) {
if (DEBUG) Slog.v(getTag(), “startAuthentication(” + opPackageName + “)”);
int lockoutMode = getLockoutMode();
if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
Slog.v(getTag(), “In lockout mode(” + lockoutMode + “) ; disallowing authentication”);
int errorCode = lockoutMode == AuthenticationClient.LOCKOUT_TIMED ?
BiometricConstants.BIOMETRIC_ERROR_LOCKOUT :
BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
if (!client.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */)) {
Slog.w(getTag(), “Cannot send permanent lockout message to client”);
}
return;
}
/重点关注/
startClient(client, true /* initiatedByClient */);
//这里将AuthenticationClient传递进去
}
startClient(client, true /* initiatedByClient */);
private void startClient(ClientMonitor newClient, boolean initiatedByClient) {
ClientMonitor currentClient = mCurrentClient;
if (currentClient != null) {
if (DEBUG) Slog.v(getTag(), "request stop current client " +
currentClient.getOwnerString());
// This check only matters for FingerprintService, since enumerate may call back
// multiple times.
if (currentClient instanceof InternalEnumerateClient
|| currentClient instanceof InternalRemovalClient) {
// This condition means we’re currently running internal diagnostics to
// remove extra templates in the hardware and/or the software
// TODO: design an escape hatch in case client never finishes
if (newClient != null) {
Slog.w(getTag(), "Internal cleanup in progress but trying to start client "
-
newClient.getClass().getSuperclass().getSimpleName()
-
“(” + newClient.getOwnerString() + “)”
-
", initiatedByClient = " + initiatedByClient);
}
} else {
currentClient.stop(initiatedByClient);
// Only post the reset runnable for non-cleanup clients. Cleanup clients should
// never be forcibly stopped since they ensure synchronization between HAL and
// framework. Thus, we should instead just start the pending client once cleanup
// finishes instead of using the reset runnable.
mHandler.removeCallbacks(mResetClientState);
mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
}
mPendingClient = newClient;
} else if (newClient != null) {
// For BiometricPrompt clients, do not start until
// Service#startPreparedClient is called. BiometricService waits until all
// modalities are ready before initiating authentication.
if (newClient instanceof AuthenticationClient) {
AuthenticationClient client = (AuthenticationClient) newClient;
if (client.isBiometricPrompt()) {
if (DEBUG) Slog.v(getTag(), "Returning cookie: " + client.getCookie());
mCurrentClient = newClient;
if (mBiometricService == null) {
mBiometricService = IBiometricService.Stub.asInterface(
ServiceManager.getService(Context.BIOMETRIC_SERVICE));
}
try {
mBiometricService.onReadyForAuthentication(client.getCookie(),
client.getRequireConfirmation(), client.getTargetUserId());
} catch (RemoteException e) {
Slog.e(getTag(), “Remote exception”, e);
}
return;
}
}
// We are not a BiometricPrompt client, start the client immediately
mCurrentClient = newClient;
/重点关注/
startCurrentClient(mCurrentClient.getCookie());
//这里继续将AuthenticationClient传递进去
}
}
startCurrentClient(mCurrentClient.getCookie());
protected void startCurrentClient(int cookie) {
if (mCurrentClient == null) {
Slog.e(getTag(), “Trying to start null client!”);
return;
}
if (DEBUG) Slog.v(getTag(), "starting client "
-
mCurrentClient.getClass().getSuperclass().getSimpleName()
-
“(” + mCurrentClient.getOwnerString() + “)”
-
" cookie: " + cookie + “/” + mCurrentClient.getCookie());
if (cookie != mCurrentClient.getCookie()) {
Slog.e(getTag(), “Mismatched cookie”);
return;
}
notifyClientActiveCallbacks(true);
/重点关注/
mCurrentClient.start();
//这里调用的是AuthenticationClient的start方法
}
frameworks/base/services/core/java/com/android/server/biometrics/AuthenticationClient.java
public int start() {
mStarted = true;
onStart();
try {
/重点关注/
final int result = getDaemonWrapper().authenticate(mOpId, getGroupId());
if (result != 0) {
Slog.w(getLogTag(), “startAuthentication failed, result=” + result);
mMetricsLogger.histogram(mConstants.tagAuthStartError(), result);
onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
return result;
}
if (DEBUG) Slog.w(getLogTag(), “client " + getOwnerString() + " is authenticating…”);
} catch (RemoteException e) {
Slog.e(getLogTag(), “startAuthentication failed”, e);
return ERROR_ESRCH;
}
return 0; // success
}
start方法会调用faced,调用底层的人脸库,底层库返回结果后会调用onAuthenticated来反馈结果给receiver,在往上层反馈
五、人脸解锁屏幕
frameworks/base/services/core/java/com/android/server/biometrics/AuthenticationClient.java
public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
boolean authenticated, ArrayList token) {
super.logOnAuthenticated(getContext(), a