本文旨在实现一个 android O 上简单的 HAL 库,并用 C++ 实现一个客户端的测试程序。
如果按照以下步骤依次创建并编辑相关文件的话,相信最终来完成这个测试应该是没有什么问题的。
首先在 hardware/interfaces 下新建 hidldebug 文件夹,进入该文件夹,
来吧,一起从"0"开始,先来看一下最终的目录结构:
1 .2 ├── 1.0
3 │ ├── Android.bp4 │ ├── Android.mk5 │ ├── default
6 │ │ ├── Android.bp7 │ │ ├── Hidldebug.cpp8 │ │ ├── Hidldebug.h9 │ │ └── service.cpp10 │ ├── hidldebug_test11 │ │ ├── Android.bp12 │ │ └── client.cpp13 │ └── IHidldebug.hal14 └── Android.bp
当然,你的目录是现在空的,别急,我们一步一步进行,接下来会依次创建每一个文件,
请紧跟操作步骤,缺少的文件夹要自己补充啊。
一、服务端实现
① 创建 .hal 文件 [ IHidldebug.hal ]:
1 IHidldebug.hal2
3 package android.hardware.hidldebug@1.0;4
5 interfaceIHidldebug {6 helloWorld(string name) generates (stringresult);7 };
② 生成相应的 .cpp 及 .h 文件:
1 PACKAGE=android.hardware.hidldebug@1.0
2
3 LOC=hardware/interfaces/hidldebug/1.0/default/
4
5 out/host/linux-x86/bin/hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
③ 修改文件内容并加入函数的实现 [ Hidldebug.cpp ]:
1 #include "Hidldebug.h"
2
3 namespaceandroid {4 namespacehardware {5 namespacehidldebug {6 namespaceV1_0 {7 namespaceimplementation {8
9 //Methods from ::android::hardware::hidldebug::V1_0::IHidldebug follow.
10 Return Hidldebug::helloWorld(const hidl_string&name, helloWorld_cb _hidl_cb) {11 //TODO implement
12 char buf[100];13 ::memset(buf, 0x00, 100);14 ::snprintf(buf, 100, "[Test Routine] Hello, %s", name.c_str());15 hidl_string result(buf);16
17 _hidl_cb(result);18 returnVoid();19 }20
21
22 //Methods from ::android::hidl::base::V1_0::IBase follow.23
24 //IHidldebug* HIDL_FETCH_IHidldebug(const char* /* name */) {25 //return new Hidldebug();26 //}
27
28 } //namespace implementation
29 } //namespace V1_0
30 } //namespace hidldebug
31 } //namespace hardware
32 } //namespace android
④ 头文件基本不变 [ Hidldebug.h ]:
1 #ifndef ANDROID_HARDWARE_HIDLDEBUG_V1_0_HIDLDEBUG_H2 #define ANDROID_HARDWARE_HIDLDEBUG_V1_0_HIDLDEBUG_H
3
4 #include
5 #include
6 #include
7
8 namespaceandroid {9 namespacehardware {10 namespacehidldebug {11 namespaceV1_0 {12 namespaceimplementation {13
14 using::android::hardware::hidldebug::V1_0::IHidldebug;15 using ::android::hidl::base::V1_0::DebugInfo;16 using ::android::hidl::base::V1_0::IBase;17 using::android::hardware::hidl_array;18 using::android::hardware::hidl_memory;19 using::android::hardware::hidl_string;20 using::android::hardware::hidl_vec;21 using::android::hardware::Return;22 using::android::hardware::Void;23 using::android::sp;24
25 struct Hidldebug : publicIHidldebug {26 //Methods from ::android::hardware::hidldebug::V1_0::IHidldebug follow.
27 Return helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) override;28
29 //Methods from ::android::hidl::base::V1_0::IBase follow.
30
31 };32
33 //extern "C" IHidldebug* HIDL_FETCH_IHidldebug(const char* name);
34
35 } //namespace implementation
36 } //namespace V1_0
37 } //namespace hidldebug
38 } //namespace hardware
39 } //namespace android
40
41 #endif //ANDROID_HARDWARE_HIDLDEBUG_V1_0_HIDLDEBUG_H
⑤ 创建 service.cpp:
1 touch hardware/interfaces/hidldebug/1.0/default/service.cpp
⑥ 在 service.cpp 文件中以下内容 [ service.cpp ]:
1 #define LOG_TAG "android.hardware.hidldebug@1.0-service"
2
3 #include
4 #include
5
6 #include "Hidldebug.h"
7
8 using::android::hardware::configureRpcThreadpool;9 using::android::hardware::hidldebug::V1_0::IHidldebug;10 using::android::hardware::hidldebug::V1_0::implementation::Hidldebug;11 using::android::hardware::joinRpcThreadpool;12 using::android::OK;13 using::android::sp;14
15 int main(int /*argc*/, char* /*argv*/[]) {16 sp hidldebug = newHidldebug;17 configureRpcThreadpool(1, true /*will join*/);18 if (hidldebug->registerAsService() !=OK) {19 ALOGE("Could not register service.");20 return 1;21 }22 joinRpcThreadpool();23
24 ALOGE("Service exited!");25 return 1;26 }
⑦ 创建 android.hardware.hidldebug@1.0-service.rc 文件并填入以下内容:
1 service hidldebug_hal_service /vendor/bin/hw/android.hardware.hidldebug@1.0-service2 classhal3 user root4 group root
⑧ 创建服务端的 Android.bp 编译脚本并填入以下内容:
1 cc_binary {2 name: "android.hardware.hidldebug@1.0-service",3 relative_install_path: "hw",4 vendor: true,5 srcs: [6 "Hidldebug.cpp",7 "service.cpp"
8 ],9 init_rc: ["android.hardware.hidldebug@1.0-service.rc"],10 shared_libs: [11 "liblog",12 "libhidlbase",13 "libhidltransport",14 "libutils",15 "libhardware",16 "android.hardware.hidldebug@1.0",17 ],18 }
二、客户端实现
① 客户端代码实现 [ client.cpp ]:
1 # include
2 # include
3 # include
4 # include
5 # include
6 # include
7
8 usingandroid::hardware::hidldebug::V1_0::IHidldebug;9 usingandroid::sp;10 usingandroid::hardware::hidl_string;11
12 intmain()13 {14 intret;15
16 android::sp service =IHidldebug::getService();17 if(service ==nullptr) {18 printf("Failed to get service");19 return -1;20 }21
22 service->helloWorld("Zackary.Liu", [&](hidl_string result) {23 printf("%s", result.c_str());24 });25
26 return 0;27 }
② 客户端的编译脚本内容 [ Android.bp ]:
1 cc_binary {2 name: "hidldebug_test",3 vendor: true,4 srcs: [5 "client.cpp",6 ],7 shared_libs: [8 "liblog",9 "libhidlbase",10 "libutils",11 "android.hardware.hidldebug@1.0",12 ],13 }
三、编译所有文件
① 执行更新脚本,让系统帮我们创建其它需要的脚本文件:
1 hardware/interfaces/update-makefiles.sh
② 比对一下最终的文件结构是否和开篇时说的一样
③ 进行最终的编译:
1 mmm hardware/interfaces/hidldebug/
④ 如果编译成功,将会产出以下的库和可执行文件:
1 system/lib64/android.hardware.hidldebug@1.0.so2 vendor/bin/hw/android.hardware.hidldebug@1.0-service3 vendor/etc/init/android.hardware.hidldebug@1.0-service.rc4 vendor/bin/hidldebug_test
四、运行测试
1 / # vendor/bin/hw/android.hardware.hidldebug@1.0-service &
2 /# hidldebug_test3 [Test Routine] Hello, Zackary.Liu
执行完成,成功调用到我们在服务端实现的函数,拼接了客户端输入的字符串并将其打印出来。
目前只是完成在 hal 层的一个测试,接下来还需要了解下 APP 层的调用流程,并实现一个直接的客户端再来进行测试。