Comprehensively analyze the fingerprint startup process of Android system

Time:2022-1-2

This chapter mainly arranges the Android fingerprint startup process, focusing on Hal and framework.

I Viewing fingerprint startup process from Android system startup process

Source of the picture below →

Phase I

Boot ROM: after the Android device is powered on, it will start from the boot code of the ROM on the processor chip. The ROM on the chip will look for the bootloader code and load it into memory. The main thing is to power on and start the system.

Phase II

Bootloader starts to execute. It is first responsible for completing the initialization of the hardware, and then finds the Linux kernel code and loads it into memory.

During startup, bootloader (bootable / bootloader / LK by default) will select an appropriate devicetree (DTS) to load into memory according to the machine hardware information. If pin ID compatibility is adopted, then the IC of the fingerprint can be determined by reading the value of ID pin (this is pulled by hardware and confirmed with the hardware engineer how to correspond to the IC).

Phase III

Kernel, the Linux kernel starts to start, initializes various software and hardware environments, loads drivers, mounts the root file system, and looks for init RC file and start the init process.In the kernel, load the fingerprint driver, create a device node according to the incoming DTS information, and register the device.

Phase IV

Init, initialize and start the property service, and start the zygote process.

Find Android hardware. biometrics. [email protected] -service. RC, start Android hardware. biometrics. [email protected] -Service, open fingerprint deault. So, wait for communication with the upper layer.

Phase V

Start the zygote process, create a Java virtual machine, register the JNI method for the Java virtual machine, create a server-side socket, and start the systemserver process.

Phase VI

The system server process starts, the binder thread pool and the system service manager are started, and various system services are started.The fingerprint service starts

The above is the start-up process of fingerprint at each stage from the Android start-up process, which is described in detail below.

II Driving layer

This is mainly about the registration of device node drivers. I won’t talk about it in detail here. I focus on the probe function.

III Hal layer

First, hardware / interfaces / biometrics / fingerprint / 2.1 / default / Android hardware. biometrics. [email protected] -service. RC (hereinafter referred to as 2.1 RC)


service vendor.fps_hal /vendor/bin/hw/android[email protected]
    # "class hal" causes a race condition on some devices due to files created
    # in /data. As a workaround, postpone startup until later in boot once
    # /data is mounted.
    class late_start
    user system
    group system input
    writepid /dev/cpuset/system-background/tasks

It will make android.com located under vendor / bin / HW of the system hardware. biometrics. [email protected] -Service (hereinafter referred to as 2.1 bin) starts automatically after startup. After startup, 2.1 service will be registered

The corresponding code of the bin service is in: Hardware / interfaces / biometrics / fingerprint / 2.1/default/service CPP, there are only two steps in the whole registration process. First, instantiate the incoming ibiometricsfingerprint interface object, and then register the service to hwservicemanager through registerasservice.

int main() {
    android::sp<IBiometricsFingerprint> bio = BiometricsFingerprint::getInstance();
 
    configureRpcThreadpool(1, true /*callerWillJoin*/);
 
    if (bio != nullptr) {
        If (:: Android:: OK! = bio - > registerasservice()) {// ****** register service*****
            return 1;
        }
    } else {
        ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
    }
 
    joinRpcThreadpool();
 
    return 0; // should never get here
}

hardware/interfaces/biometrics/fingerprint/2.1/default/BiometricsFingerprint. CPP, focusing on the openhal function, will open fingerprint default. so

fingerprint_device_t* BiometricsFingerprint::openHal() {
    int err;
    const hw_module_t *hw_mdl = nullptr;
    ALOGD("Opening fingerprint hal library...");
    //*******Open fingerprint default. so********
    if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) {
        ALOGE("Can't open fingerprint HW Module, error: %d", err);
        return nullptr;
    }
 
    if (hw_mdl == nullptr) {
        ALOGE("No valid fingerprint module");
        return nullptr;
    }
 
    fingerprint_module_t const *module =
        reinterpret_cast<const fingerprint_module_t*>(hw_mdl);
    if (module->common.methods->open == nullptr) {
        ALOGE("No valid open method");
        return nullptr;
    }
 
    hw_device_t *device = nullptr;
 
    if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) {
        ALOGE("Can't open fingerprint methods, error: %d", err);
        return nullptr;
    }
 
    if (kVersion != device->version) {
        // enforce version on new devices because of [email protected] translation layer
        ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
        return nullptr;
    }
 
    fingerprint_device_t* fp_device =
        reinterpret_cast<fingerprint_device_t*>(device);
 
    if (0 != (err =
            fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) {
        ALOGE("Can't register fingerprint module callback, error: %d", err);
        return nullptr;
    }
 
    return fp_device;
}

