前言

因为源码剖析的代码量比拟大,大部分博客网站的内容显示页面都比拟窄,显示进去的成果都异样俊俏,所以您也能够间接查看 《 Thinking in Android 》 来浏览这边文章,心愿这篇文章能帮你梳理分明 “指纹注册流程”


外围源码

要害类门路
FingerprintEnrollIntroduction.javapackages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
BiometricEnrollIntroduction.javapackages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
FingerprintEnrollEnrolling.javapackages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
BiometricsEnrollEnrolling.javapackages/apps/Settings/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java
FingerprintEnrollSidecar.javapackages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java
BiometricEnrollSidecar.javapackages/apps/Settings/src/com/android/settings/biometrics/BiometricEnrollSidecar.java
FingerprintEnrollFindSensor.javapackages/apps/Settings/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
FingerprintManager.javaframeworks/base/core/java/android/hardware/fingerprint/FingerprintManager.java
FingerprintService.javaframeworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
BiometricServiceBase.javaframeworks/base/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
EnrollClient.javaframeworks/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 继承自 BiometricEnrollIntroductiononNextButtonClick() 办法在其父类 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()

FingerprintManagerFingerprintService 间接通过 aidl 进行通信,在 FingerprintService 中外部类 FingerprintServiceWrapper 实现了 IFingerprintService.Stub,咱们调用的 FingerMangerenroll() 办法就是调用 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);        }    }}