1、环境准备

首先准备一份Android源码。

#源码中编译生成hidl-gen

make hidl-gen

下面是hidl-gen的语法:

usage: hidl-gen [-p <root path>] -o <output path> -L <language> [-O <owner>] (-r <interface root>)+ [-R] [-v] [-d <depfile>] FQNAME...

Process FQNAME, PACKAGE(.SUBPACKAGE)*@[0-9]+.[0-9]+(::TYPE)?, to create output.

-h: Prints this menu.
-L <language>: The following options are available:
check : Parses the interface to see if valid but doesn't write any files.
c++ : (internal) (deprecated) Generates C++ interface files for talking to HIDL interfaces.
c++-headers : (internal) Generates C++ headers for interface files for talking to HIDL interfaces.
c++-sources : (internal) Generates C++ sources for interface files for talking to HIDL interfaces.
export-header : Generates a header file from @export enumerations to help maintain legacy code.
c++-impl : Generates boilerplate implementation of a hidl interface in C++ (for convenience).
c++-impl-headers: c++-impl but headers only.
c++-impl-sources: c++-impl but sources only.
c++-adapter : Takes a x.(y+n) interface and mocks an x.y interface.
c++-adapter-headers: c++-adapter but helper headers only.
c++-adapter-sources: c++-adapter but helper sources only.
c++-adapter-main: c++-adapter but the adapter binary source only.
java : (internal) Generates Java library for talking to HIDL interfaces in Java.
java-constants : (internal) Like export-header but for Java (always created by -Lmakefile if @export exists).
vts : (internal) Generates vts proto files for use in vtsd.
makefile : (removed) Used to generate makefiles for -Ljava and -Ljava-constants.
androidbp : (internal) Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter.
androidbp-impl : Generates boilerplate bp files for implementation created with -Lc++-impl.
hash : Prints hashes of interface in `current.txt` format to standard out.
function-count : Prints the total number of functions added by the package or interface.
dependencies : Prints all depended types.
-O <owner>: The owner of the module for -Landroidbp(-impl)?.
-o <output path>: Location to output files.
-p <root path>: Android build root, defaults to $ANDROID_BUILD_TOP or pwd.
-R: Do not add default package roots if not specified in -r.
-r <package:path root>: E.g., android.hardware:hardware/interfaces.
-v: verbose output.
-d <depfile>: location of depfile to write to.

2、创建hidl

在vendor/qcom/proprietary/interfaces下创建howie目录,在howie下创建1.0目录,在1.0目录下创建接口IHowie.hal,包名设置为自定义vendor.oem.hardware.howie的创建目录default。

package vendor.qcom.hardware.howie@1.0;interface IHowie{helloWorld(string name) generates (string result);
};

这时候,目录结构为:

howie/

└── 1.0

    ├── default

    └── IHowie.hal

在1.0下写一个hidl-gen.sh脚本

# -o <output path>: Location to output files.
# -r <package:path root>: E.g., android.hardware:hardware/interfaces.
# -L <language>
#   androidbp : (internal) Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter.
#   androidbp-impl : Generates boilerplate bp files for implementation created with -Lc++-impl.
#   c++-impl : Generates boilerplate implementation of a hidl interface in C++ (for convenience).PACKAGE=vendor.qcom.hardware.howie@1.0
LOC=default
# 生成Android.bp
hidl-gen -L androidbp -r vendor.qcom.hardware:vendor/qcom/proprietary/interfaces -r android.hidl:system/libhidl/transport $PACKAGE
# 生成Android.bp
hidl-gen -o $LOC -L androidbp-impl -r vendor.qcom.hardware:vendor/qcom/proprietary/interfaces -r android.hidl:system/libhidl/transport $PACKAGE
# 生成C++文件
hidl-gen -o $LOC -L c++-impl -r vendor.qcom.hardware:vendor/qcom/proprietary/interfaces -r android.hidl:system/libhidl/transport $PACKAGE

运行后,目录结构为:

.
└── 1.0
    ├── Android.bp
    ├── default
    │   ├── Android.bp
    │   ├── Howie.cpp
    │   └── Howie.h
    ├── hidl-gen.sh
    └── IHowie.hal

2 directories, 6 files

1.0目录下的Android.bp

// This file is autogenerated by hidl-gen -Landroidbp.hidl_interface {name: "vendor.qcom.hardware.howie@1.0",root: "vendor.qcom.hardware",system_ext_specific: true,srcs: ["IHowie.hal",],interfaces: ["android.hidl.base@1.0",],gen_java: true,
}

我们稍作修改

