Android9.0 HAL 层开发
一、生成 HAL 代码
1. 生成 hidl-gen 工具
-
source source ./build/envsetup.sh
-
lunch your_project
-
make hidl-gen -j4
2. 编写接口文件
编写 types.hal, IHello.hal, IHelloCallback.hal,Android.bp
-
1. IHello.hal 代码
-
package vendor.tests.hardware.hello@1.0;
-
-
import types;
-
import IHelloCallback;
-
-
interface IHello {
-
get_data_char() generates(Status st, vec<int8_t> version);
-
-
write_data_char(vec<int8_t>data, uint32_t size) generates(int32_t result);
-
-
write_data_string(string data) generates(int32_t result);
-
};
-
2. types.hal 代码
-
package vendor.tests.hardware.hello@1.0;
-
-
enum Status : int32_t{
-
SUCCESS,
-
FAILURE
-
};
-
3. IHelloCallback.hal 代码
-
package vendor.tests.hardware.hello@1.0;
-
-
interface IHelloCallback {
-
oneway onNotifyHelloEvent(string event);
-
};
-
4. Android.bp 代码
-
如果 HAL 代码是在hardware/interfaces 目录下面,则可以在 hardware/interfaces/ 目录执行下面自动生成下面的 Android.bp
-
-
./update-makefiles.sh
-
hidl_interface {
-
name: "vendor.tests.hardware.hello@1.0",
-
root: "vendor.tests.hardware",
-
srcs: [
-
"types.hal",
-
"IHello.hal",
-
"IHelloCallback.hal",
-
],
-
interfaces: [
-
"android.hidl.base@1.0",
-
],
-
types: [
-
"Status",
-
],
-
gen_java: true,
-
}
注意,由于 "vendor.test.hardware.hello@1.0" 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" 目录下面,比如 "vendor.tests.hardware.hello@1.0" 就在 "vendor/tests/interfaces" 下面新建 "hello/1.0" 目录,然后在该目录下面新建 "Android.bp"、 "types.hal"、"IHello.hal"、"IHelloCallback.hal" 等。
在"vendor/tests/interfaces/" 目录下面新建具体实现的目录,比如 "impl",在impl下面新建 ”hello“对应的目录,比如 "hello/1.0/default"目录
3. 配置临时变量,包名,生成代码路径
-
// 包名
-
PACKAGE=vendor.tests.hardware.hello@1.0
-
-
// 生成代码路径
-
LOC=vendor/tests/interfaces/impl/hello/1.0/default/
4. 生成代码
-
生成 c 代码:其中 LOC 指定生成代码的路径:
-
hidl-gen -o $LOC -Lc -impl -rvendor.tests.hardware:vendor/tests/interfaces/ -randroid.hidl:system/libhidl/transport $PACKAGE
-
-
其中 "-r" 参数作用 "-r <package:path root>: 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
二、修改 c 实现代码
1. 通过类方式实现功能
修改 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 <vendor/tests/hardware/hello/1.0/IHello.h>
-
#include <hidl/MQDescriptor.h>
-
#include <hidl/Status.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::sp;
-
-
class Hello : public IHello {
-
public:
-
// Methods from ::vendor::tests::hardware::hello::V1_0::IHello follow.
-
Return<void> get_data_char(get_data_char_cb _hidl_cb) override;
-
Return<int32_t> write_data_char(const hidl_vec<int8_t>& data, uint32_t size) override;
-
Return<int32_t> 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 <vendor/tests/hardware/hello/1.0/IHelloCallback.h>
-
#include <hidl/MQDescriptor.h>
-
#include <hidl/Status.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::sp;
-
-
class HelloCallback : public IHelloCallback {
-
// Methods from ::vendor::tests::hardware::hello::V1_0::IHelloCallback follow.
-
Return<void> 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<void> 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
2. 实现 HelloDeathListener 类
该类继承于 "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 <hidl/MQDescriptor.h>
-
#include <hidl/Status.h>
-
#include <android-base/file.h>
-
#include <android-base/logging.h>
-
#include <android-base/properties.h>
-
#include <android-base/stringprintf.h>
-
#include <android-base/strings.h>
-
#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<IBase>& 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 <log/log.h>
-
-
#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<IBase>& who) {
-
ALOGE("%s", __FUNCTION__);
-
if (mHello != nullptr) {
-
mHello->onServiceDied();
-
}
-
}
-
-
} // namespace implementation
-
} // namespace V1_0
-
} // namespace hello
-
} // namespace hardware
-
} // namespace tests
-
} // namespace vendor
3. 根据 IHello.hal 实现对应接口
-
IHello.hal 中接口:
-
-
// 该方法参数都为 输出参数,即返回值为 Status,返回数据为 vector<int8_t> 实际为 vector<char>,可进行数据转换。
-
get_data_char() generates(Status st, vec<int8_t> version);
-
-
// 该方法参数为 两个输入参赛,一个返回值。
-
write_data_char(vec<int8_t>data, uint32_t size) generates(int32_t result);
-
-
/ 该方法参数为 一个输入参赛,一个返回值。
-
write_data_string(string data) generates(int32_t result);
-
-
-
// Hello.cpp 实现:
-
#include "Hello.h"
-
#include <string.h>
-
#include <log/log.h>
-
#include <android/log.h>
-
-
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<void> Hello::get_data_char(get_data_char_cb _hidl_cb) {
-
static char buffer[] = "hello return data!";
-
std::vector<int8_t> data(buffer, buffer strlen(buffer));
-
-
_hidl_cb(Status::SUCCESS, (const hidl_vec<int8_t>)data);
-
return Void();
-
}
-
-
Return<int32_t> Hello::write_data_char(const hidl_vec<int8_t>& data, uint32_t size) {
-
ALOGE("data: %s, len: %d", data.data(), size);
-
-
return int32_t {0};
-
}
-
-
Return<int32_t> 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
4. 实现HelloService
-
// HelloService.cpp 代码
-
#define LOG_TAG "vendor.tests.hardware.hello@1.0-service"
-
-
#include <stdio.h>
-
#include <android/log.h>
-
#include <utils/SystemClock.h>
-
#include <hidl/HidlTransportSupport.h>
-
#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<Hello>();
-
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;
-
}
5. 更新 Android.bp
-
// 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: "vendor.tests.hardware.hello@1.0-impl",
-
relative_install_path: "hw",
-
defaults: ["hello_defaults"],
-
proprietary: true,
-
srcs: [
-
"Hello.cpp",
-
"HelloCallback.cpp",
-
"HelloDeathListener.cpp",
-
],
-
shared_libs: [
-
"libhidlbase",
-
"libhidltransport",
-
"libutils",
-
"vendor.tests.hardware.hello@1.0",
-
],
-
}
-
-
// new add
-
cc_binary {
-
name: "vendor.tests.hardware.hello@1.0-service",
-
relative_install_path: "hw",
-
defaults: ["hello_defaults"],
-
init_rc: ["vendor.tests.hardware.hello@1.0-service.rc"],
-
rtti: false,
-
srcs: [
-
"HelloService.cpp"
-
],
-
header_libs: [],
-
shared_libs: [
-
"libbase",
-
"libprotobuf-cpp-lite",
-
"libcommon-base",
-
"vendor.tests.hardware.hello@1.0",
-
"vendor.tests.hardware.hello@1.0-impl",
-
],
-
cppflags: [
-
"-fexceptions"
-
]
-
}
6. HAL service 启动 rc文件
-
//vendor.tests.hardware.hello@1.0-service.rc
-
service vendor.tests.hardware.hello-1.0 /vendor/bin/hw/vendor.tests.hardware.hello@1.0-service
-
class hal
-
user system
-
group system inet
7. selinux 标签修改
-
在 xxx.te 中对 service 标签进行修改
-
-
// file_contexs
-
/(vendor|system/vendor)/bin/hw/vendor.tests.hardware.hello@1.0-service 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
8. 对应模块加入系统编译
-
xxx.mk
-
-
PRODUCT_PACKAGES = \
-
vendor.tests.hardware.hello@1.0 \
-
vendor.tests.hardware.hello@1.0-impl \
-
vendor.tests.hardware.hello@1.0-service \
三、client 实现
-
#define LOG_TAG "HelloClient"
-
-
#include <log/log.h>
-
#include <android/log.h>
-
-
#include <hidl/HidlSupport.h>
-
#include <hidl/Status.h>
-
#include <vendor/tests/hardware/hello/1.0/IHello.h>
-
-
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<IHello> helloService = IHello::getService();
-
if (helloService == nullptr) {
-
LOGE("can't not get IHello service!");
-
return -1;
-
}
-
-
Status status = FAILURE;
-
std::vector<int8_t> readBuffer;
-
helloService->get_data_char([&](Status st, std::vector<int8_t> data){
-
status = st; readBuffer = data;
-
});
-
-
-
char str[] = "write data string .....";
-
std::vector<int8_t> writeBuffer(str, str strlen(str));
-
int len = helloService->write_data_char(writeBuffer, strlen(str));
-
-
}
四. 完整测试代码
https://download.csdn.net/download/SHK242673/72544934
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfaggf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01