第一部分 指纹模块流程分析
一、Fingerprint模块架构
Fingerprint模块架构图如下,这里分为application,framework,fingerprintd和FingerprintHal这几个部分,不涉及指纹的IC库和驱动这部分,这部分逻辑由指纹厂商来实现。
![这里写图片描述](https://img-blog.csdn.net/20170607165125316?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hzZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Setting中指纹代码
![这里写图片描述](https://img-blog.csdn.net/20170607165143722?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hzZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
SystemUI中指纹解锁代码
![这里写图片描述](https://img-blog.csdn.net/20170607165203660?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hzZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
二、Fingerprint framework初始化流程
在系统开机的时候,会启动各种Service,包括FingerprintService。从下图的开机log(sys_log.boot)中可以看出:
05-29 10:37:57.870869 1127 1127 I SystemServiceManager: Starting com.android.server.dreams.DreamManagerService
05-29 10:37:57.874643 1127 1127 I SystemServer: StartAssetAtlasService
05-29 10:37:57.883240 1127 1127 I SystemServiceManager: Starting com.android.server.print.PrintManagerService
05-29 10:37:57.910104 1127 1127 I SystemServiceManager: Starting com.android.server.restrictions.RestrictionsManagerService
05-29 10:37:57.913926 1127 1127 I SystemServiceManager: Starting com.android.server.media.MediaSessionService
05-29 10:37:57.926584 1127 1127 I SystemServer: StartMediaRouterService
05-29 10:37:57.939619 1127 1127 I SystemServiceManager: Starting com.android.server.trust.TrustManagerService
05-29 10:37:57.952689 1127 1127 I SystemServiceManager: Starting com.android.server.fingerprint.FingerprintService
05-29 10:37:58.866228 1127 1127 V FingerprintService: Fingerprint HAL id: 488345235968
05-29 10:37:58.867305 1127 1127 I SystemServer: StartBackgroundDexOptService
FingerprintService的启动在SystemServer.Java的startOtherService方法中
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
private void startOtherServices() {
final Context context = mSystemContext;
VibratorService vibrator = null;
IMountService mountService = null;
.......
//启动FingerprintService
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
mSystemServiceManager.startService(FingerprintService.class);
}
......
这里启动的时候,会将FingerprintService添加到ServiceManager中去,如下图:
![这里写图片描述](https://img-blog.csdn.net/20170607165301397?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hzZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
将FingerprintService添加到ServiceManager中后,在SystemServiceRegistry.java中静态代码块中注册服务的时候,可以从ServiceManager中获取FingerprintService的Binder对象,从而可以构造出FingerprintManager对象,这样app端就可以通过Context来获取FingerprintManager对象。另外FingerprintService的onStart()方法中还会调用getFingerprintDaemon()来完成以下步骤:
//①获取fingerprintd
//②向fingerprintd注册回调函数mDaemonCallback
//③调用获取fingerprintd的openhal函数
public IFingerprintDaemon getFingerprintDaemon() {
//①获取fingerprintd
mDaemon = IFingerprintDaemon.Stub.asInterface(ServiceManager.getService(
FINGERPRINTD));
mDaemon.asBinder().linkToDeath(this, 0);
//②向fingerprintd注册回调函数mDaemonCallback
mDaemon.init(mDaemonCallback);
//③调用获取fingerprintd的openhal函数
mHalDeviceId = mDaemon.openHal();
......
}
app端通过Context获取FingerprintManager,通过调用FingerprintManager的接口来实现相应的功能,FingerprintManager转调FingerprintService中方法,FingerprintService负责管理整个注册,识别、删除指纹、检查权限等流程的逻辑,FingerprintService调用fingerprintd的接口,通过fingerprintd和FingerprintHal层进行通信。
三、fingerprintd
fingerprintd在system/core/fingerprintd目录下
![这里写图片描述](https://img-blog.csdn.net/20170607165240129?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hzZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
fingerprintd可以分为四个部分:
1. fingerprintd.cpp “负责将fingerprintd加入到ServiceManager中,以便FingerprintService能够获取”
2. IFingerprintDaemon.h/IFingerprintDaemon.cpp “负责java层到fingerprintd的Binder通信(我们指纹录入和识别都会调用里面的方法)”
3. FingerprintDaemonProxy.h/FingerprintDaemonProxy.cpp “负责fingerprintd和Fignerprint hal层的通信”
4. IFingerprintDaemonCallback.h/IFingerprintDaemonCallback.cpp “负责将指纹的回调结果传给java层”
四、指纹录制流程
![这里写图片描述](https://img-blog.csdn.net/20170607165228160?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hzZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
指纹录制的activity为FingerprintEnrollEnrolling实现了FingerprintEnrollSidecar.Listener 接口。
//指纹录制时提示(比如太快,移动手指之类)
@Override
public void onEnrollmentHelp(CharSequence helpString) {
mErrorText.setText(helpString);
}
//提示指纹录制过程中超时,或者未注册。
@Override
public void onEnrollmentError(int errMsgId, CharSequence errString) {
int msgId;
......
showErrorDialog(getText(msgId), errMsgId);
......
}
//录制过程中进度的变化
@Override
public void onEnrollmentProgressChange(int steps, int remaining) {
updateProgress(true /* animate */);//更新进度
updateDescription();//更新描述
animateFlash();//更新动画
......
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
FingerprintEnrollSidecar的onStart方法中调用了startEnrollment(),该方法中调用FingeprintManager的enroll方法,并且传入了EnrollmentCallback对象,EnrollmentCallback是指纹录入结果的回调,分别调用了FingerprintEnrollSidecar.Listener 接口中的方法,这样就能更新指纹录制的进度和录制结果。
private void startEnrollment() {
......
mFingerprintManager.enroll(mToken, mEnrollmentCancel,
0 /* flags */, mUserId, mEnrollmentCallback);
mEnrolling = true;
}
private FingerprintManager.EnrollmentCallback mEnrollmentCallback
= new FingerprintManager.EnrollmentCallback() {
@Override
public void onEnrollmentProgress(int remaining) {
......
mListener.onEnrollmentProgressChange(mEnrollmentSteps, remaining);
}
}
@Override
public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
if (mListener != null) {
mListener.onEnrollmentHelp(helpString);
}
}
@Override
public void onEnrollmentError(int errMsgId, CharSequence errString) {
if (mListener != null) {
mListener.onEnrollmentError(errMsgId, errString);
}
mEnrolling = false;
}
};
public void enroll(byte [] token, CancellationSignal cancel, int flags,
int userId, EnrollmentCallback callback) {
......
mService.enroll(mToken, token, userId, mServiceReceiver, flags,
mContext.getOpPackageName());
......
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
注意传入的mServiceReceiver对象,这个对象会通过handler发送相关消息去调用EnrollmentCallback或者AuthenticationCallback中方法。
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) {
mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
}
@Override // binder call
public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 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) {
mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
}
@Override // binder call
public void onRemoved(long deviceId, int fingerId, int groupId) {
mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
}
};
public void handleMessage(android.os.Message msg) {
switch(msg.what) {
case MSG_ENROLL_RESULT:
sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
break;
case MSG_ACQUIRED:
sendAcquiredResult((Long) msg.obj /* deviceId */,
msg.arg1 /* acquire info */);
break;
case MSG_AUTHENTICATION_SUCCEEDED:
sendAuthenticatedSucceeded((Fingerprint) msg.obj, msg.arg1 /* userId */);
break;
case MSG_AUTHENTICATION_FAILED:
sendAuthenticatedFailed();
break;
case MSG_ERROR:
sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
break;
case MSG_REMOVED:
sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
msg.arg2 /* groupId */);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
FingerprintManager与FingerprintService直接通过aidl进行通信,在FingerprintService中内部类FingerprintServiceWrapper实现了IFingerprintService.Stub,我们调用的FingerManger的enroll方法就是调用FingerprintServiceWrapper类中的enroll()。
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
......
@Override // Binder call
public void enroll(final IBinder token, final byte[] cryptoToken,
final int userId,final IFingerprintServiceReceiver receiver,
final int flags,
final String opPackageName) {
checkPermission(MANAGE_FINGERPRINT);
final int limit = mContext.getResources().getInteger(
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
final int enrolled = FingerprintService.this.
getEnrolledFingerprints(userId).size();
if (enrolled >= limit) {
Slog.w(TAG, "Too many fingerprints registered");
return;
}
......
mHandler.post(new Runnable() {
@Override
public void run() {
startEnrollment(token, cryptoToken, userId, receiver,
flags,restricted, opPackageName);
}
});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
startEnrollment方法中会调用EnrollClient的start方法,EnrollClient是为给定的客户端跟踪指纹录制状态。
/**
* A class to keep track of the enrollment state for a given client.
*/
public abstract class EnrollClient extends ClientMonitor {
......
public EnrollClient(Context context, long halDeviceId, IBinder token,
IFingerprintServiceReceiver receiver, int userId, int groupId, byte [] cryptoToken,
boolean restricted, String owner) {
super(context, halDeviceId, token, receiver, userId, groupId, restricted, owner);
......
}
@Override
public boolean onEnrollResult(int fingerId, int groupId, int remaining) {
......
return sendEnrollResult(fingerId, groupId, remaining);
}
/*
* @return true if we're done.
*/
private boolean sendEnrollResult(int fpId, int groupId, int remaining) {
IFingerprintServiceReceiver receiver = getReceiver();
......
receiver.onEnrollResult(getHalDeviceId(), fpId, groupId, remaining);
......
}
@Override
public int start() {
IFingerprintDaemon daemon = getFingerprintDaemon();
......
final int result = daemon.enroll(mCryptoToken, getGroupId(), timeout);
......
return 0; // success
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
start方法会调用fingerprintd,调用底层的指纹库,底层库返回结果后会调用onEnrollResult来反馈结果给receiver,在往上层反馈。这就是指纹的录制流程。
五、指纹的解锁流程
指纹解锁的核心类FingerprintUnlockController,实现了KeyguardUpdateMonitorCallback
public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
@Override
public void onFingerprintAuthenticated(int userId) {
......
switch (mMode) {
case MODE_DISMISS_BOUNCER://亮屏并且出现图案锁
mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
false /* strongAuth */);
break;
case MODE_UNLOCK://亮屏不出现图案锁
if (!wasDeviceInteractive) {
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
}
mStatusBarKeyguardViewManager.animateCollapsePanels(
FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
break;
......
case MODE_WAKE_AND_UNLOCK://息屏锁屏解锁
mStatusBarWindowManager.setStatusBarFocusable(false);
mDozeScrimController.abortPulsing();
mKeyguardViewMediator.onWakeAndUnlocking();
mScrimController.setWakeAndUnlocking();
if (mPhoneStatusBar.getNavigationBarView() != null) {
mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
}
break;
......
case MODE_DISMISS_KEYGUARD://通话界面息屏解锁
mStatusBarWindowManager.setStatusBarFocusable(false);
mKeyguardViewMediator.onWakeAndUnlocking();
if (mPhoneStatusBar.getNavigationBarView() != null) {
mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
}
break;
}
......
}
@Override
public void onFinishedGoingToSleep(int why) {
......
}
@Override
public void onFingerprintAuthFailed() {
cleanup();
}
@Override
public void onFingerprintError(int msgId, String errString) {
cleanup();
if(Settings.Global.getInt(mContext.getContentResolver(),"persist.fg.errorshow",0) == 0){
if(!mPowerManager.isScreenOn()){
mPowerManager.wakeUp(SystemClock.uptimeMillis());
}else {
mStatusBarKeyguardViewManager.animateCollapsePanels(
FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
}
Settings.Global.putInt(mContext.getContentResolver(),"persist.fg.errorshow",1);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
KeyguardUpdateMonitor类为解锁屏模块的监听者,它负责监听时间、sim卡、运营商信息、电池信息、电话信息等状态的变化,并通知keyguard View模块更新显示。这个类里面还有有监听指纹的方法startListeningForFingerprint, 该方法调用了FingerprintManager的authenticate()方法并且参数中传入了AuthenticationCallback对象,AuthenticationCallback类中调用了KeyguardUpdateMonitorCallback的方法,FingerprintUnlockController实现了KeyguardUpdateMonitorCallback这样就能实现指纹解锁。
private void startListeningForFingerprint() {
......
//调用了FingerprintManager的authenticate()方法
mFpm.authenticate(null, mFingerprintCancelSignal, 0,
mAuthenticationCallback, null, userId);
......
}
private FingerprintManager.AuthenticationCallback mAuthenticationCallback
= new AuthenticationCallback() {
//指纹匹配失败(没超过5次)
@Override
public void onAuthenticationFailed() {
handleFingerprintAuthFailed();
};
//指纹匹配成功
@Override
public void onAuthenticationSucceeded(AuthenticationResult result) {
handleFingerprintAuthenticated(result.getUserId());
}
//指纹匹配提示
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
handleFingerprintHelp(helpMsgId, helpString.toString());
}
//指纹匹配错误(匹配失败次数超过5次)
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
handleFingerprintError(errMsgId, errString.toString());
}
//获得到指纹
@Override
public void onAuthenticationAcquired(int acquireInfo) {
if(Settings.Global.getInt(mContext.getContentResolver(),"persist.
fg.errorshow",0) == 1){
Settings.Global.putInt(mContext.getContentResolver(),"persist
.fg.errorshow",0);
}
handleFingerprintAcquired(acquireInfo);
}
};
private void handleFingerprintAuthenticated(int authUserId) {
......
onFingerprintAuthenticated(userId);
......
private void onFingerprintAuthenticated(int userId) {
mUserFingerprintAuthenticated.put(userId, true);
......
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
//这里会调用FingerprintUnLockController中的onFingerprintAuthenticated方法处理解锁
cb.onFingerprintAuthenticated(userId);
}
}
.....
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
回来继续看FingerprintManager的authenticate()方法,此方法继续调用了FingerprintServiceWarpper的authenticate方法(FingerprintManager与FingerprintService直接通过aidl来通信)。
public void authenticate(@Nullable CryptoObject crypto, @Nullable
......
mService.authenticate(mToken, sessionId, userId, mServiceReceiver,
flags,mContext.getOpPackageName());
......
}
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@Override // Binder call
public void authenticate(final IBinder token, final long opId,
final int groupId,final IFingerprintServiceReceiver receiver,
final int flags,final String opPackageName) {
startAuthentication(token, opId, callingUserId, groupId,
receiver, flags, restricted, opPackageName);
}
startAuthentication方法会调用AuthenticationClient的start方法,AuthenticationClient
是为给定的客户端跟踪指纹认证状态。
public abstract class AuthenticationClient extends ClientMonitor {
public AuthenticationClient(Context context, long halDeviceId, IBinder token,
IFingerprintServiceReceiver receiver, int targetUserId,
int groupId, long opId,boolean restricted, String owner) {
super(context, halDeviceId, token, receiver, targetUserId,
groupId, restricted, owner);
}
//指纹库处理结果调用
@Override
public boolean onAuthenticated(int fingerId, int groupId) {
......
boolean authenticated = fingerId != 0;
if (!authenticated) {
//认证失败
receiver.onAuthenticationFailed(getHalDeviceId());
} else {
//认证成功
receiver.onAuthenticationSucceeded(getHalDeviceId(), fp, getTargetUserId());
}
if (!authenticated) {
if (inLockoutMode) {
//认证错误
receiver.onError(getHalDeviceId(),
FingerprintManager.FINGERPRINT_ERROR_LOCKOUT);
}
}
......
}
/**
* Start authentication
*/
@Override
public int start() {
IFingerprintDaemon daemon = getFingerprintDaemon();
......
final int result = daemon.authenticate(mOpId, getGroupId());
......
return 0; // success
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
start方法会调用fingerprintd,调用底层的指纹库,底层库返回结果后会调用onAuthenticated来反馈结果给receiver,在往上层反馈。这就是指纹的识别流程。