// This file is autogenerated by hidl-gen -Landroidbp.hidl_interface {name: "vendor.qcom.hardware.howie@1.0",root: "vendor.qcom.hardware.howie",required: ["manifest_vendor.qcom.hardware.howie.xml"],//vendor: true,srcs: ["IHowie.hal",],interfaces: ["android.hidl.base@1.0",],gen_java: true,
}

1.0/default目录下的Android.bp

// FIXME: your file license if you have onecc_library_shared {// FIXME: this should only be -impl for a passthrough hal.// In most cases, to convert this to a binderized implementation, you should:// - change '-impl' to '-service' here and make it a cc_binary instead of a//   cc_library_shared.// - add a *.rc file for this module.// - delete HIDL_FETCH_I* functions.// - call configureRpcThreadpool and registerAsService on the instance.// You may also want to append '-impl/-service' with a specific identifier like// '-vendor' or '-<hardware identifier>' etc to distinguish it.name: "vendor.qcom.hardware.howie@1.0-impl",relative_install_path: "hw",// FIXME: this should be 'vendor: true' for modules that will eventually be// on AOSP.proprietary: true,srcs: ["Howie.cpp",],shared_libs: ["libhidlbase","libutils","vendor.qcom.hardware.howie@1.0",],
}

稍作修改

cc_library_shared {// FIXME: this should only be -impl for a passthrough hal.// In most cases, to convert this to a binderized implementation, you should:// - change '-impl' to '-service' here and make it a cc_binary instead of a//   cc_library_shared.// - add a *.rc file for this module.// - delete HIDL_FETCH_I* functions.// - call configureRpcThreadpool and registerAsService on the instance.// You may also want to append '-impl/-service' with a specific identifier like// '-vendor' or '-<hardware identifier>' etc to distinguish it.name: "vendor.qcom.hardware.howie@1.0-impl",//relative_install_path: "hw",// FIXME: this should be 'vendor: true' for modules that will eventually be// on AOSP.vendor: true,srcs: ["Howie.cpp",],shared_libs: ["libhidlbase","libutils","vendor.qcom.hardware.howie@1.0",],
}

Howie.h

// FIXME: your file license if you have one#pragma once#include <vendor/qcom/hardware/howie/1.0/IHowie.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>namespace vendor::qcom::hardware::howie::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 Howie : public V1_0::IHowie {// Methods from ::vendor::qcom::hardware::howie::V1_0::IHowie follow.Return<void> helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) override;// Methods from ::android::hidl::base::V1_0::IBase follow.};// FIXME: most likely delete, this is only for passthrough implementations
// extern "C" IHowie* HIDL_FETCH_IHowie(const char* name);}  // namespace vendor::qcom::hardware::howie::implementation

Howie.cpp

// FIXME: your file license if you have one#include "Howie.h"namespace vendor::qcom::hardware::howie::implementation {// Methods from ::vendor::qcom::hardware::howie::V1_0::IHowie follow.
Return<void> Howie::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {// TODO implementreturn Void();
}// Methods from ::android::hidl::base::V1_0::IBase follow.//IHowie* HIDL_FETCH_IHowie(const char* /* name */) {//return new Howie();
//}
//
}  // namespace vendor::qcom::hardware::howie::implementation

如上面的注释所说,如果将下面的几行注释去掉,hidl将采用直通式通信方式。

// extern "C" IHowie* HIDL_FETCH_IHowie(const char* name);

//IHowie* HIDL_FETCH_IHowie(const char* /* name */) {
    //return new Howie();
//}

下面,润色一下Howie.cpp

// FIXME: your file license if you have one#include "Howie.h"namespace vendor::qcom::hardware::howie::implementation {// Methods from ::vendor::qcom::hardware::howie::V1_0::IHowie follow.
Return<void> Howie::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {char buf[128];::memset(buf, 0, 128);::snprintf(buf, 128, "Hello World, %s", name.c_str());hidl_string result(buf);_hidl_cb(result);return Void();
}// Methods from ::android::hidl::base::V1_0::IBase follow.//IHowie* HIDL_FETCH_IHowie(const char* /* name */) {//return new Howie();
//}
//
}  // namespace vendor::qcom::hardware::howie::implementation

我希望hidl接口和实现都编译到vendor分区,因此需要做出一点改动:

vendor.qcom.hardware.howie@1.0的root修改为"vendor.qcom.hardware.howie";

将1.0/Android.bp的"system_ext_specific: true,"改成"vendor: true,";

将1.0/default/Android.bp的"proprietary: true,"改成"vendor: true,",后面碰到编译问题,这一行可以注释掉;

