前言
因为源码剖析的代码量比拟大,大部分博客网站的内容显示页面都比拟窄,显示进去的成果都异样俊俏,所以您也能够间接查看 《 Thinking in Android 》 来浏览这边文章,心愿这篇文章能帮你梳理分明 “指纹注册流程”。
外围源码
要害类 | 门路 |
---|---|
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 { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mFingerprintManager = Utils.getFingerprintManagerOrNull(this); mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class); // Cancel Button mFooterBarMixin.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 Button mFooterBarMixin.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 BiometricEnrollBase implements LinkSpan.OnClickListener { @Override protected void onNextButtonClick(View view) { mNextClicked = true; if (checkMaxEnrolled() == 0) { // Lock thingy is already set up, launch directly to the next page launchNextEnrollingActivity(mToken); // 接下来就要拉起指纹录入界面 } else { setResult(RESULT_FINISHED); finish(); } } }
2.2 BiometricEnrollIntroduction.launchNextEnrollingActivity()
// packages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollIntroduction.javapublic abstract class BiometricEnrollIntroduction extends BiometricEnrollBase implements LinkSpan.OnClickListener { private void launchNextEnrollingActivity(byte[] token) { Intent intent = getEnrollingIntent(); // 获取 FingerprintEnrollFindSensor if (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 BiometricEnrollBase implements LinkSpan.OnClickListener { protected abstract Intent getEnrollingIntent(); // 形象办法,由子类 FingerprintEnrollIntroduction 实现 }
所以咱们跳转到 FingerprintEnrollIntroduction
:
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.javapublic class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction { @Override protected 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 { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentView()); mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class); // Skip button mFooterBarMixin.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 sensor setHeaderText(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(); // 增加 FingerprintEnrollEnrolling getSupportFragmentManager().beginTransaction() .add(mSidecar, FingerprintEnrollEnrolling.TAG_SIDECAR) .commitAllowingStateLoss(); } // FingerprintEnrollEnrolling 实现了 BiometricEnrollSidecar.Listener 接口 mSidecar.setListener(new Listener() { // 匿名外部类的形式实现接口办法 @Override public void onEnrollmentProgressChange(int steps, int remaining) { mNextClicked = true; proceedToEnrolling(true /* cancelEnrollment */); } @Override public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { } @Override public 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 的 Intent startActivityForResult(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 { @Override protected 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 { // 指纹录制时提醒(比方太快,挪动手指之类) @Override public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { if (!TextUtils.isEmpty(helpString)) { mErrorText.removeCallbacks(mTouchAgainRunnable); showError(helpString); } } // 提醒指纹录制过程中超时,或者未注册 @Override public 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() 会被触发,执行一系列解决工作) @Override public 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 BiometricEnrollBase implements BiometricEnrollSidecar.Listener { @Override protected void onStart() { super.onStart(); if (shouldStartAutomatically()) { // 恒定为 true startEnrollment(); // 调用 startEnrollment() 办法 } } }
5.2 BiometricsEnrollEnrolling.startEnrollment()
// packages/apps/Settings/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.javapublic abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase implements 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(); // 获取 mSidecar getSupportFragmentManager().beginTransaction().add(mSidecar, TAG_SIDECAR) .commitAllowingStateLoss(); } mSidecar.setListener(this); } }// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.javapublic class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override protected 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; @Override protected 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() { @Override public void onEnrollmentProgress(int remaining) { FingerprintEnrollSidecar.super.onEnrollmentProgress(remaining); } @Override public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { FingerprintEnrollSidecar.super.onEnrollmentHelp(helpMsgId, helpString); } @Override public 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 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 boolean restricted = isRestricted(); final int groupId = userId; // default group for fingerprint enrollment final EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver), mCurrentUserId, groupId, cryptoToken, restricted, opPackageName, new int[0] /* disabledFeatures */, ENROLL_TIMEOUT_SEC) { @Override public boolean shouldVibrate() { return true; } @Override protected 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 SystemService implements 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 SystemService implements 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 immediately mCurrentClient = newClient; startCurrentClient(mCurrentClient.getCookie()); // 调用 startCurrentClient() 办法 } } }
9.3 BiometricServiceBase.startCurrentClient()
// frameworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.javapublic abstract class BiometricServiceBase extends SystemService implements 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,再往下层反馈。 @Override public 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 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) { 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, 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(); } }; private class MyHandler extends Handler { private MyHandler(Context context) { super(context.getMainLooper()); } private MyHandler(Looper looper) { super(looper); } @Override 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 */, 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); } }}