新增HIDL服务

一、HIDL概述
HIDL 是用于指定 HAL 与其用户之间接口的一个接口描述语言,它允许将指定的类型与函数调用收集到接口和包中。更广泛地说,HIDL 是一个可以让那些独立编译的代码库之间进行通信的系统。 HIDL 实际上是用于进行进程间通信的。进程间的通信可以称为 Binder 化。对于必须连接到进程的库,也可以使用 passthough 模式。 HIDL 将指定的数据结构与方法签名组织到接口中,这些接口又会被收集到包中以供使用。
HIDL服务的诞生将system分区和vendor分区可以独立升级变成了可能。
在android在camera框架中,HIDL连接cameraserver和cameraprovider两个进程,直通式的HIDL可以让cameraserver进程访问cameraprovider中的相关库。
 
二、实现一个HIDL服务:
1、hardware/interfaces目录下创建lethe_hidl/1.0目录,并在此目录下创建一个Ilethe.hal文件
package android.hardware.lethe_hidl@1.0;        // 类似于java中包的概念                                          

interface Ilethe {
        // 添加一个addition_hidl函数,该函数有两个函数a和b,并返回total
        addition_hidl(uint32_t a, uint32_t b) generates (uint32_t total);
};
使用Android提供的工具hidl-gen来生成HIDL框架,执行如下命令:
 PACKAGE=android.hardware.lethe_hidl@1.0
 LOC=hardware/interfaces/lethe_hidl/1.0/default/
 hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
 hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
2、再在执行./hardware/interfaces/update-makefiles.sh这个命令,update-makefiles.sh这个脚本目的是为HIDL生成对应Android.bp文件。
3、接着我们还需要在default目录下增加一个空文件service.cpp,用作注册HIDL服务。
4、创建一个test文件夹,用作HIDL服务的测试。
5、需要将该HIDL服务注册到manifest.xml文件中,这样才能被framework所获取和识别到。在vendor/etc/vintf/manifest.xml进行修改push进去之后再重启即可生效。
<hal format="hidl">
     <name>android.hardware.lethe_hidl</name>
     <transport>hwbinder</transport>
     <version>1.0</version>
     <interface>
         <name>Ilethe</name>
         <instance>default</instance>
     </interface>
     <fqname>@1.0::Ilethe/default</fqname>
 </hal>
在HIDL服务中,我们也可以调用到之前所写的lethe hal模块。
 
 
下面是具体代码和详细的解释说明:
1.0目录下的Android.bp:
// This file is autogenerated by hidl-gen -Landroidbp.
 
hidl_interface { // hidl-gen生成的.bp文件
  name: "android.hardware.lethe_hidl@1.0", // 名称,在default目录的Android.bp文件引用
  root: "android.hardware", // 定义好的package root name
  vndk: { // vendor ndk
    enabled: true,
  },
  srcs: [ // 源.hal文件
    "Ilethe.hal",
  ],
  interfaces: [ // 编译过程中所依赖的接口名称
    "android.hidl.base@1.0",
  ],
  gen_java: true, // 是否编译为java使用的接口
}
 
default目录下的Android.bp:
// FIXME: your file license if you have one
 
cc_library_shared { // 编译生成native动态库
  name: "android.hardware.lethe_hidl@1.0-impl", // 可执行程序名
  relative_install_path: "hw", // 相对路径,和prop进行组合生成路径
  proprietary: true, // 编译生成到vendor/lib(64)
  srcs: [ // 目标文件
    "lethe.cpp",
  ],
  shared_libs: [ // 编译时依赖的动态库
    "libhidlbase",
    "libhidltransport",
    "libutils",
    "android.hardware.lethe_hidl@1.0",
    "liblog",
    "libhardware",
  ],
}
 
cc_binary { // 生成bin
  name:"android.hardware.lethe_hidl@1.0-service", // 程序名
  defaults: ["hidl_defaults"], // 引用默认模块名称
  relative_install_path: "hw",
  vendor:true, // 是否放在vendor/etc目录下
  srcs: [
    "service.cpp",
  ],
 
  shared_libs: [
    "libhidlbase",
    "libhidltransport",
    "libutils",
    "android.hardware.lethe_hidl@1.0",
    "libhardware",
    "liblog",
  ],
}
 
lethe.h:
// FIXME: your file license if you have one
 
#pragma once

#include <android/hardware/lethe_hidl/1.0/Ilethe.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace lethe_hidl {
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;
 