vendor.qcom.hardware.howie@1.0-impl移除relative_install_path: "hw",因为会碰到找不到该动态库的问题;

除此以外,在howie目录下新增Android.bp

subdirs = ["1.0",
]hidl_package_root {name: "vendor.qcom.hardware.howie",path: "vendor/qcom/proprietary/interface/howie",
}

3、构建service

为了能调用到先前创建的hidl接口,我们在default下面再创建一个service.cpp,通过直通式注册服务。

#define LOG_TAG "vendor.qcom..hardware.howie@1.0-service"#include <vendor/qcom/hardware/howie/1.0/IHowie.h>
#include <hidl/LegacySupport.h>using vendor::qcom::hardware::howie::V1_0::IHowie;
using android::hardware::defaultPassthroughServiceImplementation;int main() {return defaultPassthroughServiceImplementation<IHowie>(10);//10表示与/dev/hwbinder通信的最大的线程数
}

绑定式写法:

#define LOG_TAG "vendor.qcom..hardware.howie@1.0-service"#include <utils/Log.h>
#include "android/log.h"
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <utils/String16.h>
#include <vendor/qcom/hardware/howie/1.0/IHowie.h>
#include <hidl/LegacySupport.h>
#include "Howie.h"using vendor::qcom::hardware::howie::V1_0::IHowie;
using vendor::qcom::hardware::howie::implementation::Howie;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;
using android::status_t;
using android::OK;int main() {configureRpcThreadpool(10, true);sp<IHowie> howie = new Howie();status_t status = howie->registerAsService();LOG_ALWAYS_FATAL_IF(status != OK, "Could not register IHowie");// other interface registration comes herejoinRpcThreadpool();return 0;
}

同时在default目录下创建rc文件——vendor.qcom.hardware.howie@1.0-service.rc,用于启动vendor.qcom..hardware.howie@1.0-service。

service howie_service /vendor/bin/hw/vendor.qcom.hardware.howie@1.0-serviceclass haluser systemgroup system

由于新增了两个文件,想要将这两个文件也编进系统,需要再次编辑1.0/default下的Android.bp,如下为新增的:

//新增如下
cc_binary {name: "vendor.qcom.hardware.howie@1.0-service",defaults: ["hidl_defaults"],vendor: true,relative_install_path: "hw",srcs: ["service.cpp"],init_rc: ["vendor.qcom.hardware.howie@1.0-service.rc"],shared_libs: ["libhidlbase","libhidltransport","libutils","liblog","vendor.qcom.hardware.howie@1.0","vendor.qcom.hardware.howie@1.0-impl",],
}

4、设备清单和框架清单

为了能为server被client访问到,在howie目录下新增目录vintf,在vintf目录下新增设备清单manifest_vendor.qcom.hardware.howie.xml和框架清单vendor_framework_compatibility_matrix.xml。

<manifest version="1.0" type="device"><!-- Howie service--><hal format="hidl"><name>vendor.qcom.hardware.howie</name><transport>hwbinder</transport><version>1.0</version><interface><name>IHowie</name><instance>default</instance></interface></hal>
</manifest>
<compatibility-matrix version="1.0" type="framework"><hal format="hidl" optional="true"><name>vendor.qcom.hardware.howie</name><impl level="generic"></impl><version>1.0</version><interface><name>IHowie</name><instance>default</instance></interface></hal>
</compatibility-matrix>

将两个清单文件加入编译,新增vendor_framework_compatibility_matrix.mk

DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE += \vendor/qcom/proprietary/interface/howie/vintf/vendor_framework_compatibility_matrix.xml

新增Android.bp

prebuilt_etc_xml {name: "manifest_vendor.qcom.hardware.howie.xml",src: "manifest_vendor.qcom.hardware.howie.xml",vendor: true,installable: true,sub_dir: "vintf/manifest",
}

同时,为了vintf下新增的vendor_framework_compatibility_matrix.mk被编译到,在howie目录下新增Android.mk

LOCAL_PATH := $(call my-dir)include $(call all-makefiles-under,$(LOCAL_PATH))

将vintf也加入到howie下的Android.bp

subdirs = ["1.0","vintf",
]

5、新增测试client

在1.0目录下新增test目录,在test下面新增如下文件:

HowieTest.cpp

#include <vendor/qcom/hardware/howie/1.0/IHowie.h>
#include <hidl/Status.h>
#include <hidl/LegacySupport.h>
#include <utils/misc.h>
#include <hidl/HidlSupport.h>
#include <stdio.h>using ::android::hardware::hidl_string;
using ::android::sp;
using vendor::qcom::hardware::howie::V1_0::IHowie;int main(){android::sp<IHowie> service = IHowie::getService();if (service == nullptr){printf("Failed to get service\n");return -1;}service->helloWorld("Howie", [&](hidl_string result){printf("%s\n", result.c_str());});return 0;
}

