第一部分 指纹模块流程分析
一、Fingerprint模块架构
Fingerprint模块架构图如下,这里分为application,framework,fingerprintd和FingerprintHal这几个部分,不涉及指纹的IC库和驱动这部分,这部分逻辑由指纹厂商来实现。
Setting中指纹代码
SystemUI中指纹解锁代码
二、Fingerprint framework初始化流程
在系统开机的时候,会启动各种Service,包括FingerprintService。从下图的开机log(sys_log.boot)中可以看出:
05-29 10:37:57.870869 1127 1127 I SystemServiceManager: Starting com.android.server.dreams.DreamManagerService05-29 10:37:57.874643 1127 1127 I SystemServer: StartAssetAtlasService05-29 10:37:57.883240 1127 1127 I SystemServiceManager: Starting com.android.server.print.PrintManagerService05-29 10:37:57.910104 1127 1127 I SystemServiceManager: Starting com.android.server.restrictions.RestrictionsManagerService05-29 10:37:57.913926 1127 1127 I SystemServiceManager: Starting com.android.server.media.MediaSessionService05-29 10:37:57.926584 1127 1127 I SystemServer: StartMediaRouterService05-29 10:37:57.939619 1127 1127 I SystemServiceManager: Starting com.android.server.trust.TrustManagerService05-29 10:37:57.952689 1127 1127 I SystemServiceManager: Starting com.android.server.fingerprint.FingerprintService05-29 10:37:58.866228 1127 1127 V FingerprintService: Fingerprint HAL id: 48834523596805-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中去,如下图:
将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目录下
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层”
四、指纹录制流程
指纹录制的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,在往上层反馈。这就是指纹的识别流程。