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被规定为绑定式的:

和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

然后到对应目录确认下:

Android P 指纹 HAL_第1张图片

嘿,还真的有!

这里先不管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中的内容。

Android P 指纹 HAL_第2张图片

IBiometricsFingerprint和IBiometricsFingerprintClientCallback是两个接口,文件 types.hal并不定义接口,而是定义软件包中每个接口可以访问的数据类型。

default文件夹内是接口的具体实现。

vts是google测试相关。

 

这里大概看一下default里面的内容;

Android P 指纹 HAL_第3张图片

[email protected]:负责把service加到系统服务

service vendor.fps_hal /vendor/bin/hw/[email protected]
    # "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 [email protected] 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,指纹)