天天看点

Android6.0指纹框架

1. FingerprintService的启动

在系统开机的时候,会启动各种Service,包括FingerprintService

Android6.0指纹框架

FingerprintService的启动在SystemServer.Java的startOtherService方法中:

Android6.0指纹框架

1.开启FingerprintService服务,调用FingerprintService.java中的onStart()方法

Android6.0指纹框架

1.通过publishBinderService()方法将FingerprintService的binder对象IFingerprintService添加到ServiceManager中。此处的FingerprintServiceWrapper继承至IFingerprintService,为IFingerprintService的具体实现类。

Android6.0指纹框架

2.通过getFingerprintDaemon()方法获取与fingerprintd进行通信的binder对象IFingerprintDaemon。

Android6.0指纹框架

1.从ServiceManager中能获取IFingerprintDaemon对象是因为fingerprintd在init.rc有相应的开机启动脚本,所以一开机就会运行它的main函数。

Android6.0指纹框架

main函数就是将fingerprintd添加到servicemanager中管理。

2.向fingerprintd注册回调函数,接收hal层传递上来的数据。

3.调用fingerprintd的openHal()函数,与hal层进行连接。

2. FingerprintManager的初始化

在应用层,fingerprintManager对象的创建为:

Android6.0指纹框架

通过getSystemService()方法调用SystemServiceRegistry.java文件中的CreatService()函数

Android6.0指纹框架

获取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目录下,有如下文件:

Android6.0指纹框架

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文件中:

Android6.0指纹框架
Android6.0指纹框架

1.需要手动保证IFingerprintDaemon.h文件的②处顺序与IFingerprintDaemon.aidl文件一致

IFingerprintDaemo.aidl:

Android6.0指纹框架

当添加接口来调用指纹底层暴露的接口,在IFingerprintDaemon.h文件中添加类似上面②处的枚举,枚举的值需要与java层aidl自动生成的java文件中的枚举保持一致。

2.需要在④处加上描述这些接口的纯虚函数(c++中的纯虚函数类似java的抽象方法,用于定义接口的规范,在C++中,一个具有纯虚函数的基类被称为抽象类)。(系统已加)

3.1.2 IFingerprintDaemon.cpp

如IFingerprintDaemon.cpp的onTransact:

Android6.0指纹框架

case后的值为IFingerprintDaemon.h文件②处定义的枚举值。

可以看到onTransact有四个参数code,data,replay,flags

code: 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法;

data: 客户端传递过来的参数;

replay: 服务器返回回去的值;

flags: 标明是否有返回值,0为有(双向),1为没有(单向);

3.1.3 IFingerprintDaemon.aidl

IFingerprintDaemon.aidl文件生成的IFingerprintDaemon.java的onTransact:

Android6.0指纹框架

case后的值与IFingerprintDaemon.cpp文件case后的值基本是一致的。

因此需要手动保证IFingerprintDaemon.h文件与IFingerprintDaemon.aidl文件一致,这样的方式类似在第三方应用使用aidl文件,需要保持client端和server端aidl文件一致。

3.2 fingerprintd与Fingerprint Hal层通信

Hal层,即硬件抽象层,Android系统为HAL层中的模块接口定义了规范,所有工作于HAL的模块必须按照这个规范来编写模块接口,否则将无法正常访问硬件。

Android6.0指纹框架

指纹的HAL层规范fingerprint.h在/hardware/libhardware/include/hardware/目录下

在fingerprint.h中定义了两个结构体,分别是fingerprint_device_t和fingerprint_module_t:

Android6.0指纹框架

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()函数中:

Android6.0指纹框架

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 指纹框架示意图

Android6.0指纹框架

4.2 添加自定义方法

4.2.1 应用层调用
Android6.0指纹框架
4.2.2 FingerprintManager.java添加
Android6.0指纹框架
4.2.3 IFingerprintService.aidl添加
Android6.0指纹框架
4.2.4 FingerprintService.java添加
Android6.0指纹框架
4.2.5 IFingerprintDaemon.aidl添加
Android6.0指纹框架
4.2.6 IFingerprintDaemon.h添加
Android6.0指纹框架
Android6.0指纹框架
4.2.7 IFingerprintDaemon.cpp添加
Android6.0指纹框架
4.2.8 FingerprintDaemonProxy.h添加
Android6.0指纹框架
4.2.9 FingerprintDaemonProxy.cpp添加
Android6.0指纹框架

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层。