共计 22788 个字符,预计需要花费 57 分钟才能阅读完成。
前言
因为源码剖析的代码量比拟大,大部分博客网站的内容显示页面都比拟窄,显示进去的成果都异样俊俏,所以您也能够间接查看《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.java
public 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.java
public 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.java
public 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.java
public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
implements LinkSpan.OnClickListener {protected abstract Intent getEnrollingIntent(); // 形象办法,由子类 FingerprintEnrollIntroduction 实现
}
所以咱们跳转到 FingerprintEnrollIntroduction
:
// packages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public 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.java
public class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants {private void sendEnrollResult(Fingerprint fp, int remaining) {if (mEnrollmentCallback != null) {
// 调用 EnrollmentCallback 的 onEnrollmentProgress 办法
mEnrollmentCallback.onEnrollmentProgress(remaining);
}
}
}