接前面文章
??????生物解锁--指纹服务注册流程_liujun3512159的博客-CSDN博客
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,
uint32_t gid) {
return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid));
}
下面的部分,是我猜测的,这段代码,我感觉应该是hal层或者说硬件厂商指纹设别后,然后回调到这里的,然后有这个地方层层上报到最上层,告诉用户,有没有解锁成功,或者其他。
void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) {
BiometricsFingerprint* thisPtr = static_cast<BiometricsFingerprint*>(
BiometricsFingerprint::getInstance());
std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex);
if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
ALOGE("Receiving callbacks before the client callback is registered.");
return;
}
const uint64_t devId = reinterpret_cast<uint64_t>(thisPtr->mDevice);
switch (msg->type) {
case FINGERPRINT_ERROR: {
int32_t vendorCode = 0;
FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
ALOGD("onError(%d)", result);
if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
ALOGE("failed to invoke fingerprint onError callback");
}
}
break;
case FINGERPRINT_ACQUIRED: {
int32_t vendorCode = 0;
FingerprintAcquiredInfo result =
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
ALOGD("onAcquired(%d)", result);
if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
ALOGE("failed to invoke fingerprint onAcquired callback");
}
}
break;
case FINGERPRINT_TEMPLATE_ENROLLING:
ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)",
msg->data.enroll.finger.fid,
msg->data.enroll.finger.gid,
msg->data.enroll.samples_remaining);
if (!thisPtr->mClientCallback->onEnrollResult(devId,
msg->data.enroll.finger.fid,
msg->data.enroll.finger.gid,
msg->data.enroll.samples_remaining).isOk()) {
ALOGE("failed to invoke fingerprint onEnrollResult callback");
}
break;
case FINGERPRINT_TEMPLATE_REMOVED:
ALOGD("onRemove(fid=%d, gid=%d, rem=%d)",
msg->data.removed.finger.fid,
msg->data.removed.finger.gid,
msg->data.removed.remaining_templates);
if (!thisPtr->mClientCallback->onRemoved(devId,
msg->data.removed.finger.fid,
msg->data.removed.finger.gid,
msg->data.removed.remaining_templates).isOk()) {
ALOGE("failed to invoke fingerprint onRemoved callback");
}
break;
case FINGERPRINT_AUTHENTICATED:
if (msg->data.authenticated.finger.fid != 0) {
ALOGD("onAuthenticated(fid=%d, gid=%d)",
msg->data.authenticated.finger.fid,
msg->data.authenticated.finger.gid);
const uint8_t* hat =
reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
const hidl_vec<uint8_t> token(
std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
if (!thisPtr->mClientCallback->onAuthenticated(devId,
msg->data.authenticated.finger.fid,
msg->data.authenticated.finger.gid,
token).isOk()) {
ALOGE("failed to invoke fingerprint onAuthenticated callback");
}
} else {
// Not a recognized fingerprint
if (!thisPtr->mClientCallback->onAuthenticated(devId,
msg->data.authenticated.finger.fid,
msg->data.authenticated.finger.gid,
hidl_vec<uint8_t>()).isOk()) {
ALOGE("failed to invoke fingerprint onAuthenticated callback");
}
}
break;
case FINGERPRINT_TEMPLATE_ENUMERATING:
ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)",
msg->data.enumerated.finger.fid,
msg->data.enumerated.finger.gid,
msg->data.enumerated.remaining_templates);
if (!thisPtr->mClientCallback->onEnumerate(devId,
msg->data.enumerated.finger.fid,
msg->data.enumerated.finger.gid,
msg->data.enumerated.remaining_templates).isOk()) {
ALOGE("failed to invoke fingerprint onEnumerate callback");
}
break;
}
}
第63行,thisPtr在第2行有定义,即是BiometricsFingerprint对象实例。继续,看看mClientCallback 是如何定义的,原来是其他地方传过来的,其实就是后面的HalResultController
Return<uint64_t> BiometricsFingerprint::setNotify(
const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
std::lock_guard<std::mutex> lock(mClientCallbackMutex);
mClientCallback = clientCallback;
// This is here because HAL 2.1 doesn't have a way to propagate a
// unique token for its driver. Subsequent versions should send a unique
// token for each call to setNotify(). This is fine as long as there's only
// one fingerprint device on the platform.
return reinterpret_cast<uint64_t>(mDevice);
}
Fingerprint21类下的 synchronized IBiometricsFingerprint getDaemon() 方法中会被调用setNotify的,见下面的第35行。
@VisibleForTesting
synchronized IBiometricsFingerprint getDaemon() {
if (mTestHalEnabled) {
final TestHal testHal = new TestHal(mContext, mSensorId);
testHal.setNotify(mHalResultController);
return testHal;
}
if (mDaemon != null) {
return mDaemon;
}
Slog.d(TAG, "Daemon was null, reconnecting, current operation: "
+ mScheduler.getCurrentClient());
try {
mDaemon = IBiometricsFingerprint.getService();
} catch (java.util.NoSuchElementException e) {
// Service doesn't exist or cannot be opened.
Slog.w(TAG, "NoSuchElementException", e);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to get fingerprint HAL", e);
}
if (mDaemon == null) {
Slog.w(TAG, "Fingerprint HAL not available");
return null;
}
mDaemon.asBinder().linkToDeath(this, 0 /* flags */);
// HAL ID for these HIDL versions are only used to determine if callbacks have been
// successfully set.
long halId = 0;
try {
halId = mDaemon.setNotify(mHalResultController);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to set callback for fingerprint HAL", e);
mDaemon = null;
}
Slog.d(TAG, "Fingerprint HAL ready, HAL ID: " + halId);
if (halId != 0) {
scheduleLoadAuthenticatorIds();
scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */);
} else {
Slog.e(TAG, "Unable to set callback");
mDaemon = null;
}
return mDaemon;
}
?看看第35行,从哪儿传进来mHalResultController
?halId = mDaemon.setNotify(mHalResultController);
Fingerprint21(@NonNull Context context,
@NonNull FingerprintStateCallback fingerprintStateCallback,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@NonNull BiometricScheduler scheduler, @NonNull Handler handler,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull HalResultController controller) {
mContext = context;
mFingerprintStateCallback = fingerprintStateCallback;
mSensorProperties = sensorProps;
mSensorId = sensorProps.sensorId;
mIsUdfps = sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL
|| sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC;
mIsPowerbuttonFps = sensorProps.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON;
mScheduler = scheduler;
mHandler = handler;
mActivityTaskManager = ActivityTaskManager.getInstance();
mTaskStackListener = new BiometricTaskStackListener();
mAuthenticatorIds = Collections.synchronizedMap(new HashMap<>());
mLazyDaemon = Fingerprint21.this::getDaemon;
mLockoutResetDispatcher = lockoutResetDispatcher;
mLockoutTracker = new LockoutFrameworkImpl(context, mLockoutResetCallback);
mHalResultController = controller;
mHalResultController.setCallback(() -> {
mDaemon = null;
mCurrentUserId = UserHandle.USER_NULL;
});
try {
ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to register user switch observer");
}
}
?注意第24行。
public static Fingerprint21 newInstance(@NonNull Context context,
@NonNull FingerprintStateCallback fingerprintStateCallback,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
final Handler handler = new Handler(Looper.getMainLooper());
final BiometricScheduler scheduler =
new BiometricScheduler(TAG,
BiometricScheduler.sensorTypeFromFingerprintProperties(sensorProps),
gestureAvailabilityDispatcher);
final HalResultController controller = new HalResultController(sensorProps.sensorId,
context, handler,
scheduler);
return new Fingerprint21(context, fingerprintStateCallback, sensorProps, scheduler, handler,
lockoutResetDispatcher, controller);
}
?注意第11行,把controller 对象传入进来。
回到前面的方法
void BiometricsFingerprint::notify(const fingerprint_msg_t *msg)的第63行
!thisPtr->mClientCallback->onAuthenticated 实际上是调用的是HalResultController下的onAuthenticated方法
public static class HalResultController extends IBiometricsFingerprintClientCallback.Stub {
/**
* Interface to sends results to the HalResultController's owner.
*/
public interface Callback {
/**
* Invoked when the HAL sends ERROR_HW_UNAVAILABLE.
*/
void onHardwareUnavailable();
}
private final int mSensorId;
@NonNull private final Context mContext;
@NonNull final Handler mHandler;
@NonNull final BiometricScheduler mScheduler;
@Nullable private Callback mCallback;
HalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
@NonNull BiometricScheduler scheduler) {
mSensorId = sensorId;
mContext = context;
mHandler = handler;
mScheduler = scheduler;
}
public void setCallback(@Nullable Callback callback) {
mCallback = callback;
}
@Override
public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof FingerprintEnrollClient)) {
Slog.e(TAG, "onEnrollResult for non-enroll client: "
+ Utils.getClientName(client));
return;
}
final int currentUserId = client.getTargetUserId();
final CharSequence name = FingerprintUtils.getLegacyInstance(mSensorId)
.getUniqueName(mContext, currentUserId);
final Fingerprint fingerprint = new Fingerprint(name, groupId, fingerId, deviceId);
final FingerprintEnrollClient enrollClient = (FingerprintEnrollClient) client;
enrollClient.onEnrollResult(fingerprint, remaining);
});
}
@Override
public void onAcquired(long deviceId, int acquiredInfo, int vendorCode) {
onAcquired_2_2(deviceId, acquiredInfo, vendorCode);
}
@Override
public void onAcquired_2_2(long deviceId, int acquiredInfo, int vendorCode) {
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof AcquisitionClient)) {
Slog.e(TAG, "onAcquired for non-acquisition client: "
+ Utils.getClientName(client));
return;
}
final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client;
acquisitionClient.onAcquired(acquiredInfo, vendorCode);
});
}
@Override
public void onAuthenticated(long deviceId, int fingerId, int groupId,
ArrayList<Byte> token) {
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof AuthenticationConsumer)) {
Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
+ Utils.getClientName(client));
return;
}
final AuthenticationConsumer authenticationConsumer =
(AuthenticationConsumer) client;
final boolean authenticated = fingerId != 0;
final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
authenticationConsumer.onAuthenticated(fp, authenticated, token);
});
}
@Override
public void onError(long deviceId, int error, int vendorCode) {
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
Slog.d(TAG, "handleError"
+ ", client: " + Utils.getClientName(client)
+ ", error: " + error
+ ", vendorCode: " + vendorCode);
if (!(client instanceof ErrorConsumer)) {
Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(client));
return;
}
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(error, vendorCode);
if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
if (mCallback != null) {
mCallback.onHardwareUnavailable();
}
}
});
}
@Override
public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
mHandler.post(() -> {
Slog.d(TAG, "Removed, fingerId: " + fingerId + ", remaining: " + remaining);
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof RemovalConsumer)) {
Slog.e(TAG, "onRemoved for non-removal consumer: "
+ Utils.getClientName(client));
return;
}
final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
final RemovalConsumer removalConsumer = (RemovalConsumer) client;
removalConsumer.onRemoved(fp, remaining);
});
}
@Override
public void onEnumerate(long deviceId, int fingerId, int groupId, int remaining) {
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof EnumerateConsumer)) {
Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
+ Utils.getClientName(client));
return;
}
final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
enumerateConsumer.onEnumerationResult(fp, remaining);
});
}
}
回到前面的代码部分
if (!thisPtr->mClientCallback->onAuthenticated(devId,
msg->data.authenticated.finger.fid,
msg->data.authenticated.finger.gid,
token).isOk()) {
ALOGE("failed to invoke fingerprint onAuthenticated callback");
}
thisPtr->mClientCallback->onAuthenticated 调用的实际上就是HalResultController类下的对应的方法
@Override
public void onAuthenticated(long deviceId, int fingerId, int groupId,
ArrayList<Byte> token) {
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof AuthenticationConsumer)) {
Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
+ Utils.getClientName(client));
return;
}
final AuthenticationConsumer authenticationConsumer =
(AuthenticationConsumer) client;
final boolean authenticated = fingerId != 0;
final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
authenticationConsumer.onAuthenticated(fp, authenticated, token);
});
}
第16行,authenticationConsumer其实就是FingerprintAuthenticationClient 对象实例
生物解锁--指纹服务注册流程_liujun3512159的博客-CSDN博客
那么,authenticationConsumer.onAuthenticated(fp, authenticated, token)调用的就是
@Override
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
boolean authenticated, ArrayList<Byte> token) {
super.onAuthenticated(identifier, authenticated, token);
if (authenticated) {
mState = STATE_STOPPED;
mSensorOverlays.hide(getSensorId());
} else {
mState = STATE_STARTED_PAUSED_ATTEMPTED;
}
}
代码super.onAuthenticated(identifier, authenticated, token);,比较关键
他实际上是调用的AuthenticationClient下的onAuthenticated方法
@Override
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
boolean authenticated, ArrayList<Byte> hardwareAuthToken) {
super.logOnAuthenticated(getContext(), authenticated, mRequireConfirmation,
getTargetUserId(), isBiometricPrompt());
final ClientMonitorCallbackConverter listener = getListener();
if (DEBUG) Slog.v(TAG, "onAuthenticated(" + authenticated + ")"
+ ", ID:" + identifier.getBiometricId()
+ ", Owner: " + getOwnerString()
+ ", isBP: " + isBiometricPrompt()
+ ", listener: " + listener
+ ", requireConfirmation: " + mRequireConfirmation
+ ", user: " + getTargetUserId()
+ ", clientMonitor: " + toString());
final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId());
if (isCryptoOperation()) {
pm.incrementCryptoAuthForUser(getTargetUserId(), authenticated);
} else {
pm.incrementAuthForUser(getTargetUserId(), authenticated);
}
if (mAllowBackgroundAuthentication) {
Slog.w(TAG, "Allowing background authentication,"
+ " this is allowed only for platform or test invocations");
}
// Ensure authentication only succeeds if the client activity is on top.
boolean isBackgroundAuth = false;
if (!mAllowBackgroundAuthentication && authenticated
&& !Utils.isKeyguard(getContext(), getOwnerString())
&& !Utils.isSystem(getContext(), getOwnerString())) {
final List<ActivityManager.RunningTaskInfo> tasks =
mActivityTaskManager.getTasks(1);
if (tasks == null || tasks.isEmpty()) {
Slog.e(TAG, "No running tasks reported");
isBackgroundAuth = true;
} else {
final ComponentName topActivity = tasks.get(0).topActivity;
if (topActivity == null) {
Slog.e(TAG, "Unable to get top activity");
isBackgroundAuth = true;
} else {
final String topPackage = topActivity.getPackageName();
if (!topPackage.contentEquals(getOwnerString())) {
Slog.e(TAG, "Background authentication detected, top: " + topPackage
+ ", client: " + getOwnerString());
isBackgroundAuth = true;
}
}
}
}
// Fail authentication if we can't confirm the client activity is on top.
if (isBackgroundAuth) {
Slog.e(TAG, "Failing possible background authentication");
authenticated = false;
// SafetyNet logging for exploitation attempts of b/159249069.
final ApplicationInfo appInfo = getContext().getApplicationInfo();
EventLog.writeEvent(0x534e4554, "159249069", appInfo != null ? appInfo.uid : -1,
"Attempted background authentication");
}
if (authenticated) {
// SafetyNet logging for b/159249069 if constraint is violated.
if (isBackgroundAuth) {
final ApplicationInfo appInfo = getContext().getApplicationInfo();
EventLog.writeEvent(0x534e4554, "159249069", appInfo != null ? appInfo.uid : -1,
"Successful background authentication!");
}
markAlreadyDone();
if (mTaskStackListener != null) {
mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
}
final byte[] byteToken = new byte[hardwareAuthToken.size()];
for (int i = 0; i < hardwareAuthToken.size(); i++) {
byteToken[i] = hardwareAuthToken.get(i);
}
if (mIsStrongBiometric) {
mBiometricManager.resetLockoutTimeBound(getToken(),
getContext().getOpPackageName(),
getSensorId(), getTargetUserId(), byteToken);
}
final CoexCoordinator coordinator = CoexCoordinator.getInstance();
coordinator.onAuthenticationSucceeded(SystemClock.uptimeMillis(), this,
new CoexCoordinator.Callback() {
@Override
public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
if (addAuthTokenIfStrong && mIsStrongBiometric) {
final int result = KeyStore.getInstance().addAuthToken(byteToken);
Slog.d(TAG, "addAuthToken: " + result);
} else {
Slog.d(TAG, "Skipping addAuthToken");
}
if (listener != null) {
try {
// Explicitly have if/else here to make it super obvious in case the
// code is touched in the future.
if (!mIsRestricted) {
listener.onAuthenticationSucceeded(getSensorId(),
identifier,
byteToken,
getTargetUserId(),
mIsStrongBiometric);
} else {
listener.onAuthenticationSucceeded(getSensorId(),
null /* identifier */,
byteToken,
getTargetUserId(),
mIsStrongBiometric);
}
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify listener", e);
}
} else {
Slog.w(TAG, "Client not listening");
}
}
@Override
public void sendHapticFeedback() {
if (listener != null && mShouldVibrate) {
vibrateSuccess();
}
}
@Override
public void handleLifecycleAfterAuth() {
AuthenticationClient.this.handleLifecycleAfterAuth(true /* authenticated */);
}
@Override
public void sendAuthenticationCanceled() {
sendCancelOnly(listener);
}
});
} else {
// Allow system-defined limit of number of attempts before giving up
final @LockoutTracker.LockoutMode int lockoutMode =
handleFailedAttempt(getTargetUserId());
if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
markAlreadyDone();
}
final CoexCoordinator coordinator = CoexCoordinator.getInstance();
coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode,
new CoexCoordinator.Callback() {
@Override
public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
if (listener != null) {
try {
listener.onAuthenticationFailed(getSensorId());
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify listener", e);
}
}
}
@Override
public void sendHapticFeedback() {
if (listener != null && mShouldVibrate) {
vibrateError();
}
}
@Override
public void handleLifecycleAfterAuth() {
AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */);
}
@Override
public void sendAuthenticationCanceled() {
sendCancelOnly(listener);
}
});
}
}
|