Android.bp

cc_binary {name: "howie_client",defaults: ["hidl_defaults"],vendor: true,relative_install_path: "hw",srcs: ["HowieTest.cpp"],shared_libs: ["liblog","libhardware","libhidlbase","libhidltransport","libutils","vendor.qcom.hardware.howie@1.0",],}

重新修改目录howie下的Android.bp,将test加入其中。

subdirs = ["1.0","vintf","test",
]

6、编译

mmm vendor/qcom/proprietary/interfaces/howie

按照之前的编译规则,我们可以在以下的路径中找到编译产物,out/target/product/${PRODUCT}/下,找到这些产物后,push到手机对应目录下即可:

/vendor/lib64/vendor.qcom.hardware.howie@1.0.so

/vendor/lib64/vendor.qcom.hardware.howie@1.0-impl.so

/vendor/bin/hw/vendor.qcom.hardware.howie@1.0-service

/vendor/etc/init/vendor.qcom.hardware.howie@1.0-service.rc

/vendor/etc/vintf/manifest/manifest_vendor.qcom.hardware.howie.xml

产物vendor_framework_compatibility_matrix.xml没找到,需要将手机中的/vendor/etc/vintf/compatibility_matrix.xml手动pull出来,然后添加以下内容,并push手机中原文件位置处。

    <hal format="hidl" optional="true"><name>vendor.qcom.hardware.howie</name><impl level="generic"></impl><version>1.0</version><interface><name>IHowie</name><instance>default</instance></interface></hal>

7、运行测试

上述文件全部push后重启手机。重启后,在终端模拟器中做如下操作:

#获取root权限

adb root

#运行service

adb shell

cd vendor/bin/hw

./vendor.qcom.hardware.howie@1.0-service

另起一个终端模拟器

adb shell

cd vendor/bin/hw

./howie_client

这时候,终端模拟器会打印信息:

Hello World, Howie

8、添加HIDL接口的hash值

上述添加hidl接口后,会报VTS问题,这时候需要添加hidl接口的hash值

通过修改hidl-gen.sh,注意,这里需要将之前的生成C++文件和bp文件的语句注释掉,否则前面写的内容就全部没了。

# -o <output path>: Location to output files.
# -r <package:path root>: E.g., android.hardware:hardware/interfaces.
# -L <language>
#   androidbp : (internal) Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter.
#   androidbp-impl : Generates boilerplate bp files for implementation created with -Lc++-impl.
#   c++-impl : Generates boilerplate implementation of a hidl interface in C++ (for convenience).PACKAGE=vendor.qcom.hardware.howie@1.0
# 生成Android.bp
#hidl-gen -Landroidbp -rvendor.qcom.hardware.howie:vendor/qcom/proprietary/interfaces/howie -randroid.hidl:system/libhidl/transport $PACKAGE
#LOC=default
# 生成C++文件
#hidl-gen -o $LOC -Lc++-impl -rvendor.qcom.hardware:vendor/qcom/proprietary/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
# 生成Android.bp
#hidl-gen -o $LOC -Landroidbp-impl -rvendor.qcom.hardware:vendor/qcom/proprietary/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
CURRENT_PATH="$(dirname $(readlink -f "$0"))"
CURRENT_FILE="${CURRENT_PATH}/../current.txt"
if [ ! -f ${CURRENT_FILE} ]
thentouch ${CURRENT_FILE}
fi
hidl-gen -Lhash -rvendor.qcom.hardware.howie:vendor/qcom/proprietary/interfaces/howie $PACKAGE >> ${CURRENT_FILE}

然后运行脚本,就会在vendor/qcom/proprietary/interfaces/howie下看到current.txt文件了

9c2be150b345854b44ea713cbd64ea64e45932f78ff30770e736286100df5777 vendor.qcom.hardware.howie@1.0::IHowie

9、资源链接

androidhidlhowie.zip-Android文档类资源-CSDN下载

参考文章:

[1] HIDL最全编译流程_Gunder的博客-CSDN博客_hidl编译

[2] https://www.jianshu.com/p/fd73ab98e423

[3] https://www.jianshu.com/p/ca6823b897b5

[4] Android P HIDL服务绑定模式与直通模式的分析 (原创) - five.li - 博客园

[5] 添加HIDL接口hash值(解VTS问题)_JoggingPig的博客-CSDN博客

