锁屏要使用指纹解锁,首先要注册指纹服务,我看过的一些大厂项目中,实际上是在KeyguardUpdate.java类中发起注册的,一般是根据当前状态,是不是已经处于上锁状态(侧边指纹机器,是不等上锁即进行指纹服务注册,屏下指纹需要等上锁后,才发起指纹服务注册)。
具体代码一般就是KeyguardUpdateMonitor类下的
private void startListeningForFingerprint() {final int userId = getCurrentUser();final boolean unlockPossible = isUnlockWithFingerprintPossible(userId);if (mFingerprintCancelSignal != null) {Log.e(TAG, "Cancellation signal is not null, high chance of bug in fp auth lifecycle"+ " management. FP state: " + mFingerprintRunningState+ ", unlockPossible: " + unlockPossible);}if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);return;}if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {// Waiting for restart via handleFingerprintError().return;}if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");if (unlockPossible) {mFingerprintCancelSignal = new CancellationSignal();if (isEncryptedOrLockdown(userId)) {mFpm.detectFingerprint(mFingerprintCancelSignal, mFingerprintDetectionCallback,userId);} else {mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal,mFingerprintAuthenticationCallback, null /* handler */,FingerprintManager.SENSOR_ID_ANY, userId, 0 /* flags */);}setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);}}
mFpm变量就是FingerPrintManager类对象实例。见第27行,会调用指纹服务注册流程。
下面看看FingerPrintManager类的authenticate方法
@RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT})public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,@NonNull AuthenticationCallback callback, Handler handler, int sensorId, int userId,int flags) {FrameworkStatsLog.write(FrameworkStatsLog.AUTH_DEPRECATED_API_USED,AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_AUTHENTICATE,mContext.getApplicationInfo().uid,mContext.getApplicationInfo().targetSdkVersion);if (callback == null) {throw new IllegalArgumentException("Must supply an authentication callback");}if (cancel != null && cancel.isCanceled()) {Slog.w(TAG, "authentication already canceled");return;}final boolean ignoreEnrollmentState = flags == 0 ? false : true;if (mService != null) {try {useHandler(handler);mAuthenticationCallback = callback;mCryptoObject = crypto;final long operationId = crypto != null ? crypto.getOpId() : 0;final long authId = mService.authenticate(mToken, operationId, sensorId, userId,mServiceReceiver, mContext.getOpPackageName(), ignoreEnrollmentState);if (cancel != null) {cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));}} catch (RemoteException e) {Slog.w(TAG, "Remote exception while authenticating: ", e);// Though this may not be a hardware issue, it will cause apps to give up or try// again later.callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE,getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE,0 /* vendorCode */));}}}
见第28行,就是进行指纹服务注册,继续往下看,就是调用mService.authenticate 方法
下面看看变量mService对象是哪个?通过souce insight 工具搜索
有这个定义private IFingerprintService mService;
然后继续往下找在哪儿定义的
public FingerprintManager(Context context, IFingerprintService service) {mContext = context;mService = service;if (mService == null) {Slog.v(TAG, "FingerprintService was null");}mHandler = new MyHandler(context);}
在其他地方初始化FingerprintManager的时候传进来的,然后在KeyguardUpdate类中找到以下代码
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);}
显然mFpm是个系统服务,继续往下找。搜到类SystemServieRegistry.java
registerService(Context.FINGERPRINT_SERVICE, FingerprintManager.class,new CachedServiceFetcher<FingerprintManager>() {@Overridepublic FingerprintManager createService(ContextImpl ctx) throws ServiceNotFoundException {final IBinder binder;if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {binder = ServiceManager.getServiceOrThrow(Context.FINGERPRINT_SERVICE);} else {binder = ServiceManager.getService(Context.FINGERPRINT_SERVICE);}IFingerprintService service = IFingerprintService.Stub.asInterface(binder);return new FingerprintManager(ctx.getOuterContext(), service);}});
第11行,从代码来看,可以发现这里用到Binder调用技术,即aidl
service 就是继承IFingerprintService的FingerprintService类。
就是说,上面的mService 就是 要到FingerprintService类中去寻找对象实例了。
然后来到FingerprintService类,查找对应的authenticate方法
@SuppressWarnings("deprecation")@Override // Binder callpublic long authenticate(final IBinder token, final long operationId,final int sensorId, final int userId, final IFingerprintServiceReceiver receiver,final String opPackageName, boolean ignoreEnrollmentState) {final int callingUid = Binder.getCallingUid();final int callingPid = Binder.getCallingPid();final int callingUserId = UserHandle.getCallingUserId();if (!canUseFingerprint(opPackageName, true /* requireForeground */, callingUid,callingPid, callingUserId)) {Slog.w(TAG, "Authenticate rejecting package: " + opPackageName);return -1;}// Keyguard check must be done on the caller's binder identity, since it also checks// permission.final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName);// Clear calling identity when checking LockPatternUtils for StrongAuth flags.long identity = Binder.clearCallingIdentity();try {if (isKeyguard && Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {// If this happens, something in KeyguardUpdateMonitor is wrong.// SafetyNet for b/79776455EventLog.writeEvent(0x534e4554, "79776455");Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown");return -1;}} finally {Binder.restoreCallingIdentity(identity);}final boolean restricted = getContext().checkCallingPermission(MANAGE_FINGERPRINT)!= PackageManager.PERMISSION_GRANTED;final int statsClient = isKeyguard ? BiometricsProtoEnums.CLIENT_KEYGUARD: BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER;final Pair<Integer, ServiceProvider> provider;if (sensorId == FingerprintManager.SENSOR_ID_ANY) {provider = getSingleProvider();} else {Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);provider = new Pair<>(sensorId, getProviderForSensor(sensorId));}if (provider == null) {Slog.w(TAG, "Null provider for authenticate");return -1;}final FingerprintSensorPropertiesInternal sensorProps =provider.second.getSensorProperties(sensorId);if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)&& sensorProps != null && sensorProps.isAnyUdfpsType()) {identity = Binder.clearCallingIdentity();try {return authenticateWithPrompt(operationId, sensorProps, userId, receiver,ignoreEnrollmentState);} finally {Binder.restoreCallingIdentity(identity);}}return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,restricted, statsClient, isKeyguard);}
先看第41行代码
provider = getSingleProvider();
@Nullableprivate Pair<Integer, ServiceProvider> getSingleProvider() {final List<FingerprintSensorPropertiesInternal> properties = getSensorProperties();if (properties.isEmpty()) {Slog.e(TAG, "No providers found");return null;}// Theoretically we can just return the first provider, but maybe this is easier to// understand.final int sensorId = properties.get(0).sensorId;for (ServiceProvider provider : mServiceProviders) {if (provider.containsSensor(sensorId)) {return new Pair<>(sensorId, provider);}}Slog.e(TAG, "Provider not found");return null;}
第12行,mServiceProviders集合
private void addHidlProviders(List<FingerprintSensorPropertiesInternal> hidlSensors) {for (FingerprintSensorPropertiesInternal hidlSensor : hidlSensors) {final Fingerprint21 fingerprint21;if ((Build.IS_USERDEBUG || Build.IS_ENG)&& getContext().getResources().getBoolean(R.bool.allow_test_udfps)&& Settings.Secure.getIntForUser(getContext().getContentResolver(),Fingerprint21UdfpsMock.CONFIG_ENABLE_TEST_UDFPS, 0 /* default */,UserHandle.USER_CURRENT) != 0) {fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(),mFingerprintStateCallback, hidlSensor,mLockoutResetDispatcher, mGestureAvailabilityDispatcher);} else {fingerprint21 = Fingerprint21.newInstance(getContext(),mFingerprintStateCallback, hidlSensor,mLockoutResetDispatcher, mGestureAvailabilityDispatcher);}mServiceProviders.add(fingerprint21);}}
再看看
return provider.second.scheduleAuthenticate 方法调用,实际上就是调用Fingerprint21对象实例。注意 这里的second的用法,可以参照pair使用规则。
继续往下看
@Overridepublic void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener,@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,boolean allowBackgroundAuthentication) {mHandler.post(() -> {scheduleUpdateActiveUserWithoutHandler(userId);final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(mContext, mLazyDaemon, token, requestId, listener, userId, operationId,restricted, opPackageName, cookie, false /* requireConfirmation */,mSensorProperties.sensorId, isStrongBiometric, statsClient,mTaskStackListener, mLockoutTracker,mUdfpsOverlayController, mSidefpsController,allowBackgroundAuthentication, mSensorProperties);mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);});}
第17行代码的mScheduler是在这里定义的
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);}
第7行代码,继续往下看,类BiometricScheduler下寻找方法scheduleClientMonitor
public void scheduleClientMonitor(@NonNull BaseClientMonitor clientMonitor,@Nullable BaseClientMonitor.Callback clientCallback) {// If the incoming operation should interrupt preceding clients, mark any interruptable// pending clients as canceling. Once they reach the head of the queue, the scheduler will// send ERROR_CANCELED and skip the operation.if (clientMonitor.interruptsPrecedingClients()) {for (Operation operation : mPendingOperations) {if (operation.mClientMonitor instanceof Interruptable&& operation.mState != Operation.STATE_WAITING_IN_QUEUE_CANCELING) {Slog.d(getTag(), "New client incoming, marking pending client as canceling: "+ operation.mClientMonitor);operation.mState = Operation.STATE_WAITING_IN_QUEUE_CANCELING;}}}mPendingOperations.add(new Operation(clientMonitor, clientCallback));Slog.d(getTag(), "[Added] " + clientMonitor+ ", new queue size: " + mPendingOperations.size());// If the new operation should interrupt preceding clients, and if the current operation is// cancellable, start the cancellation process.if (clientMonitor.interruptsPrecedingClients()&& mCurrentOperation != null&& mCurrentOperation.mClientMonitor instanceof Interruptable&& mCurrentOperation.mState == Operation.STATE_STARTED) {Slog.d(getTag(), "[Cancelling Interruptable]: " + mCurrentOperation);cancelInternal(mCurrentOperation);}startNextOperationIfIdle();}
然后来到方法startNextOperationIfIdle
protected void startNextOperationIfIdle() {if (mCurrentOperation != null) {Slog.v(getTag(), "Not idle, current operation: " + mCurrentOperation);return;}if (mPendingOperations.isEmpty()) {Slog.d(getTag(), "No operations, returning to idle");return;}mCurrentOperation = mPendingOperations.poll();final BaseClientMonitor currentClient = mCurrentOperation.mClientMonitor;Slog.d(getTag(), "[Polled] " + mCurrentOperation);// If the operation at the front of the queue has been marked for cancellation, send// ERROR_CANCELED. No need to start this client.if (mCurrentOperation.mState == Operation.STATE_WAITING_IN_QUEUE_CANCELING) {Slog.d(getTag(), "[Now Cancelling] " + mCurrentOperation);if (!(currentClient instanceof Interruptable)) {throw new IllegalStateException("Mis-implemented client or scheduler, "+ "trying to cancel non-interruptable operation: " + mCurrentOperation);}final Interruptable interruptable = (Interruptable) currentClient;interruptable.cancelWithoutStarting(getInternalCallback());// Now we wait for the client to send its FinishCallback, which kicks off the next// operation.return;}if (mGestureAvailabilityDispatcher != null&& mCurrentOperation.mClientMonitor instanceof AcquisitionClient) {mGestureAvailabilityDispatcher.markSensorActive(mCurrentOperation.mClientMonitor.getSensorId(),true /* active */);}// Not all operations start immediately. BiometricPrompt waits for its operation// to arrive at the head of the queue, before pinging it to start.final boolean shouldStartNow = currentClient.getCookie() == 0;if (shouldStartNow) {if (mCurrentOperation.isUnstartableHalOperation()) {final HalClientMonitor<?> halClientMonitor =(HalClientMonitor<?>) mCurrentOperation.mClientMonitor;// Note down current length of queuefinal int pendingOperationsLength = mPendingOperations.size();final Operation lastOperation = mPendingOperations.peekLast();Slog.e(getTag(), "[Unable To Start] " + mCurrentOperation+ ". Last pending operation: " + lastOperation);// For current operations, 1) unableToStart, which notifies the caller-side, then// 2) notify operation's callback, to notify applicable system service that the// operation failed.halClientMonitor.unableToStart();if (mCurrentOperation.mClientCallback != null) {mCurrentOperation.mClientCallback.onClientFinished(mCurrentOperation.mClientMonitor, false /* success */);}// Then for each operation currently in the pending queue at the time of this// failure, do the same as above. Otherwise, it's possible that something like// setActiveUser fails, but then authenticate (for the wrong user) is invoked.for (int i = 0; i < pendingOperationsLength; i++) {final Operation operation = mPendingOperations.pollFirst();if (operation == null) {Slog.e(getTag(), "Null operation, index: " + i+ ", expected length: " + pendingOperationsLength);break;}if (operation.isHalOperation()) {((HalClientMonitor<?>) operation.mClientMonitor).unableToStart();}if (operation.mClientCallback != null) {operation.mClientCallback.onClientFinished(operation.mClientMonitor,false /* success */);}Slog.w(getTag(), "[Aborted Operation] " + operation);}// It's possible that during cleanup a new set of operations came in. We can try to// run these. A single request from the manager layer to the service layer may// actually be multiple operations (i.e. updateActiveUser + authenticate).mCurrentOperation = null;startNextOperationIfIdle();} else {Slog.d(getTag(), "[Starting] " + mCurrentOperation);currentClient.start(getInternalCallback());mCurrentOperation.mState = Operation.STATE_STARTED;}} else {try {mBiometricService.onReadyForAuthentication(currentClient.getCookie());} catch (RemoteException e) {Slog.e(getTag(), "Remote exception when contacting BiometricService", e);}Slog.d(getTag(), "Waiting for cookie before starting: " + mCurrentOperation);mCurrentOperation.mState = Operation.STATE_WAITING_FOR_COOKIE;}}
见第87行
currentClient.start(getInternalCallback());,这里要分析变量currentClient
//注意这几行代码,是我从源码中挑出来的,非先后顺序关系。@VisibleForTesting @Nullable Operation mCurrentOperation;final BaseClientMonitor currentClient = mCurrentOperation.mClientMonitor;mCurrentOperation = mPendingOperations.poll();mPendingOperations.add(new Operation(clientMonitor, clientCallback));//这里的mCurrentOperation.mClientMonitor实际上就是 clientMonitor//可以去方法scheduleClientMonitor中去寻找逻辑,见前面的部分源码//这里的clientMonitor实际上就是Fingerprint21.scheduleAuthenticate 方法中有定义,在前面有讲解。//就是如下部分。final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(mContext, mLazyDaemon, token, requestId, listener, userId, operationId,restricted, opPackageName, cookie, false /* requireConfirmation */,mSensorProperties.sensorId, isStrongBiometric, statsClient,mTaskStackListener, mLockoutTracker,mUdfpsOverlayController, mSidefpsController,allowBackgroundAuthentication, mSensorProperties);mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
再回到currentClient.start(getInternalCallback());
currentClient 就是对象实例FingerprintAuthenticationClient
public void start(@NonNull Callback callback) {super.start(callback);if (mSensorProps.isAnyUdfpsType()) {// UDFPS requires user to touch before becoming "active"mState = STATE_STARTED_PAUSED;} else {mState = STATE_STARTED;}}
第二行,继续往下找AuthenticationClient 类下的start方法
@Overridepublic void start(@NonNull Callback callback) {super.start(callback);final @LockoutTracker.LockoutMode int lockoutMode =mLockoutTracker.getLockoutModeForUser(getTargetUserId());if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {Slog.v(TAG, "In lockout mode(" + lockoutMode + ") ; disallowing authentication");int errorCode = lockoutMode == LockoutTracker.LOCKOUT_TIMED? BiometricConstants.BIOMETRIC_ERROR_LOCKOUT: BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;onError(errorCode, 0 /* vendorCode */);return;}if (mTaskStackListener != null) {mActivityTaskManager.registerTaskStackListener(mTaskStackListener);}Slog.d(TAG, "Requesting auth for " + getOwnerString());mStartTimeMs = System.currentTimeMillis();mAuthAttempted = true;startHalOperation();}
见第24行startHalOperation(),实际上就是调用到FingerprintAuthenticationClient 类下的
@Overrideprotected void startHalOperation() {mSensorOverlays.show(getSensorId(), getShowOverlayReason(), this);try {// GroupId was never used. In fact, groupId is always the same as userId.getFreshDaemon().authenticate(mOperationId, getTargetUserId());} catch (RemoteException e) {Slog.e(TAG, "Remote exception when requesting auth", e);onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,0 /* vendorCode */);mSensorOverlays.hide(getSensorId());mCallback.onClientFinished(this, false /* success */);}}
getFreshDaemon().authenticate 就是进行指纹服务注册,后面会继续分析相关底层。
继续往下分析getFreshDaemon()
//HalClientMonitor 文件getFreshDaemon()public T getFreshDaemon() {//应该调用到Fingerprint21 类下的getDaemon方法return mLazyDaemon.getDaemon();}//Fingerprint21 文件mLazyDaemon = Fingerprint21.this::getDaemon;
@VisibleForTestingsynchronized 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行,在另外一篇文章 中,会用到
指纹设别流程_liujun3512159的博客-CSDN博客
第16行,mDaemon = IBiometricsFingerprint.getService(),就是hidl调用获取到对应的对象。
IBiometricsFingerprint.getService() 最终的信息在BiometricsFingerprint.cpp中有描述
IBiometricsFingerprint.hal文件如下
/** Copyright (C) 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**/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.biometrics.fingerprint@2.1;import IBiometricsFingerprintClientCallback;interface IBiometricsFingerprint {/*** Set notification callback:* Registers a user function that must receive notifications from the HAL* This call must block if the HAL state machine is in busy state until HAL* leaves the busy state.** @return deviceId is a unique handle for this fingerprint device*/@callflow(next={"setActiveGroup"})@entrysetNotify(IBiometricsFingerprintClientCallback clientCallback)generates (uint64_t deviceId);/*** Fingerprint pre-enroll enroll request:* Generates a unique token to upper layers to indicate the start of* an enrollment transaction. pre-enroll and post-enroll specify* a pin/password cleared time window where enrollment is allowed.* Pre-enroll only generates a challenge, a full hardwareAuthToken is* generated by trustzone after verifying a pin/password/swipe. This is to* ensure adding a new fingerprint template was preceded by some kind of* credential confirmation (e.g. device password).** @return 0 if function failed, a uint64_t of challenge otherwise.*/@callflow(next={"enroll", "postEnroll"})preEnroll() generates (uint64_t authChallenge);/*** Fingerprint enroll request:* Switches the HAL state machine to collect and store a new fingerprint* template. Switches back as soon as enroll is complete, signalled by* (fingerprintMsg.type == FINGERPRINT_TEMPLATE_ENROLLING &&* fingerprintMsg.data.enroll.samplesRemaining == 0)* or after timeoutSec seconds.* The fingerprint template must be assigned to the group gid.** @param hat a valid Hardware Authentication Token (HAT), generated* as a result of a preEnroll() call.* @param gid a framework defined fingerprint set (group) id.* @param timeoutSec a timeout in seconds.** @return debugErrno is a value the framework logs in case it is not 0.** A notify() function may be called with a more detailed error structure.*/@callflow(next={"cancel", "enroll", "postEnroll", "remove"})enroll(uint8_t[69] hat, uint32_t gid, uint32_t timeoutSec)generates (RequestStatus debugErrno);/*** Finishes the enroll operation and invalidates the preEnroll() generated* challenge. This must be called at the end of a multi-finger enrollment* session to indicate that no more fingers may be added.** @return debugErrno is a value the framework logs in case it is not 0.*/@callflow(next={"authenticate", "setActiveGroup", "enumerate", "remove"})postEnroll() generates (RequestStatus debugErrno);/*** getAuthenticatorId:* Returns a token associated with the current fingerprint set. This value* must change whenever a new fingerprint is enrolled, thus creating a new* fingerprint set.** @return getAuthenticatorIdRet current authenticator id, 0 if function* failed.*/@callflow(next={"authenticate"})getAuthenticatorId() generates (uint64_t AuthenticatorId);/*** Cancel pending enroll or authenticate, sending FINGERPRINT_ERROR_CANCELED* to all running clients. Switches the HAL state machine back to the idle* state. Unlike enrollDone() doesn't invalidate the preEnroll() challenge.** @return debugErrno is a value the framework logs in case it is not 0.*/@callflow(next={"authenticate", "enroll", "enumerate", "remove","setActiveGroup"})cancel() generates (RequestStatus debugErrno);/*** Enumerate all the fingerprint templates found in the directory set by* setActiveGroup():* For each template found a notify() must be called with:* fingerprintMsg.type == FINGERPRINT_TEMPLATE_ENUMERATED* fingerprintMsg.data.enumerated.finger indicating a template id* fingerprintMsg.data.enumerated.remainingTemplates indicating how many more* enumeration messages to expect.** @return debugErrno is a value the framework logs in case it is not 0.*/@callflow(next={"remove", "enroll", "authenticate", "setActiveGroup"})enumerate() generates (RequestStatus debugErrno);/*** Fingerprint remove request:* Deletes fingerprint template(s).* Works only within the path set by setActiveGroup().* For each template found a notify() must be called with:* fingerprintMsg.type == FINGERPRINT_TEMPLATE_REMOVED* fingerprintMsg.data.removed.finger indicating the template id deleted* fingerprintMsg.data.removed.remainingTemplates indicating how many more* templates must be deleted by this operation.** @param gid group id must match the last group set by setActiveGroup().* @param fid template id to delete or 0 to delete all templates within the* current group.** @return debugErrno is a value the framework logs in case it is not 0.*/@callflow(next={"enumerate", "authenticate", "cancel", "getAuthenticatorId","setActiveGroup"})remove(uint32_t gid, uint32_t fid) generates (RequestStatus debugErrno);/*** Restricts the HAL operation to a set of fingerprints belonging to a group* provided. The caller must provide a path to a storage location within the* user's data directory.** @param gid the fingerprint group (set) id.* @param storePath filesystem path to the template storage directory.** @return debugErrno is a value the framework logs in case it is not 0.*/@callflow(next={"authenticate", "preEnroll", "enumerate", "remove"})setActiveGroup(uint32_t gid, string storePath)generates (RequestStatus debugErrno);/*** Authenticates an operation identified by operationId** @param operationId operation id.* @param gid fingerprint group id.** @return debugErrno is a value the framework logs in case it is not 0.*/@callflow(next={"cancel", "preEnroll", "remove"})authenticate(uint64_t operationId, uint32_t gid)generates (RequestStatus debugErrno);};
//BiometricsFingerprint.cpp 文件BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) {sInstance = this; // keep track of the most recent instancemDevice = openHal();if (!mDevice) {ALOGE("Can't open HAL module");}}
见第4行openHal方法
//这个方法最终会访问到底层了,比如我们熟悉的hw_get_modulefingerprint_device_t* BiometricsFingerprint::openHal() {int err;const hw_module_t *hw_mdl = nullptr;ALOGD("Opening fingerprint hal library...");if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) {ALOGE("Can't open fingerprint HW Module, error: %d", err);return nullptr;}if (hw_mdl == nullptr) {ALOGE("No valid fingerprint module");return nullptr;}fingerprint_module_t const *module =reinterpret_cast<const fingerprint_module_t*>(hw_mdl);if (module->common.methods->open == nullptr) {ALOGE("No valid open method");return nullptr;}hw_device_t *device = nullptr;if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) {ALOGE("Can't open fingerprint methods, error: %d", err);return nullptr;}if (kVersion != device->version) {// enforce version on new devices because of HIDL@2.1 translation layerALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);return nullptr;}fingerprint_device_t* fp_device =reinterpret_cast<fingerprint_device_t*>(device);if (0 != (err =fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) {ALOGE("Can't register fingerprint module callback, error: %d", err);return nullptr;}return fp_device;}
第40行,设置回调到底软 ,后面有设置
dev->set_notify = set_notify_callback;
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,uint32_t gid) {return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid));}
第25行,module->common.methods->open
全面解析Android系统指纹启动流程_liujun3512159的博客-CSDN博客_android 指纹流程
这个open方法主要是将厂商指纹模组模块的算法识别逻辑结果和HAL层进行绑定(一般是fingerprint.default.so文件),设置回调通知,这个文件一般都不开源,不过Android原生也是有这部分代码的(当然只是看看,并不能使用)
例如,文件Fingerprint.c文件。
static int fingerprint_open(const hw_module_t* module, const char __unused *id,hw_device_t** device){if (device == NULL) {ALOGE("NULL device on open");return -EINVAL;}fingerprint_device_t *dev = malloc(sizeof(fingerprint_device_t));memset(dev, 0, sizeof(fingerprint_device_t));dev->common.tag = HARDWARE_DEVICE_TAG;dev->common.version = FINGERPRINT_MODULE_API_VERSION_2_0;dev->common.module = (struct hw_module_t*) module;dev->common.close = fingerprint_close;dev->pre_enroll = fingerprint_pre_enroll;dev->enroll = fingerprint_enroll;dev->get_authenticator_id = fingerprint_get_auth_id;dev->cancel = fingerprint_cancel;dev->remove = fingerprint_remove;dev->set_active_group = fingerprint_set_active_group;dev->authenticate = fingerprint_authenticate;dev->set_notify = set_notify_callback;dev->notify = NULL;*device = (hw_device_t*) dev;return 0;}static struct hw_module_methods_t fingerprint_module_methods = {.open = fingerprint_open,};fingerprint_module_t HAL_MODULE_INFO_SYM = {.common = {.tag= HARDWARE_MODULE_TAG,.module_api_version = FINGERPRINT_MODULE_API_VERSION_2_0,.hal_api_version = HARDWARE_HAL_API_VERSION,.id = FINGERPRINT_HARDWARE_MODULE_ID,.name= "Demo Fingerprint HAL",.author = "The Android Open Source Project",.methods = &fingerprint_module_methods,},};
好了,指纹服务注册分析到此为止。