【 Android 10 生物识别 】系列 -- Fingerprint_指纹录入流程
# 前言
由于源码分析的代码量比较大,大部分博客网站的内容显示页面都比较窄,显示出来的效果都异常丑陋,所以您也可以直接查看 《 Thinking in Android 》 来阅读这边文章(也可以点击 RSS 订阅查看代码更方便),希望这篇文章能帮你梳理清楚“指纹注册流程”。
# 核心源码
关键类 | 路径 |
---|---|
FingerprintEnrollIntroduction.java | packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java |
BiometricEnrollIntroduction.java | packages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java |
FingerprintEnrollEnrolling.java | packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java |
BiometricsEnrollEnrolling.java | packages/apps/Settings/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java |
FingerprintEnrollSidecar.java | packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java |
BiometricEnrollSidecar.java | packages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollSidecar.java |
FingerprintEnrollFindSensor.java | packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java |
FingerprintManager.java | frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager.java |
FingerprintService.java | frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java |
BiometricServiceBase.java | frameworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.java |
EnrollClient.java | frameworks/base/services/core/java/com/android/server/biometrics/EnrollClient.java |
# 相关类
关键类 | 说明 |
---|---|
BiometricEnrollBase | 指纹录制的基类。 |
FingerprintEnrollFindSensor |
指纹开始准备录入的 Activity,继承 BiometricEnrollBase 。
|
FingerprintEnrollSidecar |
注册 EnrollmentCallback ,监听指纹录入状态,继承 BiometricEnrollSidecar 。
|
FingerprintEnrollEnrolling |
指纹录入过程的 Activity,继承 BiometricEnrollBase 类。
|
FingerprintEnrollFinish |
指纹录制结束后调用的 Activity,继承 BiometricEnrollBase 类。
|
FingerprintRemoveSidecar | 管理指纹删除操作。 |
FingerprintFindSensorAnimation | 指纹动画接口。 |
FingerprintLocationAnimationView |
指纹动画,实现了 FingerprintFindSensorAnimation 接口。
|
本篇文章,我们从源码角度探讨指纹录入的过程(测试样机:Pixel),我们先看下 UI 图,这个你应该不陌生了。
一、FingerprintEnrollIntroduction
接下来我们就从指纹引导界面开始源码分析,图 1 的逻辑就在 FingerprintEnrollIntroduction
类,点击 Next
执行下一步,会执行 onNextButtonClick()
方法。
1.1 FingerprintEnrollIntroduction.onNextButtonClick()
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.javapublic class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mFingerprintManager = Utils.getFingerprintManagerOrNull(this);mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);// Cancel ButtonmFooterBarMixin.setSecondaryButton(new FooterButton.Builder(this).setText(R.string.security_settings_face_enroll_introduction_cancel).setListener(this::onCancelButtonClick).setButtonType(FooterButton.ButtonType.SKIP).setTheme(R.style.SudGlifButton_Secondary).build());// Next ButtonmFooterBarMixin.setPrimaryButton(new FooterButton.Builder(this).setText(R.string.wizard_next).setListener(this::onNextButtonClick) // 点击 "下一步" 的处理流程.setButtonType(FooterButton.ButtonType.NEXT).setTheme(R.style.SudGlifButton_Primary).build());}}
我们可以发现:FingerprintEnrollIntroduction
继承自 BiometricEnrollIntroduction
,onNextButtonClick()
方法在其父类 BiometricEnrollIntroduction
中处理。
二、BiometricEnrollIntroduction
2.1 BiometricEnrollIntroduction.onNextButtonClick()
// packages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollIntroduction.javapublic abstract class BiometricEnrollIntroduction extends BiometricEnrollBaseimplements LinkSpan.OnClickListener {@Overrideprotected void onNextButtonClick(View view) {mNextClicked = true;if (checkMaxEnrolled() == 0) {// Lock thingy is already set up, launch directly to the next pagelaunchNextEnrollingActivity(mToken); // 接下来就要拉起指纹录入界面} else {setResult(RESULT_FINISHED);finish();}}}
2.2 BiometricEnrollIntroduction.launchNextEnrollingActivity()
// packages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollIntroduction.javapublic abstract class BiometricEnrollIntroduction extends BiometricEnrollBaseimplements LinkSpan.OnClickListener {private void launchNextEnrollingActivity(byte[] token) {Intent intent = getEnrollingIntent(); // 获取 FingerprintEnrollFindSensorif (token != null) {intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);}if (mUserId != UserHandle.USER_NULL) {intent.putExtra(Intent.EXTRA_USER_ID, mUserId);}intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, mFromSettingsSummary);startActivityForResult(intent, BIOMETRIC_FIND_SENSOR_REQUEST); // 跳转 FingerprintEnrollFindSensor}}
我们看下 getEnrollingIntent()
方法:
// packages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollIntroduction.javapublic abstract class BiometricEnrollIntroduction extends BiometricEnrollBaseimplements LinkSpan.OnClickListener {protected abstract Intent getEnrollingIntent(); // 抽象方法,由子类 FingerprintEnrollIntroduction 实现}
所以我们跳转到 FingerprintEnrollIntroduction
:
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.javapublic class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {@Overrideprotected Intent getEnrollingIntent() {return new Intent(this, FingerprintEnrollFindSensor.class); // 获取 FingerprintEnrollFindSensor}}
三、FingerprintEnrollFindSensor
我们把上面的图再拿过来,此时就进入了图 2 界面的逻辑,我们接着往下看。
3.1 FingerprintEnrollFindSensor.onCreate()
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.javapublic class FingerprintEnrollFindSensor extends BiometricEnrollBase {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(getContentView());mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);// Skip buttonmFooterBarMixin.setSecondaryButton(new FooterButton.Builder(this).setText(R.string.skip_label).setListener(this::onSkipButtonClick).setButtonType(FooterButton.ButtonType.SKIP).setTheme(R.style.SudGlifButton_Secondary).build());// Touch the sensorsetHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);// 执行 startLookingForFingerprint() 方法startLookingForFingerprint(); // already confirmed, so start looking for fingerprint// 演示动画View animationView = findViewById(R.id.fingerprint_sensor_location_animation);if (animationView instanceof FingerprintFindSensorAnimation) {mAnimation = (FingerprintFindSensorAnimation) animationView;} else {mAnimation = null;}}}
到这里都只是涉及到 UI 界面的相关逻辑,接下来的代码逻辑就稍微复杂一点了,我们仔细深挖研究。
3.2 FingerprintEnrollFindSensor.startLookingForFingerprint()
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.javapublic class FingerprintEnrollFindSensor extends BiometricEnrollBase {private FingerprintEnrollSidecar mSidecar;private boolean mNextClicked;private void startLookingForFingerprint() {// FingerprintEnrollSidecar 这个 fragment 的生命周期正式开启mSidecar = (FingerprintEnrollSidecar) getSupportFragmentManager().findFragmentByTag(FingerprintEnrollEnrolling.TAG_SIDECAR);if (mSidecar == null) {mSidecar = new FingerprintEnrollSidecar();// 添加 FingerprintEnrollEnrollinggetSupportFragmentManager().beginTransaction().add(mSidecar, FingerprintEnrollEnrolling.TAG_SIDECAR).commitAllowingStateLoss();}// FingerprintEnrollEnrolling 实现了 BiometricEnrollSidecar.Listener 接口mSidecar.setListener(new Listener() { // 匿名内部类的方式实现接口方法@Overridepublic void onEnrollmentProgressChange(int steps, int remaining) {mNextClicked = true;proceedToEnrolling(true /* cancelEnrollment */);}@Overridepublic void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {}@Overridepublic void onEnrollmentError(int errMsgId, CharSequence errString) {if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {mNextClicked = false;proceedToEnrolling(false /* cancelEnrollment */);}}});}}
这里面有个重点方法:onEnrollmentProgressChange()
,如果我们此时用手指贴在指纹传感器上,会产生反馈信息的回调,此时 onEnrollmentProgressChange()
方法被执行,进入执行 proceedToEnrolling()
方法,我们看下这个方法:
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.javapublic class FingerprintEnrollFindSensor extends BiometricEnrollBase {private void proceedToEnrolling(boolean cancelEnrollment) {if (mSidecar != null) {if (cancelEnrollment) {if (mSidecar.cancelEnrollment()) {// Enrollment cancel requested. When the cancellation is successful,// onEnrollmentError will be called with FINGERPRINT_ERROR_CANCELED, calling// this again.return;}}getSupportFragmentManager().beginTransaction().remove(mSidecar).commitAllowingStateLoss();mSidecar = null;// getFingerprintEnrollingIntent() 方法会返回一个包含 FingerprintEnrollEnrolling 的 IntentstartActivityForResult(getFingerprintEnrollingIntent(), ENROLL_REQUEST);}}}
正常流程会走到 startActivityForResult()
方法,跳转到 FingerprintEnrollEnrolling
界面。
四、FingerprintEnrollEnrolling
我们把上面的图再拿过来,此时就进入了图 3 界面的逻辑,我们接着往下看。
4.1 FingerprintEnrollEnrolling.onStart()
我们重点关注 onStart()
方法:
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java/*** Activity which handles the actual enrolling for fingerprint.*/
public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {@Overrideprotected void onStart() {super.onStart(); // 调用父类 BiometricEnrollSidecar 的 onStart() 方法updateProgress(false /* animate */); // 更新录入进度updateDescription();if (mRestoring) {startIconAnimation();}}}
FingerprintEnrollEnrolling
类继承自 BiometricsEnrollEnrolling
类,而 BiometricsEnrollEnrolling
类实现了 BiometricEnrollSidecar.Listener
接口,所以 FingerprintEnrollEnrolling
也实现了 BiometricEnrollSidecar.Listener
接口。
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java/*** Activity which handles the actual enrolling for fingerprint.*/
public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {// 指纹录制时提示(比如太快,移动手指之类)@Overridepublic void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {if (!TextUtils.isEmpty(helpString)) {mErrorText.removeCallbacks(mTouchAgainRunnable);showError(helpString);}}// 提示指纹录制过程中超时,或者未注册@Overridepublic void onEnrollmentError(int errMsgId, CharSequence errString) {int msgId;switch (errMsgId) {case FingerprintManager.FINGERPRINT_ERROR_TIMEOUT:msgId = R.string.security_settings_fingerprint_enroll_error_timeout_dialog_message;break;default:msgId = R.string.security_settings_fingerprint_enroll_error_generic_dialog_message;break;}showErrorDialog(getText(msgId), errMsgId);stopIconAnimation();mErrorText.removeCallbacks(mTouchAgainRunnable);}// 录制过程中进度的变化(手指按压指纹传感区,onEnrollmentProgressChange() 会被触发,执行一系列处理工作)@Overridepublic void onEnrollmentProgressChange(int steps, int remaining) {updateProgress(true /* animate */); // 更新进度updateDescription(); // 更新描述clearError();animateFlash(); // 更新动画mErrorText.removeCallbacks(mTouchAgainRunnable);mErrorText.postDelayed(mTouchAgainRunnable, HINT_TIMEOUT_DURATION);}}
五、BiometricsEnrollEnrolling
5.1 BiometricsEnrollEnrolling.onStart()
// packages/apps/Settings/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.javapublic abstract class BiometricsEnrollEnrolling extends BiometricEnrollBaseimplements BiometricEnrollSidecar.Listener {@Overrideprotected void onStart() {super.onStart();if (shouldStartAutomatically()) { // 恒定为 truestartEnrollment(); // 调用 startEnrollment() 方法}}}
5.2 BiometricsEnrollEnrolling.startEnrollment()
// packages/apps/Settings/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.javapublic abstract class BiometricsEnrollEnrolling extends BiometricEnrollBaseimplements BiometricEnrollSidecar.Listener {protected BiometricEnrollSidecar mSidecar;protected abstract BiometricEnrollSidecar getSidecar(); // 抽象方法,由子类实现public void startEnrollment() {// 调用 BiometricEnrollSidecar 的 onStart() 方法mSidecar = (BiometricEnrollSidecar) getSupportFragmentManager().findFragmentByTag(TAG_SIDECAR);if (mSidecar == null) {mSidecar = getSidecar(); // 获取 mSidecargetSupportFragmentManager().beginTransaction().add(mSidecar, TAG_SIDECAR).commitAllowingStateLoss();}mSidecar.setListener(this);}}// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.javapublic class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {@Overrideprotected BiometricEnrollSidecar getSidecar() {// 返回了一个继承自 BiometricEnrollSidecar 的 FingerprintEnrollSidecar 对象return new FingerprintEnrollSidecar();}}
六、FingerprintEnrollSidecar
6.1 FingerprintEnrollSidecar.startEnrollment()
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java/*** Sidecar fragment to handle the state around fingerprint enrollment.*/
public class FingerprintEnrollSidecar extends BiometricEnrollSidecar {private FingerprintManager mFingerprintManager;@Overrideprotected void startEnrollment() {super.startEnrollment();if (mUserId != UserHandle.USER_NULL) {mFingerprintManager.setActiveUser(mUserId);}/** 调用 FingeprintManager 的 enroll() 方法开始录入,并且传入了 EnrollmentCallback 对象* EnrollmentCallback 是指纹录入结果的回调,分别调用了 BiometricEnrollSidecar.Listener 接口中的方法,* 这样就能更新指纹录制的进度和录制结果。*/mFingerprintManager.enroll(mToken, mEnrollmentCancel, 0 /* flags */, mUserId, mEnrollmentCallback);}
我们看下 EnrollmentCallback
对象是什么:
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.javapublic class FingerprintEnrollSidecar extends BiometricEnrollSidecar {private FingerprintManager.EnrollmentCallback mEnrollmentCallback= new FingerprintManager.EnrollmentCallback() {@Overridepublic void onEnrollmentProgress(int remaining) {FingerprintEnrollSidecar.super.onEnrollmentProgress(remaining);}@Overridepublic void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {FingerprintEnrollSidecar.super.onEnrollmentHelp(helpMsgId, helpString);}@Overridepublic void onEnrollmentError(int errMsgId, CharSequence errString) {FingerprintEnrollSidecar.super.onEnrollmentError(errMsgId, errString);}};}
七、FingerprintManager
7.1 FingerprintManager.enroll()
// frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager.javapublic class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants {private IFingerprintService mService;// CancellationSignal 类提供删除信号类,提供终止操作的能力@RequiresPermission(MANAGE_FINGERPRINT)public void enroll(byte [] token, CancellationSignal cancel, int flags,int userId, EnrollmentCallback callback) {if (userId == UserHandle.USER_CURRENT) {userId = getCurrentUserId();}if (callback == null) {throw new IllegalArgumentException("Must supply an enrollment callback");}if (cancel != null) {if (cancel.isCanceled()) {Slog.w(TAG, "enrollment already canceled");return;} else {cancel.setOnCancelListener(new OnEnrollCancelListener());}}if (mService != null) try {mEnrollmentCallback = callback;// 调用 FingerprintServiceWrapper 的 enroll() 方法mService.enroll(mToken, token, userId, mServiceReceiver, flags,mContext.getOpPackageName());} catch (RemoteException e) {Slog.w(TAG, "Remote exception in enroll: ", e);if (callback != null) {// Though this may not be a hardware issue, it will cause apps to give up or try// again later.callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE,0 /* vendorCode */));}}}}
八、FingerprintService
8.1 FingerprintServiceWrapper.enroll()
FingerprintManager
与 FingerprintService
直接通过 aidl
进行通信,在 FingerprintService
中内部类 FingerprintServiceWrapper
实现了 IFingerprintService.Stub
,我们调用的 FingerManger
的 enroll()
方法就是调用 FingerprintServiceWrapper
类中的 enroll()
方法。
// frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.javapublic class FingerprintService extends BiometricServiceBase {/*** Receives the incoming binder calls from FingerprintManager.*/private final class FingerprintServiceWrapper extends IFingerprintService.Stub {@Override // Binder callpublic void enroll(final IBinder token, final byte[] cryptoToken, final int userId,final IFingerprintServiceReceiver receiver, final int flags,final String opPackageName) {checkPermission(MANAGE_FINGERPRINT);final boolean restricted = isRestricted();final int groupId = userId; // default group for fingerprint enrollmentfinal EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper,mHalDeviceId, token, new ServiceListenerImpl(receiver), mCurrentUserId, groupId,cryptoToken, restricted, opPackageName, new int[0] /* disabledFeatures */,ENROLL_TIMEOUT_SEC) {@Overridepublic boolean shouldVibrate() {return true;}@Overrideprotected int statsModality() {return FingerprintService.this.statsModality();}};enrollInternal(client, userId); // 调用 BiometricServiceBase 的 enrollInternal() 方法}}}
九、BiometricServiceBase
9.1 BiometricServiceBase.enrollInternal()
// frameworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.javapublic abstract class BiometricServiceBase extends SystemServiceimplements IHwBinder.DeathRecipient {protected void enrollInternal(EnrollClientImpl client, int userId) {if (hasReachedEnrollmentLimit(userId)) {return;}// Group ID is arbitrarily set to parent profile user ID. It just represents// the default biometrics for the user.if (!isCurrentUserOrProfile(userId)) {return;}mHandler.post(() -> {startClient(client, true /* initiatedByClient */); // 调用 startClient() 方法});} }
9.2 BiometricServiceBase.startClient()
// frameworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.javapublic abstract class BiometricServiceBase extends SystemServiceimplements IHwBinder.DeathRecipient {private void startClient(ClientMonitor newClient, boolean initiatedByClient) {ClientMonitor currentClient = mCurrentClient;if (currentClient != null) {if (DEBUG) Slog.v(getTag(), "request stop current client " +currentClient.getOwnerString());if (currentClient instanceof InternalEnumerateClient|| currentClient instanceof InternalRemovalClient) {if (newClient != null) {Slog.w(getTag(), "Internal cleanup in progress but trying to start client "+ newClient.getClass().getSuperclass().getSimpleName()+ "(" + newClient.getOwnerString() + ")"+ ", initiatedByClient = " + initiatedByClient);}} else {currentClient.stop(initiatedByClient);mHandler.removeCallbacks(mResetClientState);mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);}mPendingClient = newClient;} else if (newClient != null) {if (newClient instanceof AuthenticationClient) {AuthenticationClient client = (AuthenticationClient) newClient;if (client.isBiometricPrompt()) {if (DEBUG) Slog.v(getTag(), "Returning cookie: " + client.getCookie());mCurrentClient = newClient;if (mBiometricService == null) {mBiometricService = IBiometricService.Stub.asInterface(ServiceManager.getService(Context.BIOMETRIC_SERVICE));}try {mBiometricService.onReadyForAuthentication(client.getCookie(),client.getRequireConfirmation(), client.getTargetUserId());} catch (RemoteException e) {Slog.e(getTag(), "Remote exception", e);}return;}}// We are not a BiometricPrompt client, start the client immediatelymCurrentClient = newClient;startCurrentClient(mCurrentClient.getCookie()); // 调用 startCurrentClient() 方法}}}
9.3 BiometricServiceBase.startCurrentClient()
// frameworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.javapublic abstract class BiometricServiceBase extends SystemServiceimplements IHwBinder.DeathRecipient {private ClientMonitor mCurrentClient;protected void startCurrentClient(int cookie) {if (mCurrentClient == null) {Slog.e(getTag(), "Trying to start null client!");return;}if (DEBUG) Slog.v(getTag(), "starting client "+ mCurrentClient.getClass().getSuperclass().getSimpleName()+ "(" + mCurrentClient.getOwnerString() + ")"+ " targetUserId: " + mCurrentClient.getTargetUserId()+ " currentUserId: " + mCurrentUserId+ " cookie: " + cookie + "/" + mCurrentClient.getCookie());if (cookie != mCurrentClient.getCookie()) {Slog.e(getTag(), "Mismatched cookie");return;}notifyClientActiveCallbacks(true);mCurrentClient.start(); // 调用 EnrollClient 的 start() 方法}}
十、EnrollClient
10.1 EnrollClient.start()
// frameworks/base/services/core/java/com/android/server/biometrics/EnrollClient.java// EnrollClient 是为给定的客户端跟踪指纹录制状态
public abstract class EnrollClient extends ClientMonitor {// start 方法会调用 fingerprintd,调用底层的指纹库,底层库返回结果后会调用 onEnrollResult 来反馈结果给 receiver,再往上层反馈。@Overridepublic int start() {mEnrollmentStartTimeMs = System.currentTimeMillis();try {final ArrayList<Integer> disabledFeatures = new ArrayList<>();for (int i = 0; i < mDisabledFeatures.length; i++) {disabledFeatures.add(mDisabledFeatures[i]);}final int result = getDaemonWrapper().enroll(mCryptoToken, getGroupId(), mTimeoutSec,disabledFeatures);if (result != 0) {Slog.w(getLogTag(), "startEnroll failed, result=" + result);mMetricsLogger.histogram(mConstants.tagEnrollStartError(), result);onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,0 /* vendorCode */);return result;}} catch (RemoteException e) {Slog.e(getLogTag(), "startEnroll failed", e);}return 0; // success}}
getDaemonWrapper().enroll()
会调用 fingerprintd
,调用底层的指纹库,底层库返回结果后会调用 onEnrollResult
来反馈结果给 receiver
,在往上层反馈。这就是指纹的录制流程。
// frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager.javapublic class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants {private Handler mHandler;// mServiceReceiver 对象会通过 handler 发送相关消息去调用 EnrollmentCallback 或者 AuthenticationCallback 中方法private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {@Override // binder callpublic 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 callpublic void onAcquired(long deviceId, int acquireInfo, int vendorCode) {mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, vendorCode,deviceId).sendToTarget();}@Override // binder callpublic void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, fp).sendToTarget();}@Override // binder callpublic void onAuthenticationFailed(long deviceId) {mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();}@Override // binder callpublic void onError(long deviceId, int error, int vendorCode) {mHandler.obtainMessage(MSG_ERROR, error, vendorCode, deviceId).sendToTarget();}@Override // binder callpublic 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 callpublic void onEnumerated(long deviceId, int fingerId, int groupId, int remaining) {// TODO: propagate remainingmHandler.obtainMessage(MSG_ENUMERATED, fingerId, groupId, deviceId).sendToTarget();}};private class MyHandler extends Handler {private MyHandler(Context context) {super(context.getMainLooper());}private MyHandler(Looper looper) {super(looper);}@Overridepublic 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 */,msg.arg2 /* vendorCode */);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 */,msg.arg2 /* vendorCode */);break;case MSG_REMOVED:sendRemovedResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);break;case MSG_ENUMERATED:sendEnumeratedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,msg.arg2 /* groupId */);break;}}};
}
看下 MSG_ENROLL_RESULT
:
// frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager.javapublic class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants {private void sendEnrollResult(Fingerprint fp, int remaining) {if (mEnrollmentCallback != null) {// 调用 EnrollmentCallback 的 onEnrollmentProgress 方法mEnrollmentCallback.onEnrollmentProgress(remaining);}}}
# Enroll 流程图
【 Android 10 生物识别 】系列 -- Fingerprint_指纹录入流程相关推荐
- 【 Android 10 系统启动 】系列 -- ShutdownThread(关机流程)
# 前言 由于源码分析的代码量比较大,大部分博客网站的内容显示页面都比较窄,显示出来的效果都异常丑陋,所以您也可以直接查看 < Thinking in Android > 来阅读这边文章, ...
- 生物解锁--指纹录入流程
直接从FingerprintManager.java类开始讲起. 首先从enroll方法作为入口 /*** Request fingerprint enrollment. This call warm ...
- android懒加载单实例,【 Android 10 设计模式 】系列 -- 单例
前言 由于源码分析的代码量比较大,大部分博客网站的内容显示页面都比较窄,显示出来的效果都异常丑陋,所以您也可以直接查看 < Thinking in Android > 来阅读这边文章,希望 ...
- android launcher目录,【 Android 10 系统启动 】系列 -- Launcher(应用门户)
前言 由于源码分析的代码量比较大,大部分博客网站的内容显示页面都比较窄,显示出来的效果都异常丑陋,所以您也可以直接查看 < Thinking in Android > 来阅读这边文章,希望 ...
- 【Android 10 源码】Camera v1 startPreview 流程
Camera v1 startPreview 起点位于 android.hardware 包下的 Camera 类中,这是老版本的 Camera 预览的起点. 上面这张相机架构图左边就是关于 Came ...
- 优麒麟 mysql_优麒麟18.10新特性预览—生物识别
随着优麒麟18.10正式发布的日子越来越近,小编又给大家带来了一个激动人心的功能.我们知道现在越来越多的电脑都带有指纹解锁的功能,但是我们的各大linux发行版却不支持,我们广大linuxer怎么能容 ...
- linux kylin使用手册,优麒麟Ubuntu Kylin 18.10中的生物识别管理工具,附使用方法
优麒麟Ubuntu Kylin 18.10有一个生物识别管理工具,可对生物特征管理.当前越来越多的电脑都搭载有指纹解锁的功能,Ubuntu Kylin 18.10增加了生物识别的支持,下面我们一起来看 ...
- NEC为印度Aadhaar项目提供的生物识别系统注册人数突破10亿
由NEC提供生物识别系统.印度国民ID管理局(简称UIDAI)主导进行并可为每位国民签发独有身份ID的Aadhaar项目,截至2016年4月其注册人数已经突破10亿.NEC通过提供集指纹 面部 虹膜等 ...
- 人脸识别与膜虹识别_指纹,人脸,虹膜三种生物识别优缺点比较
就生物识别本身来说,也可以分为指纹识别.人脸识别.虹膜识别.掌/指纹静脉识别等.各种识别方式因各自特性适用于不同的领域.下面将其中应用最广泛的三种识别进行比较介绍. 指纹识别:便捷易操作,但存在被复制 ...
- 生物识别:怎样才能把想象力转化成商机
新模式.新市场.新技术尚待时间检验 生物识别,一种既熟悉又神秘的高科技.人们常常在电影中看到关于生物识别一系列眼花缭乱的应用:例如用虹膜识别进入金库.用指纹识别进入实验室,或是用语音识别向家中的机器人 ...
最新文章
- 阿里开源项目汇总(二十)
- 商城网站该如何选择虚拟主机
- UVa 10570 - Meeting with Aliens
- bzoj4171: Rhl的游戏
- 网络请求 get 请求时, 如果参数中的字符带有+号
- 踢向《英雄王座》的面目全非脚
- [kuangbin带你飞]专题一 简单搜索 - H - Pots
- matlab read grads,讲解:Grads Only、Network、Matlab、MatlabProcessing|P
- php url 转码,php url中文转码的方法
- python3超简代码爬取桌面壁纸
- PMP备考大全:经典题库(8月第4周)
- 《小话投行》转自2011 Morgan Stanley HK IBD唯一的大陆本科生
- Docker (四) 容器基本命令
- 作为一名IT工程师该如何提前预防职业病
- DragonEnglish——COCA20000单词+音频+释义+例句及翻译内容聚合
- 在线教育平台项目——整体架构
- 超详解The server time zone value ‘�й���ʱ��‘ is unrecognized or represents more than one time zone
- java开源自定义表单_java开发自定义表单功能类:FormUtil
- 珠峰登顶在即,5G如何先行?
- #Python3小练习,随缘更新