About fingerprint default. So is provided by vendors and is generally not open source, but Android native also has this part of the code (of course, it’s just a look and can’t be used)

hardware/libhardware/include/hardware/fingerprint.h

hardware/libhardware/modules/fingerprint/fingerprint.c

This part of the code is no longer expanded and posted here. You can take a look at it yourself, mainly fingerprint_ Open opens the device (device node), and then defines a series of functions.


dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = FINGERPRINT_MODULE_API_VERSION_2_0;
dev->common.module = (struct hw_module_t*) module;
dev->common.close = fingerprint_close;

dev->pre_enroll = fingerprint_pre_enroll;
dev->enroll = fingerprint_enroll;
dev->get_authenticator_id = fingerprint_get_auth_id;
dev->cancel = fingerprint_cancel;
dev->remove = fingerprint_remove;
dev->set_active_group = fingerprint_set_active_group;
dev->authenticate = fingerprint_authenticate;
dev->set_notify = set_notify_callback;

IV Framework layer

First, after the system server is started, it will judge whether the device supports fingerprints. If there is a start fingerprintservice

frameworks/base/services/java/com/android/server/SystemServer.java


if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
    traceBeginAndSlog("StartFingerprintSensor");
    mSystemServiceManager.startService(FingerprintService.class);
    traceEnd();
}

Here is mpackagemanager You can go to frameworks / base / core / Java / Android / content / PM / packagemanager to judge the hassystemfeature (packagemanager. Feature_fingerprint) Look at the code in Java. The logic is very simple.

It is to judge whether there is Android in the vendor / etc / permissions directory in the system hardware. fingerprint. XML file

The debugging article said that this configuration is the key to whether there is a fingerprint option in setting:


PRODUCT_COPY_FILES := frameworks/native/data/etc/android.hardware.fingerprint.xml:vendor/etc/permissions/android.hardware.fingerprint.xml 

Next, go to frameworks / base / services / core / Java / COM / Android / server / fingerprint / fingerprintservice Java, the first half of the following code is to communicate with Hal 2.1 service through MDaemon = ibiometricsfingerprint Getservice(), get 2.1 service