Android Hidl开发相关推荐

  1. Android HIDL第一个HelloWorld demo

    原址 写在前面 程序员有个癖好,无论是学习什么新知识,都喜欢以HelloWorld作为一个简单的例子来开头,咱们也不例外. OK,咱这里都是干货,废话就不多说啦,学习HIDL呢咱们还是需要一些准备工作 ...

  2. Android HIDL学习 - HelloWord入门(整理1)

    Android HIDL学习(整理1) 概述 入手准备 实例应用 1.HIDL接口文件定义 2. 生成HAL相关文件 3. 实现HAL服务端的共享库 4. Hal server端启动注册程序 5.HI ...

  3. Android HIDL 介绍学习和实战应用

    什么是HIDL? 官方回答: HAL 接口定义语言(简称 HIDL,发音为"hide-l")是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL).HIDL 允许指定 ...

  4. Android WiFi开发教程(三)——WiFi热点数据传输

    在上一篇文章中介绍了WiFi的搜索和连接,如果你还没阅读过,建议先阅读上一篇Android WiFi开发教程(二)--WiFi的搜索和连接.本篇接着简单介绍手机上如何通过WiFi热点进行数据传输. 跟 ...

  5. android ble 设备扫描程序,Android应用开发Android 7.0 BLE scan 问题:程序无错但扫描不到BLE设备...

    本文将带你了解Android应用开发Android 7.0  BLE scan 问题:程序无错但扫描不到BLE设备,希望本文对大家学Android有所帮助. < 最近在做毕设,需要几周内从头学起 ...

  6. Android Studio开发环境及第一个项目

    1. 在你的电脑上搭建Android平台开发环境. 2. 新建项目,实现以下基本内容: (1) 修改默认的APP的名称和图标(任意的,非默认的). (2) 显示个人信息,包括:照片.专业.姓名.学号等 ...

  7. Android UI开发第二十五篇——分享一篇自定义的 Action Bar

    Action Bar是android3.0以后才引入的,主要是替代3.0以前的menu和tittle bar.在3.0之前是不能使用Action Bar功能的.这里引入了自定义的Action Bar, ...

  8. [转]Android敏捷开发指南

    原文地址:http://www.apkbus.com/android-72730-1-1.html 本文紧密结合移动开发方法与技术,围绕Android平台的开发探讨提供更高质量移动产品的解决方案.作者 ...

  9. 《Android传感器开发与智能设备案例实战》——导读

    本节书摘来自异步社区<Android传感器开发与智能设备案例实战>一书中的目录,作者 朱元波,更多章节内容可以访问云栖社区"异步社区"公众号查看 目 录 前 言 第1章 ...

最新文章

  1. 2014年MCM美国大学生数学建模——From my perspective
  2. greenplum error!
  3. 艾伟_转载:DataTable.NewRow 内存泄漏问题
  4. javase 超市库存系统
  5. onedrive-cf-index 搭建教程
  6. 域名升级访问中拿笔记好_SEO优化中如何让你的页面访问速度更快
  7. IIS经典模式和集成模式的区别
  8. 耗时一周,我用Python爬取全国各地大学校花(高清照片和个人信息)
  9. ntko php,NTKO 附件管理控件_
  10. 最简单的RC振荡电路图大全
  11. Spring框架详解
  12. Airtest与夜神模拟器连接
  13. 手机连接Wi-Fi不能上网之DNS异常
  14. MATLAB批量读取文件夹名,文件名,文件数据
  15. div 设置a4大小_A4纸网页打印 html网页页面的宽度设置成多少
  16. vs2017无法打开文件atls.lib问题
  17. 快解析教你,快速注册个人域名
  18. 李 小 龙 个 人 训 练 表
  19. 乌鸦救赎《社交光环》
  20. oracle rac节点重启,oracle RAC一个节点频繁重启解决

热门文章

  1. HTML中 用CSS样式实现 文字两边添加水平线
  2. Mongdb篇三。 用Python代码实现Mongdb数据库的增删查改、集合管道示例,超详细,全部用实例print大法演示功能通俗易懂。学pymongo库看一篇就够
  3. CM201-2-ZG-Hi3798MV300/MV300H/MV310-当贝纯净桌面-卡刷固件包
  4. Matlab 三维装箱遗传算法实现
  5. Kubernets健康检查——配置存活、就绪和启动探测器
  6. 细谈position属性:static、fixed、relative与absolute
  7. 2023最新豆十三沙雕视频教学全套课程/附带完整素材和插件
  8. matlab利用shp文件提取单个或者任意个中国各个省份的降雨
  9. Java核心全知识点梳理
  10. python导入模块错误_Python导入模块时遇到的错误分析