• Android P HIDL demo代码编写 (原创)


    之前的文章已经分析了HIDL服务的注册和调用,这篇文章来总结下一个HIDL的服务如何编写。

    缩写HAL文件

     首先要确认放置文件夹和接口的包名,因为这跟后面使用脚本生成一部分代码有关,一般默认的放在hardware/interfaces目录下,我们写一个简单的IDemo.hal (hardware/interface/demo/1.0/IDemo.hal)

    package android.hardware.demo@1.0;
    
    interface IDemo {
        init(int32_t level) generates (int32_t initRet);
    
        getProperty(string key) generates (int32_t getResult, string value);
    };

     生成接口的执行代码

    使用如下命令生成执行文件:

    hidl-gen -o hardware/interfaces/demo/1.0/default -Lc++-impl -randroid.hardware:hardware/intefaces -randroid.hidl:system/libhidl/transport android.hardware.demo@1.0

    这个命令会在hardware/interfaces/demo/1.0/default 下生成Demo.cpp 和 Demo.h两个文件,上面那个接口文件里,getProperty里有两个返回值,一般函数都只有一个返回值,那这个两个返回值是回事呢?那我们看看生成的执行代码是怎么样的?

    #include "Demo.h"
    
    namespace android {
    namespace hardware {
    namespace demo {
    namespace V1_0 {
    namespace implementation {
    
    Return<int32_t> Demo::init(int32_t level) {
    //这种返回一个参数就按普通函数的做法,返回值就OK
    return int32_t{}; } Return<void> Demo::getProperty(const hidl_string& key, getProperty_cb _hidl_cb ) { //这里将两个返回值封装到一个回调函数里,然后传给调用者,使用如下 int result = 0; //使用map 里值来返回
      std::Map<hidl_string, hidl_string> demoMap = {
        {"one", "first"},
        {"two", "second"},
        {"three", "third"}
      };

      int result = -1;
      hidl_string value = "";
      auto findRet = demoMap.find(key);
      if(findRet != demoMap.end()){
        result = 0;
        value = findRet->second;
      }
      //这里就将result 和 value 作为参数直接回调给调用者
      _hidl_cb(result, value); return Void(); } } } } }

    生成Android.bp

    方法实现完了之后,就需要用命令再生成一个Android.bp

    hidl-gen -o hardware/interfaces/demo/1.0/default -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.demo@1.0

    执行命令之后,就会在hardeare/interfaces/demo/1.0/default/Android.bp

    进入hardware/interface目录下,执行./update-makefiles.sh之后,会生成demo/1.0/Android.bp 文件

    现在有了两个Android.bp之后,需要采用绑定模式来创建一个Demo服务,在demo/1.0/default下创建一个service.cpp

    添加绑定模式的服务代码

    #include <android-base/logging.h>
    #include <hidl/HidlTransportSupport.h>
    #include <android/hardware/demo/1.0/IDemo.h>
    
    #undef LOG_TAG
    #define LOG_TAG "android.hardware.demo@1.0-service"
    
    #include <hidl/LegacySupport.h>
    #include "Demo.h"
    using android::hardware::configureRpcThreadpool;
    using android::hardware::joinRpcThreadpool;
    using android::hardware::demo::V1.0::implementation::Demo;
    
    int main(){
        configureRpcThreadpool(4, true);
        Demo demo = new Demo();
        auto status = demo.registerAsService();
        if(status != android::OK){
            ALOGE("register demo As Service failed");
            return -1;
        }
        joinRpcThreadpool();
    }

     然后再在demo/1.0/default下创建android.hardware.demo@1.0-service.rc

    service demo_hal_service /vendor/bin/hw/android.hardware.demo@1.0-service
        class hal
        user  system
        group  system

    在demo/1.0/default/Android.bp中增加 init_rc和 service.cpp的编译项,并将cc_library_shared 改为 cc_binary ,具体如下:

    cc_binary {
        name: "android.hardware.demo@1.0-service",
        relative_install_path: "hw",
        proprietary: true,
        init_rc: ["android.hardware.demo@1.0-service.rc"],
        srcs: [
            "Demo.cpp",
            "service.cpp"
        ],  
        shared_libs: [
            "libhidlbase",
            "libhidltransport",
            "libutils",
         "liblog",
    "android.hardware.demo@1.0", ], }

     然后通过mmm 或 mm 的方式 就可以编译出android.hardware.demo@1.0-service 和 android.hardware.demo@1.0-service.rc的服务了。

    如果要自运行,添加上Selinux 的相关权限,可以参考其它HIDL 服务的selinux。

    关于调用HIDL的接口,之前文章分析过,下面我们写核心的几句代码:

    #include <android/hardware/demo/1.0/IDemo.h>
    sp<IDemo> mDemo = IDemo::getService();
    mDemo->init(1);
    string mValue;
    mDemo->getProperty("two", [&](int result, string value) {
           if(result == 0)
                 mVaule = value;
    });

    到这里,HIDL的Demo服务代码可以结束了,后面可以增加复杂的Icallback HIDL接口相关的代码。

  • 相关阅读:
    git this exceeds GitHub's file size limit of 100.00 MB
    使用vue-cli创建vue工程
    【转】Visual Studio Code必备插件
    linux安装openssl
    Centos7离线安装mysql8
    使用nmon来按频率采集数据
    Mac下编译android4.0.4遇到的问题
    32位ubuntu16.4编译android4.1.1
    vmvare安装vmtools菜单灰色
    Substrate 使用
  • 原文地址:https://www.cnblogs.com/jack2010/p/Android_HIDL.html
Copyright © 2020-2023  润新知