The latter part shows that it inherits ifingerprintservice Aidl, this Aidl class is the bridge between manager and service communication.


 public synchronized IBiometricsFingerprint getFingerprintDaemon() {
        if (mDaemon == null) {
            Slog.v(TAG, "mDaemon was null, reconnect to fingerprint");
            try {
                mDaemon = IBiometricsFingerprint.getService();
            } catch (java.util.NoSuchElementException e) {
                // Service doesn't exist or cannot be opened. Logged below.
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to get biometric interface", e);
            }
            if (mDaemon == null) {
                Slog.w(TAG, "fingerprint HIDL not available");
                return null;
            }
 
            mDaemon.asBinder().linkToDeath(this, 0);
 
            try {
                mHalDeviceId = mDaemon.setNotify(mDaemonCallback);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to open fingerprint HAL", e);
                mDaemon = null; // try again later!
            }
 
            if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
            if (mHalDeviceId != 0) {
                loadAuthenticatorIds();
                updateActiveGroup(ActivityManager.getCurrentUser(), null);
                doFingerprintCleanupForUser(ActivityManager.getCurrentUser());
            } else {
                Slog.w(TAG, "Failed to open Fingerprint HAL!");
                MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1);
                mDaemon = null;
            }
 
 
 
 
 
//************************************************************************************//
 
 
 
 private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
        @Override // Binder call
        public long preEnroll(IBinder token) {
            checkPermission(MANAGE_FINGERPRINT);
            return startPreEnroll(token);
        }
 
        @Override // Binder call
        public int postEnroll(IBinder token) {
            checkPermission(MANAGE_FINGERPRINT);
            return startPostEnroll(token);
        }
 
        @Override // Binder call
        public void enroll(final IBinder token, final byte[] cryptoToken, final int userId,
                final IFingerprintServiceReceiver receiver, final int flags,
                final String opPackageName) {
            checkPermission(MANAGE_FINGERPRINT);
            final int limit = mContext.getResources().getInteger(
                    com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
 
            final int enrolled = FingerprintService.this.getEnrolledFingerprints(userId).size();
            if (enrolled >= limit) {
                Slog.w(TAG, "Too many fingerprints registered");
                return;
            }
        }
        return mDaemon;
    }

The next layer of encapsulation of the fingerprint service is the fingerprint manager, and the application app can communicate with it directly

frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager. Java (the following is the code for searching mservice, you can take a look at it yourself)


    private IFingerprintService mService;
        if (mService != null) try {
            mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
 
        if (mService != null) {
                mService.authenticate(mToken, sessionId, userId, mServiceReceiver,
               
        if (mService != null) try {
            mService.enroll(mToken, token, userId, mServiceReceiver, flags,
            
        if (mService != null) try {
            result = mService.preEnroll(mToken);
        if (mService != null) try {
            result = mService.postEnroll(mToken);
        if (mService != null) try {
            mService.setActiveUser(userId);
        if (mService != null) try {
            mService.remove(mToken, fp.getFingerId(), fp.getGroupId(), userId, mServiceReceiver);
            mService.remove(mToken, fp.getFingerId(), fp.getGroupId(), userId, mServiceReceiver);
        if (mService != null) try {
            mService.enumerate(mToken, userId, mServiceReceiver);
            
        if (mService != null) {
                mService.rename(fpId, userId, newName);
        if (mService != null) try {
            return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
        if (mService != null) try {
            return mService.hasEnrolledFingerprints(
        if (mService != null) try {
            return mService.hasEnrolledFingerprints(userId, mContext.getOpPackageName());
        if (mService != null) {
                return mService.isHardwareDetected(deviceId, mContext.getOpPackageName());
        if (mService != null) {
                return mService.getAuthenticatorId(mContext.getOpPackageName());
        if (mService != null) {
                mService.resetTimeout(token);
        if (mService == null) {
        if (mService != null) try {
            mService.cancelEnrollment(mToken);
        if (mService != null) try {
            mService.cancelAuthentication(mToken, mContext.getOpPackageName());

In the above code, you can find that the fingerprint manager does not really implement any interface, but calls the ifingerprintservice. Here, Aidl is used. The fingerprint manager obtains the fingerprint service through the Aidl stub, and then calls the service method here to operate the service. This is the role of Aidl.

frameworks/base/core/java/android/hardware/fingerprint/IFingerprintService. Aidl (if you go to see the complete code, the interface here is exactly the same as those invoked in FingerprintManager).


interface IFingerprintService {
    // Authenticate the given sessionId with a fingerprint
    void authenticate(IBinder token, long sessionId, int userId,
            IFingerprintServiceReceiver receiver, int flags, String opPackageName,
            in Bundle bundle, IBiometricPromptReceiver dialogReceiver);
 
    // Cancel authentication for the given sessionId
    void cancelAuthentication(IBinder token, String opPackageName);
 
    // Start fingerprint enrollment
    void enroll(IBinder token, in byte [] cryptoToken, int groupId, IFingerprintServiceReceiver receiver,
            int flags, String opPackageName);
 
    // Cancel enrollment in progress
    void cancelEnrollment(IBinder token);
 
    // Any errors resulting from this call will be returned to the listener
    void remove(IBinder token, int fingerId, int groupId, int userId,
            IFingerprintServiceReceiver receiver);
 
    // Rename the fingerprint specified by fingerId and groupId to the given name
    void rename(int fingerId, int groupId, String name);
 
    // Get a list of enrolled fingerprints in the given group.
    List<Fingerprint> getEnrolledFingerprints(int groupId, String opPackageName);
 
    // Determine if HAL is loaded and ready
    boolean isHardwareDetected(long deviceId, String opPackageName);
 
    // Get a pre-enrollment authentication token
    long preEnroll(IBinder token);
 
    // Finish an enrollment sequence and invalidate the authentication token
    int postEnroll(IBinder token);
 

V summary

According to the above, you can draw such a flow chart (the following takes huiding fingerprint as an example, and the flow is the same)

System app issues the registration command – > fingerprint manager receives the command – > fingerprint service receives the command – > biometricsfingerprint receives the command – > fingerprint CPP receives command – > fingerprint CA receives command – > fingerprint TA receives command – > SPI collects data \ algorithm registration, etc

The above is the detailed content of comprehensively analyzing the fingerprint startup process of Android system. For more information about Android startup process, please pay attention to other relevant articles of developeppaer!

Recommended Today

Click the button in H5 to download the picture

In the development of uni app project, one requirement is to click the button to download multiple pictures, and the picture path is returned from the background. (saveimagetophotosalbum in uni app is not available) ——————- the following code is obtained by referring to other people’s methods and my own personal practice Method 1:      var […]