HIDL则是用来连接Framework和HAL通信,调用HAL层,AOSP的hardware/interfaces/目录下有很多的HIDL
- 一般目录都是hardware/interfaces/xx下,这里我们看fingerprint,具体的位置在 hardware/interface/biometrics/fingerprint/2.1/ 目录下有个 IBiometricsFingerprint.hal
package android.hardware.biometrics.fingerprint@2.1;
import IBiometricsFingerprintClientCallback;
interface IBiometricsFingerprint {
/**
* Set notification callback:
* Registers a user function that must receive notifications from the HAL
* This call must block if the HAL state machine is in busy state until HAL
* leaves the busy state.
*
* @return deviceId is a unique handle for this fingerprint device
这个方法是在HAL层定义的方法
*/
@callflow(next={"setActiveGroup"})
@entry
setNotify(IBiometricsFingerprintClientCallback clientCallback)
generates (uint64_t deviceId);
};
- 然后就可以使用Android提供的工具hidl-gen来生成HIDL框架,执行如下命令:
PACKAGE=android.hardware.fingerprint_hidl@2.1
LOC=hardware/interfaces/biometrics/fingerprint/2.1/default/
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
- 执行命令成功之后我们会发现hardware/interface/biometrics/fingerprint/2.1/下多了一个default目录,进入default目录,里面有三个文件Android.bp,BiometricsFingerprint.cpp,BiometricsFingerprint.h
- 之后再在执行./hardware/interfaces/update-makefiles.sh这个命令,update-makefiles.sh这个脚本目的是为HIDL生成对应Android.bp文件
- 还需要编写一个 service.cpp
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-service"
#include <android/log.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
#include <android/hardware/biometrics/fingerprint/2.1/types.h>
#include "BiometricsFingerprint.h"
using android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
using android::hardware::biometrics::fingerprint::V2_1::implementation::BiometricsFingerprint;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;
int main() {
android::sp<IBiometricsFingerprint> 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
}
- 然后再 Android.bp 加上service.cpp
cc_binary {
name: "android.hardware.biometrics.fingerprint@2.1-service",
defaults: ["hidl_defaults"],
init_rc: ["android.hardware.biometrics.fingerprint@2.1-service.rc"],
vendor: true,
relative_install_path: "hw",
srcs: [
"BiometricsFingerprint.cpp",
"service.cpp",
],
shared_libs: [
"libcutils",
"liblog",
"libhidlbase",
"libhidltransport",
"libhardware",
"libutils",
"android.hardware.biometrics.fingerprint@2.1",
],
}
- HIDL想要被Framework获取使用还需要在manifest.xml中注册,将这个hwservice注册到系统(这样getService()才能找到它) 在/device/(Product)/manifest.xml中添加: 例如: \device\mediatek\mt6771
- 然后执行 mmm hardware/interface/biometrics/fingerprint/2.1/ 就会进行编译,并且生成so库
- 对应java层调用直接可以用这样方式调用
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);
}
}
return mDaemon;
}
getService 方式就可以引用到HIDL层代码使用
- 还有在JNI层中也可以通过类似于 IGnss_V1_1::getService() 获取到HIDL层对象来达到调用
- HIDL中自动在defaut中生成文件xx.cpp以后需要在 HIDL_FETCH_XXX中进行HAL层的初始化操作
IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
hw_module_t* module;
IGnss* iface = nullptr;
int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
if (err == 0) {
hw_device_t* device;
err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
if (err == 0) {
iface = new Gnss(reinterpret_cast<gps_device_t*>(device));
} else {
ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
}
} else {
ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
}
return iface;
}