• Android O HIDL Binderized HAL 简单实现


    本文旨在实现一个 android O 上简单的 HAL 库,并用 C++ 实现一个客户端的测试程序。

    如果按照以下步骤依次创建并编辑相关文件的话,相信最终来完成这个测试应该是没有什么问题的。

     

    首先在 hardware/interfaces 下新建 hidldebug 文件夹,进入该文件夹,

    来吧,一起从"0"开始,先来看一下最终的目录结构:

     1 .
     2 ├── 1.0
     3 │   ├── Android.bp
     4 │   ├── Android.mk
     5 │   ├── default
     6 │   │   ├── Android.bp
     7 │   │   ├── Hidldebug.cpp
     8 │   │   ├── Hidldebug.h
     9 │   │   └── service.cpp
    10 │   ├── hidldebug_test
    11 │   │   ├── Android.bp
    12 │   │   └── client.cpp
    13 │   └── IHidldebug.hal
    14 └── Android.bp

    当然,你的目录是现在空的,别急,我们一步一步进行,接下来会依次创建每一个文件,

    请紧跟操作步骤,缺少的文件夹要自己补充啊。

     

    一、服务端实现

    ① 创建 .hal 文件 [ IHidldebug.hal ]:

    1 IHidldebug.hal
    2 
    3 package android.hardware.hidldebug@1.0;
    4 
    5 interface IHidldebug {
    6     helloWorld(string name) generates (string result);
    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 namespace android {
     4 namespace hardware {
     5 namespace hidldebug {
     6 namespace V1_0 {
     7 namespace implementation {
     8 
     9 // Methods from ::android::hardware::hidldebug::V1_0::IHidldebug follow.
    10 Return<void> 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     return Void();
    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_H
     2 #define ANDROID_HARDWARE_HIDLDEBUG_V1_0_HIDLDEBUG_H
     3 
     4 #include <android/hardware/hidldebug/1.0/IHidldebug.h>
     5 #include <hidl/MQDescriptor.h>
     6 #include <hidl/Status.h>
     7 
     8 namespace android {
     9 namespace hardware {
    10 namespace hidldebug {
    11 namespace V1_0 {
    12 namespace implementation {
    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 : public IHidldebug {
    26     // Methods from ::android::hardware::hidldebug::V1_0::IHidldebug follow.
    27     Return<void> 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 <hidl/HidlSupport.h>
     4 #include <hidl/HidlTransportSupport.h>
     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<IHidldebug> hidldebug = new Hidldebug;
    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-service
    2     class hal
    3     user root
    4     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 <android/hardware/hidldebug/1.0/IHidldebug.h>
     2 # include <hidl/Status.h>
     3 # include <hidl/LegacySupport.h>
     4 # include <utils/misc.h>
     5 # include <hidl/HidlSupport.h>
     6 # include <stdio.h>
     7 
     8 using android::hardware::hidldebug::V1_0::IHidldebug;
     9 using android::sp;
    10 using android::hardware::hidl_string;
    11 
    12 int main()
    13 {
    14     int ret;
    15 
    16     android::sp<IHidldebug> 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.so
    2 vendor/bin/hw/android.hardware.hidldebug@1.0-service
    3 vendor/etc/init/android.hardware.hidldebug@1.0-service.rc
    4 vendor/bin/hidldebug_test

    四、运行测试

    1 / # vendor/bin/hw/android.hardware.hidldebug@1.0-service &
    2 / # hidldebug_test
    3 [Test Routine] Hello, Zackary.Liu 

    执行完成,成功调用到我们在服务端实现的函数,拼接了客户端输入的字符串并将其打印出来。

    目前只是完成在 hal 层的一个测试,接下来还需要了解下 APP 层的调用流程,并实现一个直接的客户端再来进行测试。

     

  • 相关阅读:
    洛谷P4547 [THUWC2017]随机二分图
    洛谷P4590 [TJOI2018]游园会
    洛谷P4099 [HEOI2013]SAO
    #4719. 内凸包
    #1612. 天平(scales)
    #3164. 「CEOI2019」立方填词
    #4728. 问题求解
    #2754. Count(count)
    sa模板
    bzoj 2553: [BeiJing2011]禁忌
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/13741364.html
Copyright © 2020-2023  润新知