HAL 接口定义语言(简称 HIDL,发音为“hide-l”)是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL)。HIDL 允许指定类型和方法调用(会汇集到接口和软件包中)。从更广泛的意义上来说,HIDL 是指用于在可以独立编译的代码库之间进行通信的系统。从 Android 10 开始,HIDL 已废弃,Android 将在所有位置改用 AIDL。
1. 准备目录(vendor/my)及hal接口文件
manifest_hello.xml此文件内容在Android R 高通项目中可加入自身项目中device/qcom/xxxxxxx/manifest.xml 用于声明服务
<manifest version="1.0" type="device">
<hal format="hidl">
<name>vendor.my.hello</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>Ihello</name>
<instance>default</instance>
</interface>
</hal>
</manifest>
hardware/interfaces/compatibility_matrices/compatibility_matrix.5.xml 用于framework兼容
<hal format="hidl" optional="true">
<name>vendor.my.hello</name>
<version>1.0</version>
<interface>
<name>Ihello</name>
<instance>default</instance>
</interface>
</hal>
Ihello.hal 定义服务接口
package vendor.my.hello@1.0;
interface Ihello {
hello_open();
};
Android.bp 指定包名及目录映射
hidl_package_root {
name: "vendor.my",
path: "vendor/my",
}
2. hidl-gen 生成对应的android.bp,源码文件,带hash current.txt
bash 运行脚本
PKG_ROOT=vendor/my
PACKAGE=vendor.my.hello@1.0
HIDL_GEN_OUT=$PKG_ROOT/hello/1.0/default
hidl-gen -L androidbp -rvendor.my:$PKG_ROOT -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $HIDL_GEN_OUT -Lc++-impl -r vendor.my:$PKG_ROOT -r android.hidl:system/libhidl/transport $PACKAGE
hidl-gen -L hash -r vendor.my:$PKG_ROOT -randroid.hidl:system/libhidl/transport $PACKAGE >> $PKG_ROOT/current.txt
文件清单
current.txt
4da6c06c236b1b04e6bb150af18dc064b7144b72c7b10cedad9965f8b384b2c5 vendor.my.hello@1.0::types
2eb04c0162c83cc37c953690e46812ac5f5a349ba707c2062c644412ee45d5a8 vendor.my.hello@1.0::Ihello
Android.bp
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: "vendor.my.hello@1.0",
root: "vendor.my",
system_ext_specific: true,
srcs: [
"types.hal",
"Ihello.hal",
],
interfaces: [
"android.hidl.base@1.0",
],
gen_java: true,
}
3. 实现,编译,配置服务启动
这里将服务编译成一个可执行文件,配置开机rc启动
default/Android.bp
// FIXME: your file license if you have one
cc_binary {
name: "vendor.my.hello@1.0-service",
proprietary: true,
compile_multilib: "32",
relative_install_path: "hw",
srcs: [
"hello.cpp",
],
init_rc: [
"vendor.my.hello@1.0-service.rc"
],
shared_libs: [
"libhidlbase",
"libutils",
"liblog",
"vendor.my.hello@1.0",
"libcutils",
],
cppflags: [
],
}
vendor.my.hello@1.0-service.rc
service hello_service /vendor/bin/hw/vendor.my.hello@1.0-service
class hal
user system
group system
安装服务 vendor/xxx/qcom/device.mk
PRODUCT_PACKAGES += \
vendor.my.hello@1.0-service \
vendor.my.hello@1.0-service.rc
4. 添加权限设置device/qcom/sepolicy_vndr/generic/vendor/common/
attributes
attribute hal_hello_client;
attribute hal_hello_server;
attribute hal_hello;
hwservice.te
type hal_hello_hwservice, hwservice_manager_type;
hwservice_contexts
vendor.my.hello::Ihello u:object_r:hal_hello_hwservice:s0
新增hal_hello.te
binder_call(hal_hello_client, hal_hello_server)
binder_call(hal_hello_server, hal_hello_client)
add_hwservice(hal_hello_server, hal_hello_hwservice)
allow hal_hello_client hal_hello_hwservice:hwservice_manager find;
新增hal_hello_default.te
type hal_hello_default, domain;
hal_server_domain(hal_hello_default, hal_hello)
type hal_hello_default_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_hello_default)
vndbinder_use(hal_hello_default)
file_contexts
/(vendor|system/vendor)/bin/hw/vendor\.my\.hello@1\.0-service u:object_r:hal_hello_default_exec:s0
platform_app.te, system_app.te 添加规则使得这两类应用可以调用
allow platform_app hal_hello_hwservice:hwservice_manager find;
allow platform_app hal_hello_default:binder call;
4. Client端口demo实现
目录列表
Android.mk作为 makefile生成HelloClient可执行文件,验证时将HelloClient push 到设备的/vendor/bin/HelloClient
文件清单如下:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloClient
LOCAL_SRC_FILES := HelloClient.cpp main.cpp
LOCAL_SHARED_LIBRARIES:= \
liblog \
libutils \
libtinyalsa \
vendor.my.hello@1.0 \
libhidlbase \
libhidltransport \
libcutils \
libdl \
libbase \
LOCAL_LDLIBS += -llog
LOCAL_CERTIFICATE := platform
include $(BUILD_EXECUTABLE)
HelloClient.cpp
#include "HelloClient.h"
#include <hidl/HidlSupport.h>
#include <vendor/my/hello/1.0/Ihello.h>
using ::vendor::my::hello::V1_0::Ihello;
using ::android::sp;
void HelloClient::open_hello() {
LOGD("open_hello");
sp<Ihello> mDemo = Ihello::getService();
mDemo->hello_open();
}
HelloClient.h
#ifndef NATIVEAPP_HELLOCLIENT_H
#define NATIVEAPP_HELLOCLIENT_H
#include <android/log.h>
#define TAG "TAG"
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
class HelloClient {
public:
void open_hello();
};
#endif //NATIVEAPP_HELLOCLIENT_H
main.cpp
#include "HelloClient.h"
int main(int argc, char *argv[]) {
LOGD("HelloClient exec\n");
HelloClient client;
client.open_hello();
LOGD("HelloClient exit!!!\n");
exit(0);
}