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

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

下图图片出处  →

第一阶段: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采集数据\算法进行注册等

更多相关文章

  1. Android应用程序进程启动过程(后篇)
  2. Android源代码目录组成介绍-android学习之旅(97)
  3. Android系统启动流程(4) —— 解析Launcher启动过程
  4. android手动拖动滚动条快速滑动
  5. 获取Android(安卓)SDK 源代码并在Eclipse中关联查看的方法
  6. Android(安卓)ListView 去除边缘阴影、选中色、拖动背景色等
  7. Android有用代码片段(四)
  8. [转]Android(安卓)源代码结构
  9. 只发起单独activity

随机推荐

  1. Android学习点点滴滴之获取正在运行的进
  2. Android(安卓)的网络编程(4)-HttpClient
  3. [置顶] Android服务器推送之GCM
  4. Tiny210 从源代码开始创建Android
  5. Android入门进阶教程(20)-ContentProvide
  6. Android(安卓)之 WebView的使用介绍
  7. butterknife使用方法
  8. android微信开放平台,申请移动应用的应用
  9. android permission中英文大全
  10. android View的点击事件分发机制的简单认