Processus de démarrage des empreintes digitales Android

Préface: J'ai résumé le processus de débogage des empreintes digitales Android avant https://blog.csdn.net/weixin_41486477/article/details/108592205.Ce  chapitre organise principalement le processus de démarrage des empreintes digitales Android, en se concentrant sur les parties hal et framework.

1. Regardez le processus de démarrage par empreinte digitale à partir du processus de démarrage du système Android

Source de l'image ci-dessous  

La première étape: la ROM de démarrage. Une fois l'appareil Android allumé, il commencera l'exécution à partir du code de démarrage de la ROM sur puce du processeur. La ROM sur puce recherchera le code du chargeur de démarrage et le chargera dans la mémoire.

                  L'essentiel est d'allumer et de démarrer le système.

La deuxième étape: Bootloader commence à s'exécuter, d'abord est chargé de terminer l'initialisation du matériel, puis trouve le code du noyau Linux et le charge dans la mémoire.

                  Pendant le processus de démarrage, le chargeur de démarrage (bootable / bootloader / lk par défaut) sélectionnera l'arbre de périphériques approprié (dts) à charger dans la mémoire en fonction des informations matérielles de la machine. Si l'ID de la broche est compatible, alors la valeur de la broche d'identification peut être lue ( Ceci est tiré par le matériel, il suffit de confirmer avec l'ingénieur en matériel comment il correspond au CI) Le CI pour l'empreinte digitale est jugé.

La troisième étape: le noyau, le noyau Linux démarre, initialise divers environnements matériels et logiciels, charge les pilotes, monte le système de fichiers racine, recherche le fichier init.rc dans les fichiers système et lance le processus d'initialisation.

                  Dans Kernel, chargez le pilote d'empreintes digitales, créez un nœud de périphérique basé sur les informations dts entrantes et enregistrez le périphérique.

La quatrième étape: Initier, initialiser et démarrer le service de propriété et démarrer le processus Zygote.

                  Trouvez [email protected], démarrez [email protected], accédez à fingerprint.deault.so et attendez la communication avec la couche supérieure.

Cinquième étape: le processus Zygote est lancé, la machine virtuelle java est créée et la méthode JNI est enregistrée pour la machine virtuelle java, le socket côté serveur est créé et le processus SystemServer est lancé.

La sixième étape: le processus SystemServer démarre, démarre le pool de threads Binder et SystemServiceManager, et démarre divers services système.

                 Démarre Fingerprintservice

 Ce qui précède est le processus de démarrage de chaque étape de l'empreinte digitale du processus de démarrage Android, qui sera présenté en détail ci-dessous.

2. Couche de lecteur     

L'essentiel est l'enregistrement du pilote de nœud de périphérique, qui ne sera pas abordé en détail ici, et se concentre sur la fonction de sonde.

Troisième couche

Tout d'abord, hardware/interfaces/biometrics/fingerprint/2.1/default/[email protected] (ci-après dénommé 2.1 rc)

service vendor.fps_hal /vendor/bin/hw/[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

Cela permettra à [email protected] (ci-après dénommé 2.1 bin) situé dans le fournisseur du système / bin / hw de démarrer automatiquement après le démarrage, et enregistrera le service 2.1 après le démarrage.

Le code correspondant au service bin se trouve dans hardware / interfaces / biometrics / fingerprint / 2.1 / default / service.cpp. L'ensemble du processus d'enregistrement ne comporte que deux étapes. Premièrement, l'objet d'interface IBiometricsFingerprint entrant est instancié, puis le service est enregistré auprès de hwservicemanager via registerAsService.

int main() {
    android::sp<IBiometricsFingerprint> bio = BiometricsFingerprint::getInstance();

    configureRpcThreadpool(1, true /*callerWillJoin*/);

    if (bio != nullptr) {
        if (::android::OK != bio->registerAsService()) { //*****注册服务*****
            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, en se concentrant sur la fonction openHal, ouvrira fingerprint.default.so

fingerprint_device_t* BiometricsFingerprint::openHal() {
    int err;
    const hw_module_t *hw_mdl = nullptr;
    ALOGD("Opening fingerprint hal library...");
    //*******打开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;
}

À propos de fingerprint.default.so ceci est fourni par le fournisseur, généralement pas open source, mais Android natif a également cette partie du code (bien sûr, jetez un œil, et ne pouvez pas l'utiliser)

matériel / libhardware / include / hardware / fingerprint.h

matériel / libhardware / modules / empreinte digitale / empreinte digitale.c

Cette partie du code n'est plus développée et collée ici, vous pouvez aller la voir vous-même, principalement fingerprint_open ouvre le périphérique (nœud de périphérique), puis définit une série de fonctions.

    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;

Couche Four.framework

Tout d'abord, après le démarrage du SystemServer, il déterminera si l'appareil prend en charge les empreintes digitales, s'il y a un démarrage FingerprintService

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

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

Le jugement de mPackageManager.hasSystemFeature (PackageManager.FEATURE_FINGERPRINT) ici, vous pouvez aller dans frameworks / base / core / java / android / content / pm / PackageManager.java pour suivre le code pour voir, la logique est très simple.

Est de déterminer s'il existe un fichier android.hardware.fingerprint.xml dans le répertoire fournisseur / etc / permissions du système

L'article de débogage indique que cette configuration est la clé pour savoir s'il existe une option d'empreinte digitale dans le paramètre:

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

Ensuite, allez dans frameworks / base / services / core / java / com / android / server / fingerprint / FingerprintService.java, la première moitié du code ci-dessous est la partie qui communique avec le service hal 2.1, via mDaemon = IBiometricsFingerprint.getService (), obtenez 2.1 un service

Dans la seconde moitié, on peut voir qu'il hérite de IFingerprintService.aidl Cette classe aidl est le pont qui réalise la communication entre Manager et Service.

 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;
    }

L'encapsulation de FingerprintService au niveau suivant est FingerprintManager, et l'application d'application peut communiquer directement avec elle

frameworks / base / core / java / android / hardware / fingerprint / FingerprintManager.java (ce qui suit est le code pour rechercher mService, vous pouvez aller voir par vous-même)

    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());

Dans le code ci-dessus, vous pouvez constater que le FingerprintManager n'implémente en fait aucune interface. C'est le IFingerprintService qui est appelé. Voici le helpl. Le FingerprintManager obtient le Fingerprintservice via le Stub de l'aide, puis appelle la méthode de service ici pour faire fonctionner le service. C'est le rôle d'aidl.

frameworks / base / core / java / android / hardware / fingerprint / IFingerprintService.aidl (Si vous regardez le code complet, l'interface ici est exactement la même que celle appelée dans 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. Résumé

Sur la base de ce qui précède, un tel organigramme peut être dessiné (ce qui suit prend l'empreinte digitale Goodix comme exemple, le processus est le même)

L'APP système a émis une commande d'enregistrement -> FingerprintManager a reçu la commande -> FingerprintService a reçu la commande -> (service 2.1) BiometricsFingerprint a reçu la commande -> (fingerprint.default.so) Fingerprint.cpp a reçu la commande -> Fingerprint CA a reçu la commande -> Fingerprint TA reçoit la commande -> Collecte de données SPI \ algorithme d'enregistrement, etc.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_41486477/article/details/112863054
conseillé
Classement