锁屏要使用指纹解锁,首先要注册指纹服务,我看过的一些大厂项目中,实际上是在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>() {
@Override
public 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 call
public 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/79776455
EventLog.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();
@Nullable
private 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;
}
继续搜索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使用规则。
继续往下看
@Override
public 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行代码,继续往下看,类BiometricScheduler
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 queue
final 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方法
@Override
public 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? 类下的
@Override
protected 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;
@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;
}
第16行,mDaemon = IBiometricsFingerprint.getService(),就是hidl调用获取到对应的对象。
IBiometricsFingerprint.getService() 最终的信息在BiometricsFingerprint.cpp中有描述
IBiometricsFingerprint.hal文件如下
/*
* Copyright (C) 2017 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.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"})
@entry
setNotify(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 instance
mDevice = openHal();
if (!mDevice) {
ALOGE("Can't open HAL module");
}
}
见第4行openHal方法
//这个方法最终会访问到底层了,比如我们熟悉的hw_get_module
fingerprint_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 layer
ALOGE("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;
}
好了,指纹服务注册分析到此为止。
|