source source ./build/envsetup.sh
lunch your_project
make hidl-gen -j4
编写 types.hal, IHello.hal, IHelloCallback.hal,Android.bp
1. IHello.hal 代码
package [email protected];
import types;
import IHelloCallback;
interface IHello {
get_data_char() generates(Status st, vec version);
write_data_char(vecdata, uint32_t size) generates(int32_t result);
write_data_string(string data) generates(int32_t result);
};
2. types.hal 代码
package [email protected];
enum Status : int32_t{
SUCCESS,
FAILURE
};
3. IHelloCallback.hal 代码
package [email protected];
interface IHelloCallback {
oneway onNotifyHelloEvent(string event);
};
4. Android.bp 代码
hidl_interface {
name: "[email protected]",
root: "vendor.tests.hardware",
srcs: [
"types.hal",
"IHello.hal",
"IHelloCallback.hal",
],
interfaces: [
"[email protected]",
],
types: [
"Status",
],
gen_java: true,
}
注意,由于 "[email protected]" root 是 "vendor.test.hardware"
所以这个 root 一定是之前定义过的,如果自己新建的root,可以参考下面新建root,比如:
root 包 bp参考写法:
vendor/tests/hardware/Android.bp
hidl_package_root {
name: "vendor.tests.hardware", // root 包名
path: "vendor/tests/interfaces" // root 路径
}
那么所有依赖 "vendor.tests.hardware" 的都在 "vendor/tests/interfaces" 目录下面,比如 "[email protected]" 就在 "vendor/tests/interfaces" 下面新建 "hello/1.0" 目录,然后在该目录下面新建 "Android.bp"、 "types.hal"、"IHello.hal"、"IHelloCallback.hal" 等。
在"vendor/tests/interfaces/" 目录下面新建具体实现的目录,比如 "impl",在impl下面新建 ”hello“对应的目录,比如 "hello/1.0/default"目录
// 包名
[email protected]
// 生成代码路径
LOC=vendor/tests/interfaces/impl/hello/1.0/default/
生成 c++ 代码:其中 LOC 指定生成代码的路径:
hidl-gen -o $LOC -Lc++-impl -rvendor.tests.hardware:vendor/tests/interfaces/ -randroid.hidl:system/libhidl/transport $PACKAGE
其中 "-r" 参数作用 "-r : E.g., android.hardware:hardware/interfaces." 生成的 c++ 代码路径由 "-o" 参数指定,即上面的 LOC 变量定义的路径
生成 c++ 代码的 Android.bp:
hidl-gen -o $LOC -Landroidbp-impl -rvendor.tests.hardware:vendor/tests/interfaces/ -randroid.hidl:system/libhidl/transport $PACKAGE
更新代码 bp 文件
vendor/tests/interfaces/update-makefiles.sh
// 该文件一般的 interfaces 的root 目录都会有,参考 hardware/interfaces/update-makefiles.sh
修改 Helllo.cpp HelloCallback.cpp "struct" 为 "class",并实现对应构造方法,析构方法。
// Hello.h 代码
#ifndef VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLO_H
#define VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLO_H
#include
#include
#include
namespace vendor {
namespace tests {
namespace hardware {
namespace hello {
namespace V1_0 {
namespace implementation {
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
class Hello : public IHello {
public:
// Methods from ::vendor::tests::hardware::hello::V1_0::IHello follow.
Return get_data_char(get_data_char_cb _hidl_cb) override;
Return write_data_char(const hidl_vec& data, uint32_t size) override;
Return write_data_string(const hidl_string& data) override;
// Methods from ::android::hidl::base::V1_0::IBase follow.
Hello();
~Hello();
void onServiceDied();
};
// FIXME: most likely delete, this is only for passthrough implementations
// extern "C" IHello* HIDL_FETCH_IHello(const char* name);
} // namespace implementation
} // namespace V1_0
} // namespace hello
} // namespace hardware
} // namespace tests
} // namespace vendor
#endif // VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLO_H
// HelloCallback.h 代码
#ifndef VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLOCALLBACK_H
#define VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLOCALLBACK_H
#include
#include
#include
namespace vendor {
namespace tests {
namespace hardware {
namespace hello {
namespace V1_0 {
namespace implementation {
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
class HelloCallback : public IHelloCallback {
// Methods from ::vendor::tests::hardware::hello::V1_0::IHelloCallback follow.
Return onNotifyHelloEvent(const hidl_string& event) override;
// Methods from ::android::hidl::base::V1_0::IBase follow.
};
// FIXME: most likely delete, this is only for passthrough implementations
// extern "C" IHelloCallback* HIDL_FETCH_IHelloCallback(const char* name);
} // namespace implementation
} // namespace V1_0
} // namespace hello
} // namespace hardware
} // namespace tests
} // namespace vendor
#endif // VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLOCALLBACK_H
// HelloCallback.cpp 代码
#include "HelloCallback.h"
namespace vendor {
namespace tests {
namespace hardware {
namespace hello {
namespace V1_0 {
namespace implementation {
// Methods from ::vendor::tests::hardware::hello::V1_0::IHelloCallback follow.
Return HelloCallback::onNotifyHelloEvent(const hidl_string& event) {
// TODO implement
return Void();
}
// Methods from ::android::hidl::base::V1_0::IBase follow.
//IHelloCallback* HIDL_FETCH_IHelloCallback(const char* /* name */) {
//return new HelloCallback();
//}
//
} // namespace implementation
} // namespace V1_0
} // namespace hello
} // namespace hardware
} // namespace tests
} // namespace vendor
该类继承于 "android::hardware::hidl_death_recipient",并实现 “serviceDied” 方法,在该方法中调用 Helllo 类的 "onServiceDied"方法
// HelloDeathListener.h 代码
#ifndef VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLO_DEATH_LISTENE_H
#define VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLO_DEATH_LISTENE_H
#include
#include
#include
#include
#include
#include
#include
#include "Hello.h"
#include "HelloCallback.h"
namespace vendor {
namespace tests {
namespace hardware {
namespace hello {
namespace V1_0 {
namespace implementation {
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hidl::base::V1_0::IBase;
using ::android::sp;
using ::android::wp;
class Hello;
class HelloDeathListener : public android::hardware::hidl_death_recipient {
public:
HelloDeathListener(Hello *hello);
virtual ~HelloDeathListener();
virtual void serviceDied(uint64_t cookie, const wp& who) override;
private:
Hello *mHello;
};
} // namespace implementation
} // namespace V1_0
} // namespace hello
} // namespace hardware
} // namespace tests
} // namespace vendor
#endif // VENDOR_TESTS_HARDWARE_HELLO_V1_0_HELLO_DEATH_LISTENE_H
// HelloDeathListener.cpp 代码
#include "HelloDeathListener.h"
#include
#undef LOG_TAG
#define LOG_TAG "Hello@DeathListener"
namespace vendor {
namespace tests {
namespace hardware {
namespace hello {
namespace V1_0 {
namespace implementation {
using namespace android::base;
using namespace std;
HelloDeathListener::HelloDeathListener(Hello *hello) {
ALOGE("%s", __FUNCTION__);
if (hello != nullptr) {
mHello = hello;
}
}
HelloDeathListener:: ~HelloDeathListener() {}
void HelloDeathListener::serviceDied(uint64_t cookie, const wp& who) {
ALOGE("%s", __FUNCTION__);
if (mHello != nullptr) {
mHello->onServiceDied();
}
}
} // namespace implementation
} // namespace V1_0
} // namespace hello
} // namespace hardware
} // namespace tests
} // namespace vendor
IHello.hal 中接口:
// 该方法参数都为 输出参数,即返回值为 Status,返回数据为 vector 实际为 vector,可进行数据转换。
get_data_char() generates(Status st, vec version);
// 该方法参数为 两个输入参赛,一个返回值。
write_data_char(vecdata, uint32_t size) generates(int32_t result);
/ 该方法参数为 一个输入参赛,一个返回值。
write_data_string(string data) generates(int32_t result);
// Hello.cpp 实现:
#include "Hello.h"
#include
#include
#include
namespace vendor {
namespace tests {
namespace hardware {
namespace hello {
namespace V1_0 {
namespace implementation {
Hello::Hello()
{}
Hello::~Hello()
{
}
void Hello::onServiceDied()
{
ALOGE("invoked ");
}
// Methods from ::vendor::tests::hardware::hello::V1_0::IHello follow.
Return Hello::get_data_char(get_data_char_cb _hidl_cb) {
static char buffer[] = "hello return data!";
std::vector data(buffer, buffer+strlen(buffer));
_hidl_cb(Status::SUCCESS, (const hidl_vec)data);
return Void();
}
Return Hello::write_data_char(const hidl_vec& data, uint32_t size) {
ALOGE("data: %s, len: %d", data.data(), size);
return int32_t {0};
}
Return Hello::write_data_string(const hidl_string& data) {
ALOGE("data: %s", data.c_str());
return int32_t {0};
}
// Methods from ::android::hidl::base::V1_0::IBase follow.
//IHello* HIDL_FETCH_IHello(const char* /* name */) {
//return new Hello();
//}
//
} // namespace implementation
} // namespace V1_0
} // namespace hello
} // namespace hardware
} // namespace tests
} // namespace vendor
// HelloService.cpp 代码
#define LOG_TAG "[email protected]"
#include
#include
#include
#include
#include "Hello.h"
using namespace android;
using namespace android::hardware;
using namespace vendor::tests::hardware::hello::V1_0::implementation;
using namespace std::placeholders;
int main(int /* argc */, char * /* argv */[])
{
auto service = std::make_unique();
configureRpcThreadpool(4, true /* callerWillJoin */);
ALOGD("Hello HAL service starting");
status_t status = service->registerAsService();
if (status != OK)
{
ALOGE("Unable to register Hello HAL service (%d)", status);
return 1;
}
ALOGI("Register Hello Service successfully");
joinRpcThreadpool();
return 1;
}
// Android.bp 代码
// new add
cc_defaults {
name: "hello_defaults",
shared_libs: [
"liblog",
"libutils",
"libhidlbase",
"libhardware",
"libhidltransport",
],
vendor: true,
compile_multilib: "64",
cflags: [
"-Wall",
"-Wextra",
"-Werror",
"-Wno-unused-parameter"
],
}
// modify
cc_library_shared {
name: "[email protected]",
relative_install_path: "hw",
defaults: ["hello_defaults"],
proprietary: true,
srcs: [
"Hello.cpp",
"HelloCallback.cpp",
"HelloDeathListener.cpp",
],
shared_libs: [
"libhidlbase",
"libhidltransport",
"libutils",
"[email protected]",
],
}
// new add
cc_binary {
name: "[email protected]",
relative_install_path: "hw",
defaults: ["hello_defaults"],
init_rc: ["[email protected]"],
rtti: false,
srcs: [
"HelloService.cpp"
],
header_libs: [],
shared_libs: [
"libbase",
"libprotobuf-cpp-lite",
"libcommon-base",
"[email protected]",
"[email protected]",
],
cppflags: [
"-fexceptions"
]
}
//[email protected]
service vendor.tests.hardware.hello-1.0 /vendor/bin/hw/[email protected]
class hal
user system
group system inet
在 xxx.te 中对 service 标签进行修改
// file_contexs
/(vendor|system/vendor)/bin/hw/[email protected] u:object_r:hal_hello_default_exec:s0
// hal_hello_default_exec.te
# add for hello
type hal_hello_default, domain, mlstrustedsubject;
typeattribute hal_hello_default nobohaldomain, mlstrustedsubject;
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)
# Allow hwbinder call from hal client to server
binder_call(hal_hello_client, hal_hello_server)
# Add hwservice related rules
add_hwservice(hal_hello_server, hal_hello_hwservice)
allow hal_hello_client hal_hello_hwservice:hwservice_manager find;
#hwbinder_use(hal_hello)
get_prop(hal_hello, hwservicemanager_prop)
allow hal_hello_default mnt_vendor_file:dir rw_dir_perms;
allow hal_hello_default tee_device:chr_file { ioctl open read write };
allow hal_hello_default ion_device:chr_file { ioctl open read write };
typeattribute hal_hello_default system_writes_vendor_properties_violators;
allow hal_hello_default mnt_vendor_crypto_file:dir create_dir_perms;
allow hal_hello_default mnt_vendor_crypto_file:file create_file_perms;
allow hal_hello_default mnt_vendor_crypto_file:filesystem getattr;
allow hal_hello_default vendor_data_nfs_file:dir search;
allow hal_hello_default pki_sdk_file:file { read open execute getattr map };
allow hal_hello_default default_prop:file { read open execute getattr map };
allow hal_hello_default vendor_bean_prop:file { read open execute getattr map };
allow hal_hello_default property_socket:sock_file { write };
allow hal_hello_default init:unix_stream_socket { connectto };
allow hal_hello_default vfat:dir create_dir_perms;
allow hal_hello_default vfat:file create_file_perms;
allow hal_hello_default vfat:filesystem getattr;
allow hal_hello_default mnt_user_log_file:lnk_file read;
allow hal_hello_default mnt_user_file:dir search;
allow hal_hello_default mnt_user_file:lnk_file read;
allow hal_hello_default unlabeled:dir { search write read add_name open create };
allow hal_hello_default unlabeled:file { read append write open create getattr };
// 其中 hal_hello_default_exec 需要自己定义,具体参考系统中的其他修改
// 同时 attributes、hwservice.te、hwservice_contexts 需要对应修改
// attributes 修改
attribute hal_hello;
expandattribute hal_hello true;
attribute hal_hello_client;
expandattribute hal_hello_client true;
attribute hal_hello_server;
expandattribute hal_hello_server false;
// hwservice.te
type hal_hello_hwservice, hwservice_manager_type;
// hwservice_contexts
vendor.tests.hardware.hello::IHello u:object_r:hal_hello_hwservice:s0
xxx.mk
PRODUCT_PACKAGES += \
[email protected] \
[email protected] \
[email protected] \
#define LOG_TAG "HelloClient"
#include
#include
#include
#include
#include
using namespace vendor::tests::hardware::hello::V1_0;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using vendor::tests::hardware::hello::V1_0::IHello;
using vendor::tests::hardware::hello::V1_0::Status;
using android::sp;
using android::status_t;
int main(){
sp helloService = IHello::getService();
if (helloService == nullptr) {
LOGE("can't not get IHello service!");
return -1;
}
Status status = FAILURE;
std::vector readBuffer;
helloService->get_data_char([&](Status st, std::vector data){
status = st; readBuffer = data;
});
char str[] = "write data string .....";
std::vector writeBuffer(str, str+strlen(str));
int len = helloService->write_data_char(writeBuffer, strlen(str));
}
四. 完整测试代码
https://download.csdn.net/download/SHK242673/72544934