1. FingerprintService的启动
在系统开机的时候,会启动各种Service,包括FingerprintService
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLRlXMkh3MP9CXt92YuIXdn1Wauk2Lc9CX6MHc0RHaiojIsJye.png)
FingerprintService的启动在SystemServer.Java的startOtherService方法中:
1.开启FingerprintService服务,调用FingerprintService.java中的onStart()方法
1.通过publishBinderService()方法将FingerprintService的binder对象IFingerprintService添加到ServiceManager中。此处的FingerprintServiceWrapper继承至IFingerprintService,为IFingerprintService的具体实现类。
2.通过getFingerprintDaemon()方法获取与fingerprintd进行通信的binder对象IFingerprintDaemon。
1.从ServiceManager中能获取IFingerprintDaemon对象是因为fingerprintd在init.rc有相应的开机启动脚本,所以一开机就会运行它的main函数。
main函数就是将fingerprintd添加到servicemanager中管理。
2.向fingerprintd注册回调函数,接收hal层传递上来的数据。
3.调用fingerprintd的openHal()函数,与hal层进行连接。
2. FingerprintManager的初始化
在应用层,fingerprintManager对象的创建为:
通过getSystemService()方法调用SystemServiceRegistry.java文件中的CreatService()函数
获取fingerprintManager对象,并从ServiceManager中获取IFingerprintService的binder对象,传入fingerprintManager构造方法中。
这样,app端通过Context获取FingerprintManager,通过调用FingerprintManager的接口来实现相应的功能,FingerprintManager通过binder通信转调FingerprintService中的方法,FingerprintService负责管理整个注册,识别、删除指纹、检查权限等流程的逻辑,FingerprintService通过getFingerprintDaemon()函数获取与fingerprintd通信的binder对象(IFingerprintDaemon)调用fingerprintd的接口,再fingerprintd和FingerprintHal层进行通信。
3. fingerprintd部分的初始化
在system/core/fingerprintd目录下,有如下文件:
fingerprintd.cpp:“负责将fingerprintd加入到ServiceManager中,以便FingerprintService能够获取”;
IFingerprintDaemon.h/IFingerprintDaemon.cpp:“负责java层到fingerprintd的Binder通信”;
FingerprintDaemonProxy.h/FingerprintDaemonProxy.cpp:“负责fingerprintd和Fignerprint hal层的通信”;
IFingerprintDaemonCallback.h/IFingerprintDaemonCallback.cpp:“负责将指纹的回调结果传给java层的fingerprintService”;
3.1 IFingerprintDaemon与framework通信
3.1.1 IFingerprintDaemon.h
在IFingerprintDaemon.h文件中:
1.需要手动保证IFingerprintDaemon.h文件的②处顺序与IFingerprintDaemon.aidl文件一致
IFingerprintDaemo.aidl:
当添加接口来调用指纹底层暴露的接口,在IFingerprintDaemon.h文件中添加类似上面②处的枚举,枚举的值需要与java层aidl自动生成的java文件中的枚举保持一致。
2.需要在④处加上描述这些接口的纯虚函数(c++中的纯虚函数类似java的抽象方法,用于定义接口的规范,在C++中,一个具有纯虚函数的基类被称为抽象类)。(系统已加)
3.1.2 IFingerprintDaemon.cpp
如IFingerprintDaemon.cpp的onTransact:
case后的值为IFingerprintDaemon.h文件②处定义的枚举值。
可以看到onTransact有四个参数code,data,replay,flags
code: 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法;
data: 客户端传递过来的参数;
replay: 服务器返回回去的值;
flags: 标明是否有返回值,0为有(双向),1为没有(单向);
3.1.3 IFingerprintDaemon.aidl
IFingerprintDaemon.aidl文件生成的IFingerprintDaemon.java的onTransact:
case后的值与IFingerprintDaemon.cpp文件case后的值基本是一致的。
因此需要手动保证IFingerprintDaemon.h文件与IFingerprintDaemon.aidl文件一致,这样的方式类似在第三方应用使用aidl文件,需要保持client端和server端aidl文件一致。
3.2 fingerprintd与Fingerprint Hal层通信
Hal层,即硬件抽象层,Android系统为HAL层中的模块接口定义了规范,所有工作于HAL的模块必须按照这个规范来编写模块接口,否则将无法正常访问硬件。
指纹的HAL层规范fingerprint.h在/hardware/libhardware/include/hardware/目录下
在fingerprint.h中定义了两个结构体,分别是fingerprint_device_t和fingerprint_module_t:
fingerprint_device_t结构体,用于描述指纹硬件设备;
fingerprint_module_t结构体,用于描述指纹硬件模块。
在FingerprintDaemonProxy.cpp就是通过拿到fingerprint_device_t这个结构体来和Fingerprint HAL层通信的。
当需要添加接口调用指纹底层时,在fingerprint.h中同样需要添加函数指针,然后通过FingerprintDaemonProxy.cpp拿到fingerprint_device_t来调用fingerprint.h中定义的函数指针,也就相当于调用指纹HAL层。
在FingerprintDaemonProxy.cpp的openHal()函数中:
1.根据名称获取指纹hal层模块。hw_module这个一般由指纹芯片厂商根据 fingerprint.h实现,hw_get_module是由HAL框架提供的一个公用的函数,这个函数的主要功能是根据模块ID(module_id)去查找注册在当前系统中与id对应的硬件对象,然后载入(load)其相应的HAL层驱动模块的*so文件。
2.调用fingerprint_module_t的open函数。
3.向hal层注册消息回调函数,主要回调注册指纹进度,识别结果,错误信息等等。
4.判断向hal层注册消息回调是否注册成功。
4. 自定义方法
4.1 指纹框架示意图
4.2 添加自定义方法
4.2.1 应用层调用
4.2.2 FingerprintManager.java添加
4.2.3 IFingerprintService.aidl添加
4.2.4 FingerprintService.java添加
4.2.5 IFingerprintDaemon.aidl添加
4.2.6 IFingerprintDaemon.h添加
4.2.7 IFingerprintDaemon.cpp添加
4.2.8 FingerprintDaemonProxy.h添加
4.2.9 FingerprintDaemonProxy.cpp添加
fingerprint_device_t* mDevice;
mDevice在FingerprintDaemonProxy.cpp的openHal()函数中获取。
在FingerprintDaemonProxy.cpp中就是通过拿到fingerprint_device_t这个结构体来和Fingerprint HAL层通信。
当需要添加接口调用指纹底层时,在fingerprint.h中同样需要添加函数指针,然后通过FingerprintDaemonProxy.cpp拿到fingerprint_device_t来调用fingerprint.h中定义的函数指针,也就相当于调用指纹HAL层。