前言:之前总结过Android指纹调试流程https://blog.csdn.net/weixin_41486477/article/details/108592205 ,本章主要整理Android 指纹启动流程,侧重于hal和framework部分。

一.从Android系统启动流程看指纹启动流程

下图图片出处  →

Android 指纹启动流程_第1张图片

第一阶段:Boot ROM,Android设备上电后,首先会从处理器片上ROM的启动引导代码开始执行,片上ROM会寻找Bootloader代码,并加载到内存。

                  主要就是上电让系统启动。

第二阶段:Bootloader开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存。

                  启动过程中,bootloader(默认是bootable/bootloader/lk)会根据机器硬件信息选择合适的devicetree(dts)装入内存,如果采用pin id兼容,那么在此时就可以通过读取ID pin的值(这个是硬件拉的,跟硬件工程师确认是怎么对应IC的即可)判断指纹的IC了。

第三阶段:Kernel,Linux内核开始启动,初始化各种软硬件环境,加载驱动程序,挂载根文件系统,在系统文件中寻找init.rc文件,并启动init进程。

                  Kernel中,加载指纹驱动,根据传入的dts信息创建设备节点,注册设备。

第四阶段:Init,初始化和启动属性服务,并且启动Zygote进程。

                  找到android.hardware.biometrics.fingerprint@2.1-service.rc,启动android.hardware.biometrics.fingerprint@2.1-service,会去open  fingerprint.deault.so,等待与上层通信。

第五阶段:Zygote进程启动,创建java虚拟机并为java虚拟机注册JNI方法,创建服务器端Socket,启动SystemServer进程。

第六阶段:SystemServer进程启动,启动Binder线程池和SystemServiceManager,并且启动各种系统服务。

                 会启动Fingerprintservice

 以上是从Android启动流程看每个阶段指纹的启动流程 ,下面依次详细展开介绍。

二.驱动层     

主要就是设备节点驱动的注册,在此不再详细说了,重点关注probe函数。

三.hal层

首先,hardware/interfaces/biometrics/fingerprint/2.1/default/android.hardware.biometrics.fingerprint@2.1-service.rc(以下简称2.1 rc)

service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service    # "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

会使位于系统vendor/bin/hw下的android.hardware.biometrics.fingerprint@2.1-service(以下简称2.1 bin)开机自启动,启动后会注册2.1 service

该bin服务对应的代码在:hardware/interfaces/biometrics/fingerprint/2.1/default/service.cpp,整个注册过程只有两步,首先实例化传入的 IBiometricsFingerprint 接口对象,然后通过 registerAsService 将服务注册到 hwservicemanager。

int main() {    android::sp 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,重点关注openHal函数,会去打开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(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 HIDL@2.1 translation layer        ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);        return nullptr;    }    fingerprint_device_t* fp_device =        reinterpret_cast(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;}

关于fingerprint.default.so这个都是供应商提供的,一般都不开源,不过Android原生也是有这部分代码的(当然只是看看,并不能使用)

hardware/libhardware/include/hardware/fingerprint.h

hardware/libhardware/modules/fingerprint/fingerprint.c

这部分代码不再展开贴在这里了,大家可以自行去看看,主要就是fingerprint_open打开设备(设备节点),然后定义了一系列函数。

    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;

四.framework层

首先是SystemServer启动后,会去判断设备是否支持指纹,如果有start  FingerprintService

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

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

此处mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)的判断,大家可以去frameworks/base/core/java/android/content/pm/PackageManager.java中追代码看看,逻辑很简单。

就是判断系统内vendor/etc/permissions目录下是否有:android.hardware.fingerprint.xml 文件

调试的那篇说过这个配置是setting里有没有指纹选项的关键:

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

下面转到,frameworks/base/services/core/java/com/android/server/fingerprint/FingerprintService.java,以下代码前半部分是与hal 2.1 service通信的部分,通过mDaemon = IBiometricsFingerprint.getService(),获取2.1 service

后半部分可以看出其继承IFingerprintService.aidl,这个aidl类就是实现Manager和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;    }

对FingerprintService再往上一层的封装是FingerprintManager,应用app可以直接和它通信

frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager.java  (以下为搜索mService的代码,大家可以自己去看看)

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

以上代码大家可以发现FingerprintManager其实并没有真正实现什么接口,都是调用的IFingerprintService,这里就用到aidl了,FingerprintManager通过aidl的Stub获取了Fingerprintservice,然后在这里去调用这个service的方法,以操作service,这就是aidl的作用。

frameworks/base/core/java/android/hardware/fingerprint/IFingerprintService.aidl (大家如果去看完整的代码,这里的接口是和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 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);   

五.总结

根据以上可以画出这样一张流程图(以下以汇顶指纹为例,流程上都是一样的)

System APP下发注册命令->FingerprintManager收到命令->FingerprintService收到命令->(2.1 service)BiometricsFingerprint收到命令->(fingerprint.default.so)Fingerprint.cpp收到命令->指纹CA收到命令->指纹TA收到命令->SPI采集数据\算法进行注册等

Android 指纹启动流程_第2张图片

更多相关文章

  1. Android源代码目录组成介绍-android学习之旅(97)
  2. Android系统启动流程(4) —— 解析Launcher启动过程
  3. Android有用代码片段(四)
  4. [转]Android 源代码结构
  5. android代码库之textview跑马灯效果
  6. Android 垂直的Slidebar 代码
  7. Android Studio 系列(二)使用Android Studio 导入整个android 源码
  8. 【Android】Android 代码判断是否获取ROOT权限(一)
  9. Android hardware so加载流程

随机推荐

  1. Android平台常见属性集合
  2. android约束布局ConstraintLayout
  3. 【Android】Android的Activity生命周期
  4. No command 'mmm' found
  5. android 背景圆角以及图片圆角处理
  6. 通过API级别进行文档内容过滤
  7. [Android学习]ImageView的scaletype属性
  8. Android布局图标中心化
  9. android IApplicationToken分析
  10. 11月29日