孩子长大,倘无才能,可寻点小事情过活,万不可做空头文学家或美术家。
------ 鲁迅
1. Android R中framework中需要新的配置项才会在SetupWizard中启动Settings的BiometricEnrollActivity界面,否则不会启动指纹录制流程。
<!-- List of biometric sensors on the device, in decreasing strength. Consumed by AuthService
when registering authenticators with BiometricService. Format must be ID:Modality:Strength,
where: IDs are unique per device, Modality as defined in BiometricAuthenticator.java,
and Strength as defined in Authenticators.java -->
<string-array name="config_biometric_sensors" translatable="false" >
<!-- <item>0:2:15</item> ID0:Fingerprint:Strong --> // 这里要定义,否则在服务初始化registerAuthenticator阶段,将没有监测到物理sensor:BIOMETRIC_ERROR_HW_NOT_PRESENT
</string-array>
2. SetupWizard/Settings中录制指纹成功后,SystemUI模块中灭屏逻辑(KeyguardUpdateMonitor::handleStartedGoingToSleep)会去触发启动指纹验证解锁流程。
判断是否可以启动指纹监听:shouldListenForFingerprint--> startListeningForFingerprint --> 调用authenticate方法进入系统层面,这里传入了回调函数mFingerprintAuthenticationCallback用于接受后续的验证成功失败以及错误等回调。
系统端的authenticate方法会去调用FingerprintServiceWrapper类,这个是FingerpringManager和FingerprintService的server端,通过其binder call也可见是manager的server端。
/**
* Receives the incoming binder calls from FingerprintManager.
*/
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@Override // Binder call
public long preEnroll(IBinder token) {}
@Override // Binder call
public int postEnroll(IBinder token) {}
@Override // Binder call
public void enroll(final IBinder token, final byte[] cryptoToken, final int
userId, final IFingerprintServiceReceiver receiver, final int flags,final
String opPackageName) {}
@Override // Binder call
public void authenticate(final IBinder token, final long opId, final int
groupId, final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {}
@Override // Binder call
public void remove(final IBinder token, final int fingerId, final int groupId,
final int userId, final IFingerprintServiceReceiver receiver) {}
@Override // Binder call
public void rename(final int fingerId, final int groupId, final String name) {}
…………………………
}
authenticate --> BiometricServiceBase::authenticateInternal --> startAuthentication -->startClient --> mCurrentClient.start() ==> AuthenticationClient类中的start方法。
在调用过程中authenticateInternal之前,我们创建了client实例,其扩展了AuthenticationClientImpl以及父类AuthenticationClient以及ClientMonitor:
final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(),
mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver),
mCurrentUserId, groupId, opId, restricted, opPackageName,
0 /* cookie */, false /* requireConfirmation */);
其中,SystemUI传入的callback回调,保存在了Manager端的mAuthenticationCallback中,以参数的形式将另外的mServiceReceiver传入了ServiceListenerImpl类中,这个后面会用于回调到SystemUI中。
与daemon通信,DaemonWrapper是FingerprintService的内部辅助类,封装具体调用到Fingerprint Daemon服务的逻辑。
mCurrentClient.start(){
int result = getDaemonWrapper().authenticate(mOpId, getGroupId());
}
/**
* Wraps the HAL-specific code and is passed to the ClientMonitor implementations
so that they
* can be shared between the multiple biometric services.
*/
private final DaemonWrapper mDaemonWrapper = new DaemonWrapper() {
@Override
public int authenticate(long operationId, int groupId) throws RemoteException
{
IBiometricsFingerprint daemon = getFingerprintDaemon();
return daemon.authenticate(operationId, groupId);
}
@Override
public int cancel() throws RemoteException {
IBiometricsFingerprint daemon = getFingerprintDaemon();
return daemon.cancel();
}
@Override
public int remove(int groupId, int biometricId) throws RemoteException {
IBiometricsFingerprint daemon = getFingerprintDaemon();
return daemon.remove(groupId, biometricId);
}
@Override
public int enumerate() throws RemoteException {
IBiometricsFingerprint daemon = getFingerprintDaemon();
return daemon.enumerate();
}
@Override
public int enroll(byte[] cryptoToken, int groupId, int timeout,
ArrayList<Integer> disabledFeatures) throws RemoteException {
IBiometricsFingerprint daemon = getFingerprintDaemon();
return daemon.enroll(cryptoToken, groupId, timeout);
}
};
/** Gets the fingerprint daemon */
private synchronized IBiometricsFingerprint getFingerprintDaemon() {
if (mDaemon == null) {
Slog.v(TAG, "mDaemon was null, reconnect to fingerprint");
try {
// 获取daemon服务
mDaemon = IBiometricsFingerprint.getService();
} catch (java.util.NoSuchElementException e) {
// Service doesn't exist or cannot be opened. Logged below.
} catch (RemoteException e) {
Slog.e(TAG, "Failed to get biometric interface", e);
}
if (mDaemon == null) {
Slog.w(TAG, "fingerprint HIDL not available");
return null;
}
mDaemon.asBinder().linkToDeath(this, 0);
try {
//设置hal daemon到Fingerprint service的回调接口,获取hal设备id。
mHalDeviceId = mDaemon.setNotify(mDaemonCallback);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to open fingerprint HAL", e);
mDaemon = null; // try again later!
}
if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
if (mHalDeviceId != 0) {
loadAuthenticatorIds();
updateActiveGroup(ActivityManager.getCurrentUser(), null);
doTemplateCleanupForUser(ActivityManager.getCurrentUser());
} else {
Slog.w(TAG, "Failed to open Fingerprint HAL!");
MetricsLogger.count(getContext(), "fingerprintd_openhal_error", 1);
mDaemon = null;
}
}
return mDaemon;
}
HAL后面的逻辑这里不分析(后续完善)。当SystemUI通过authenticate启动验证流程后,指纹端就随时监听器件,当有手指按压触发中断,设备端会通过设置到hal的mDaemonCallback回调,调用onAcquired以及onAuthenticated,onAuthenticated方法中携带有指纹验证相关数据。
mDaemonCallback::onAuthenticated --> BiometricServiceBase::handleAuthenticated --> client.onAuthenticated
client是我们之前调用authenticateInternal之前构建的AuthenticationClientImpl,其实现的方法在父类AuthenticationClient中,通过验证identifier的id确认是否通过指纹验证。
final boolean authenticated = identifier.getBiometricId() != 0;
// 这里的listener同样是我们在authenticate时构建的new ServiceListenerImpl(receiver,其receiver就是SystemUI的回调方法。
final BiometricServiceBase.ServiceListener listener = getListener();
if (authenticated) {
listener.onAuthenticationSucceeded();
} else {
listener.onAuthenticationFailedInternal();
}
/**
* Receives callbacks from the ClientMonitor implementations. The results are forwarded to
* the FingerprintManager.
*/
private class ServiceListenerImpl implements ServiceListener {
private IFingerprintServiceReceiver mFingerprintServiceReceiver;
public ServiceListenerImpl(IFingerprintServiceReceiver receiver) {
mFingerprintServiceReceiver = receiver;
}
@Override
public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining)
throws RemoteException {
if (mFingerprintServiceReceiver != null) {
final Fingerprint fp = (Fingerprint) identifier;
mFingerprintServiceReceiver.onEnrollResult(fp.getDeviceId(), fp.getBiometricId(),
fp.getGroupId(), remaining);
}
}
@Override
public void onAcquired(long deviceId, int acquiredInfo, int vendorCode)
throws RemoteException {
if (mFingerprintServiceReceiver != null) {
mFingerprintServiceReceiver.onAcquired(deviceId, acquiredInfo, vendorCode);
}
}
@Override
public void onAuthenticationSucceeded(long deviceId,
BiometricAuthenticator.Identifier biometric, int userId)
throws RemoteException {
if (mFingerprintServiceReceiver != null) {
if (biometric == null || biometric instanceof Fingerprint) {
mFingerprintServiceReceiver.onAuthenticationSucceeded(deviceId,
(Fingerprint) biometric, userId, isStrongBiometric());
} else {
Slog.e(TAG, "onAuthenticationSucceeded received non-fingerprint biometric");
}
}
}
@Override
public void onAuthenticationFailed(long deviceId) throws RemoteException {
if (mFingerprintServiceReceiver != null) {
mFingerprintServiceReceiver.onAuthenticationFailed(deviceId);
}
}
@Override
public void onError(long deviceId, int error, int vendorCode, int cookie)
throws RemoteException {
if (mFingerprintServiceReceiver != null) {
mFingerprintServiceReceiver.onError(deviceId, error, vendorCode);
}
}
}
这里的mFingerprintServiceReceiver是authenticate时,传入的manager内部类,负责将结果进一步封装,通过handler机制,传递回SystemUI中。
private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
@Override // binder call
public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
}
@Override // binder call
public void onAcquired(long deviceId, int acquireInfo, int vendorCode) {
mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, vendorCode,
deviceId).sendToTarget();
}
@Override // binder call
public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId,
boolean isStrongBiometric) {
mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, isStrongBiometric ? 1 : 0,
fp).sendToTarget();
}
@Override // binder call
public void onAuthenticationFailed(long deviceId) {
mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();
}
@Override // binder call
public void onError(long deviceId, int error, int vendorCode) {
mHandler.obtainMessage(MSG_ERROR, error, vendorCode, deviceId).sendToTarget();
}
@Override // binder call
public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
mHandler.obtainMessage(MSG_REMOVED, remaining, 0,
new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
}
@Override // binder call
public void onEnumerated(long deviceId, int fingerId, int groupId, int remaining) {
// TODO: propagate remaining
mHandler.obtainMessage(MSG_ENUMERATED, fingerId, groupId, deviceId).sendToTarget();
}
};
sendAuthenticatedSucceeded方法中的mAuthenticationCallback,即:
// SystemUI中代码:
mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
null, userId);
// 系统处理callback,保存到mAuthenticationCallback
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal
cancel,int flags, @NonNull AuthenticationCallback callback, Handler
handler, int userId) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an authentication callback");
}
if (mService != null) try {
useHandler(handler);
mAuthenticationCallback = callback;
mCryptoObject = crypto;
long sessionId = crypto != null ? crypto.getOpId() : 0;
Slog.i("fingerprint_linhui","authenticate, pkg="+mContext.getOpPackageName(), new Throwable());
mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
mContext.getOpPackageName());
// sendAuthenticatedSucceeded中调用回SystemUI:
private void sendAuthenticatedSucceeded(Fingerprint fp, int userId, boolean isStrongBiometric) {
if (mAuthenticationCallback != null) {
final AuthenticationResult result =
new AuthenticationResult(mCryptoObject, fp, userId, isStrongBiometric);
mAuthenticationCallback.onAuthenticationSucceeded(result);
}
}
}
我们SystemUI中通过如下方法传入的回调了mFingerprintAuthenticationCallback,所以接下来就进入到了SystemUI中的逻辑:
private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
= new AuthenticationCallback() {
@Override
public void onAuthenticationFailed() {
handleFingerprintAuthFailed();
}
@Override
public void onAuthenticationSucceeded(AuthenticationResult result) {
handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric());
}
}
接着就是走解锁的逻辑: onBiometricAuthenticated --> startWakeAndUnlock,后续不再赘述,解锁失败也是同样的回调逻辑。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)