struct lethe : public Ilethe {
  // Methods from ::android::hardware::lethe_hidl::V1_0::Ilethe follow.
  Return<uint32_t> addition_hidl(uint32_t a, uint32_t b) override;
 
  // Methods from ::android::hidl::base::V1_0::IBase follow.
 
};
 
// 采用直通式需要将该句的注释打开
// FIXME: most likely delete, this is only for passthrough implementations
extern "C" Ilethe* HIDL_FETCH_Ilethe(const char* name);
 
} // namespace implementation
} // namespace V1_0
} // namespace lethe_hidl
} // namespace hardware
} // namespace android

 

lethe.cpp:
// FIXME: your file license if you have one                                                                                                       

#include "lethe.h"
#include <log/log.h>
#include <hardware/hardware.h>
//#include "../../../../libhardware/include/hardware/hardware.h"
#include "../../../../libhardware/include/hardware/lethe.h"
namespace android {
namespace hardware {
namespace lethe_hidl {
namespace V1_0 {
namespace implementation {

lethe_device_t* lethe_device = NULL;
// Methods from ::android::hardware::lethe_hidl::V1_0::Ilethe follow.
Return<uint32_t> lethe::addition_hidl(uint32_t a, uint32_t b) {         // 返回给更上层使用的接口
    // TODO implement
     uint32_t total = 0;
     ALOGE("lethe...hal addition_hidl...");
     lethe_device->add(lethe_device,(int)a,(int)b,(int *)&total);       // 调用lethe hal模块中的lethe_device->add函数
     ALOGE("[lethe]======== add 5 + 3 = %d", total);
     return total;
}


// Methods from ::android::hidl::base::V1_0::IBase follow.

Ilethe* HIDL_FETCH_Ilethe(const char* /* name */) {

        const lethe_module_t * module = NULL;

        ALOGE("lethe lethe_module_t");                                                  // lethe_hidl服务注册成功就会在这里实现打印
        int ret = hw_get_module(LETHE_HARDWARE_MODULE_ID,
                (const struct hw_module_t**)&module);

        if (!ret) {
                ret = lethe_open_test((const struct hw_module_t*)module,&lethe_device);         // 调用到lethe hal模块
        }
        if (ret < 0) {
                ALOGD("lethe hidl get lethe hal service failed .......");
                return NULL;
        }
        ALOGE("lethe hidl get lethe hal service success....");
        return new lethe();
}
//
}  // namespace implementation
}  // namespace V1_0
}  // namespace lethe_hidl
}  // namespace hardware
}  // namespace android

 

service.cpp
#define LOG_TAG "android.hardware.lethe_hidl@1.0-service"                                                             
#include <android/hardware/lethe_hidl/1.0/Ilethe.h>
#include <hidl/LegacySupport.h>
// Generated HIDL files
using android::hardware::lethe_hidl::V1_0::Ilethe;              // 参照camera的命名空间的用法,namespace implementation可以忽略
using android::hardware::defaultPassthroughServiceImplementation;               // 直通式

int main() {
        // 注册hidl服务是,就是通过"HIDL_FETCH_"与"Ilethe"字符串得到的
        return defaultPassthroughServiceImplementation<Ilethe>();               // ()中可以加线程池线程的个数等信息
}

 

test目录下的Android.bp:
cc_binary {                                                                                                                         
    name: "lethe_hidl_test",
    srcs: ["lethe_hidl_test.cpp"],
    shared_libs: [
        "liblog",
        "android.hardware.lethe_hidl@1.0",
        "libhidlbase",
        "libhidltransport",
        "libhwbinder",
        "libutils",
    ],  
}

 

lethe_hidl_test.cpp
#include <android/hardware/lethe_hidl/1.0/Ilethe.h>                                                                              
#include <hidl/LegacySupport.h>
#include <log/log.h>

using android::sp;
using android::hardware::lethe_hidl::V1_0::Ilethe;
using android::hardware::Return;
int main(){
        android::sp<Ilethe> hw_device = Ilethe::getService();    // 获取HDIL服务
        if (hw_device == nullptr) {
                ALOGD("lethe...failed to get lethe-hidl");
                return -1; 
        }
        ALOGD("lethe...success to get lethe-hidl....");
        Return<uint32_t> total = hw_device->addition_hidl(3,4);    // 调用HIDL函数

        return 0;
}

 

 

 

 
posted @ 2024-04-04 23:02  lethe1203  阅读(420)  评论(0编辑  收藏  举报