Android P 指纹 HAL
先简单了解下HIDL的一些内容,有助于查看代码。
Android O之后Android全面引入了Treble架构,HAL层从简单的函数调用转变成了依靠binder的IPC通讯模式——HIDL。
根据Google的定义HIDL分为两种模式:Passthrough和Binderized;
Binderized(绑定试HAL):以 HAL 接口定义语言 (HIDL) 表示的 HAL。这些 HAL 取代了早期 Android 版本中使用的传统 HAL 和旧版 HAL。在绑定式 HAL 中,Android 框架和 HAL 之间通过 Binder 进程间通信 (IPC) 调用进行通信。所有在推出时即搭载了 Android 8.0 或后续版本的设备都必须只支持绑定式 HAL。
Passthrough(直通式HAL):以 HIDL 封装的传统 HAL 或旧版 HAL。这些 HAL 封装了现有的 HAL,可在绑定模式和 Same-Process(直通)模式下使用。升级到 Android 8.0 的设备可以使用直通式 HAL。
HAL 模式要求:
设备 | 直通式 | 绑定式 |
---|---|---|
搭载 Android 8.0 的设备 | 直通式 HAL 中列出的 HAL 必须为直通式。 | 所有其他 HAL 均为绑定式(包括作为供应商扩展程序的 HAL)。 |
升级到 Android 8.0 的设备 | 直通式 HAL 中列出的 HAL 必须为直通式。 | 绑定式 HAL 中列出的 HAL 必须为绑定式。 |
供应商映像提供的所有其他 HAL 既可以在直通模式下使用,也可以在绑定模式下使用。 |
Google有对一些设备做出规定,是使用直通式还是绑定式的HIDL。
其中指纹相关的HIDL被规定为绑定式的:
android.hardware.biometrics.fingerprint@2.1
。取代 Android 8.0 中已不存在的fingerprintd
。
和AIDL的.aidl文件类似,HIDL也有属于自己的.hal文件,它们通常位于以下目录中:
软件包前缀 | 位置 |
---|---|
android.hardware.* | hardware/interfaces/* |
android.frameworks.* | frameworks/hardware/interfaces/* |
android.system.* | system/hardware/interfaces/* |
android.hidl.* | system/libhidl/transport/* |
HAL层代码则主要位于以下目录下:
hardware/libhardware:新的HAL代码目录,符合android treble架构的设计
hardware/libhardware_legacy:老的HAL代码目录
hardware/ril:Radio Interface Layer(和TELE相关的一些东西,需要和MODEM交互)
HAL层上接Framework Service部分,故,以FingerprintService为切入点。
之前提到过frameworks\base\services\core\java\com\android\server\fingerprint中ClientMonitor类负责和HAL层交互;
/** * Abstract base class for keeping track and dispatching events from fingerprint HAL to the * the current client. Subclasses are responsible for coordinating the interaction with * fingerprint HAL for the specific action (e.g. authenticate, enroll, enumerate, etc.). */public abstract class ClientMonitor implements IBinder.DeathRecipient
这里可以找到使用的HAL对象:
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;//.../** * Gets the fingerprint daemon from the cached state in the container class. */public abstract IBiometricsFingerprint getFingerprintDaemon();
从这个import我们可以确认:
fingerprint的.hal文件目录为:hardware/interfaces/biometrics/fingerprint/2.1
文件名是:IBiometricsFingerprint.hal
然后到对应目录确认下:
嘿,还真的有!
这里先不管HAL层部分,先看看getFingerprintDaemon方法,这个方法定义在FingerprintServcie中:
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; } } return mDaemon;}
这里是通过IBiometricsFingerprint.getService()方法拿到IBiometricsFingerprint对象的。
OK,现在再回过头来看hardware/interfaces/biometrics/fingerprint/2.1
中的内容。
IBiometricsFingerprint和IBiometricsFingerprintClientCallback是两个接口,文件 types.hal
并不定义接口,而是定义软件包中每个接口可以访问的数据类型。
default文件夹内是接口的具体实现。
vts是google测试相关。
这里大概看一下default里面的内容;
android.hardware.biometrics.fingerprint@2.1-service.rc:负责把service加到系统服务
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
再看下service.cpp:
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}
这里会实例化一个BiometricsFingerprint,并通过registerAsService注册到hw服务,也就是上面Frameworkget到的那个服务了。
BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) { sInstance = this; // keep track of the most recent instance mDevice = openHal(); if (!mDevice) { ALOGE("Can't open HAL module"); }}IBiometricsFingerprint* BiometricsFingerprint::getInstance() { if (!sInstance) { sInstance = new BiometricsFingerprint(); } return sInstance;}
BiometricsFingerprint的构造函数中会调用openHal方法,用来拿到指纹设备。
fingerprint_device_t* BiometricsFingerprint::openHal() { int err; const hw_module_t *hw_mdl = nullptr; ALOGD("Opening fingerprint hal library..."); 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;}
既然到了HAL层代码,有一个文件就不得不先提一下,它就是hardware/libhardware/include/hardware/hardware.h
这里面注释很有用,得仔细看!
/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#ifndef ANDROID_INCLUDE_HARDWARE_HARDWARE_H#define ANDROID_INCLUDE_HARDWARE_HARDWARE_H#include #include #include #include __BEGIN_DECLS/* * Value for the hw_module_t.tag field */#define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))#define HARDWARE_MODULE_TAG MAKE_TAG_CONSTANT('H', 'W', 'M', 'T')#define HARDWARE_DEVICE_TAG MAKE_TAG_CONSTANT('H', 'W', 'D', 'T')#define HARDWARE_MAKE_API_VERSION(maj,min) \ ((((maj) & 0xff) << 8) | ((min) & 0xff))#define HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) \ ((((maj) & 0xff) << 24) | (((min) & 0xff) << 16) | ((hdr) & 0xffff))#define HARDWARE_API_VERSION_2_MAJ_MIN_MASK 0xffff0000#define HARDWARE_API_VERSION_2_HEADER_MASK 0x0000ffff/* * The current HAL API version. * * All module implementations must set the hw_module_t.hal_api_version field * to this value when declaring the module with HAL_MODULE_INFO_SYM. * * Note that previous implementations have always set this field to 0. * Therefore, libhardware HAL API will always consider versions 0.0 and 1.0 * to be 100% binary compatible. * */#define HARDWARE_HAL_API_VERSION HARDWARE_MAKE_API_VERSION(1, 0)/* * Helper macros for module implementors. * * The derived modules should provide convenience macros for supported * versions so that implementations can explicitly specify module/device * versions at definition time. * * Use this macro to set the hw_module_t.module_api_version field. */#define HARDWARE_MODULE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min)#define HARDWARE_MODULE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr)/* * Use this macro to set the hw_device_t.version field */#define HARDWARE_DEVICE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min)#define HARDWARE_DEVICE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr)struct hw_module_t;struct hw_module_methods_t;struct hw_device_t;/** * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM * and the fields of this data structure must begin with hw_module_t * followed by module specific information. */typedef struct hw_module_t { /** tag must be initialized to HARDWARE_MODULE_TAG */ uint32_t tag; /** * The API version of the implemented module. The module owner is * responsible for updating the version when a module interface has * changed. * * The derived modules such as gralloc and audio own and manage this field. * The module user must interpret the version field to decide whether or * not to inter-operate with the supplied module implementation. * For example, SurfaceFlinger is responsible for making sure that * it knows how to manage different versions of the gralloc-module API, * and AudioFlinger must know how to do the same for audio-module API. * * The module API version should include a major and a minor component. * For example, version 1.0 could be represented as 0x0100. This format * implies that versions 0x0100-0x01ff are all API-compatible. * * In the future, libhardware will expose a hw_get_module_version() * (or equivalent) function that will take minimum/maximum supported * versions as arguments and would be able to reject modules with * versions outside of the supplied range. */ uint16_t module_api_version;#define version_major module_api_version /** * version_major/version_minor defines are supplied here for temporary * source code compatibility. They will be removed in the next version. * ALL clients must convert to the new version format. */ /** * The API version of the HAL module interface. This is meant to * version the hw_module_t, hw_module_methods_t, and hw_device_t * structures and definitions. * * The HAL interface owns this field. Module users/implementations * must NOT rely on this value for version information. * * Presently, 0 is the only valid value. */ uint16_t hal_api_version;#define version_minor hal_api_version /** Identifier of module */ const char *id; /** Name of this module */ const char *name; /** Author/owner/implementor of the module */ const char *author; /** Modules methods */ struct hw_module_methods_t* methods; /** module's dso */ void* dso;#ifdef __LP64__ uint64_t reserved[32-7];#else /** padding to 128 bytes, reserved for future use */ uint32_t reserved[32-7];#endif} hw_module_t;typedef struct hw_module_methods_t { /** Open a specific device */ int (*open)(const struct hw_module_t* module, const char* id, struct hw_device_t** device);} hw_module_methods_t;/** * Every device data structure must begin with hw_device_t * followed by module specific public methods and attributes. */typedef struct hw_device_t { /** tag must be initialized to HARDWARE_DEVICE_TAG */ uint32_t tag; /** * Version of the module-specific device API. This value is used by * the derived-module user to manage different device implementations. * * The module user is responsible for checking the module_api_version * and device version fields to ensure that the user is capable of * communicating with the specific module implementation. * * One module can support multiple devices with different versions. This * can be useful when a device interface changes in an incompatible way * but it is still necessary to support older implementations at the same * time. One such example is the Camera 2.0 API. * * This field is interpreted by the module user and is ignored by the * HAL interface itself. */ uint32_t version; /** reference to the module this device belongs to */ struct hw_module_t* module; /** padding reserved for future use */#ifdef __LP64__ uint64_t reserved[12];#else uint32_t reserved[12];#endif /** Close this device */ int (*close)(struct hw_device_t* device);} hw_device_t;#ifdef __cplusplus#define TO_HW_DEVICE_T_OPEN(x) reinterpret_cast(x)#else#define TO_HW_DEVICE_T_OPEN(x) (struct hw_device_t**)(x)#endif/** * Name of the hal_module_info */#define HAL_MODULE_INFO_SYM HMI/** * Name of the hal_module_info as a string */#define HAL_MODULE_INFO_SYM_AS_STR "HMI"/** * Get the module info associated with a module by id. * * @return: 0 == success, <0 == error and *module == NULL */int hw_get_module(const char *id, const struct hw_module_t **module);/** * Get the module info associated with a module instance by class 'class_id' * and instance 'inst'. * * Some modules types necessitate multiple instances. For example audio supports * multiple concurrent interfaces and thus 'audio' is the module class * and 'primary' or 'a2dp' are module interfaces. This implies that the files * providing these modules would be named audio.primary..so and * audio.a2dp..so * * @return: 0 == success, <0 == error and *module == NULL */int hw_get_module_by_class(const char *class_id, const char *inst, const struct hw_module_t **module);__END_DECLS#endif /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */
这里定义了三个关键的结构体:
struct hw_module_t; 模块
struct hw_module_methods_t; 模块方法
struct hw_device_t; 设备
这是大家都要用到的。下面看一下指纹相关HAL内容的定义,它们在hardware/libhardware/include/hardware/fingerprint.h
* Synchronous operation */typedef struct fingerprint_device { /** * Common methods of the fingerprint device. This *must* be the first member * of fingerprint_device as users of this structure will cast a hw_device_t * to fingerprint_device pointer in contexts where it's known * the hw_device_t references a fingerprint_device. */ struct hw_device_t common; //此处省略N多函数指针之类的..} fingerprint_device_t;typedef struct fingerprint_module { /** * Common methods of the fingerprint module. This *must* be the first member * of fingerprint_module as users of this structure will cast a hw_module_t * to fingerprint_module pointer in contexts where it's known * the hw_module_t references a fingerprint_module. */ struct hw_module_t common;} fingerprint_module_t;
如果之前对上面代码中openHal里面的强制指针转换有疑惑的话,看到这里基本就可以解惑了。
fingerprint_device 中还定义了很多用于操作指纹器件的函数指针,它们具体实现都在hardware/libhardware/modules/fingerprint/fingerprint.c中,这些内容都是需要设备驱动实现的。
具体根据设备厂商而定,例如之前项目中汇顶的具体实现文件就在vendor/mediatek/proprietary/hardware/fingerprint/goodix/fingerprint.cpp
更多相关文章
- Android--取得MD5指纹,取得MapKey
- Android N 指纹框架
- android 指纹验证api
- Android studio获取证书指纹 (SHA1)的方法
- android M 指纹api小示例
- Android O指纹识别解析
- Android指纹验证
- Android指纹登录工具类封装
- Android 项目生成证书指纹(MD5、SHA1、SHA256)