目录

1. 编写hal文件并编译

2. 实现Hidl Interface

3. 编写hdil service

4. 配置manifest.xml

5. hidl client端调用

5.1 实现java调用hidl service的例子

5.2 实现C++ 调用hidl service的例子

6. github地址


本文以LED为例在aosp上添加HIDL,以熟悉整个过程。

1. 编写hal文件并编译

在hardware/interfaces/目录下创建led文件夹和基版本1.0,这个版本号分为两部分,major.minor。major版本不变得话,只能添加api,不能修改。

创建ILed.hal和types.hal

hardware/interfaces/led/1.0/ILed.hal

package android.hardware.led@1.0;interface ILed
{//get led status get() generates (LedStatus result);//set led status set(LedStatus  val) generates(int32_t  ret);getBrightnessRange() generates(bool ret,BrightnessRange range);setBrightnessValue(vec<int32_t> range) generates(bool ret);on() ;off() ;};
 

hardware/interfaces/led/1.0/types.hal

package android.hardware.led@1.0;enum LedStatus : uint32_t {LED_ON,LED_OFF,LED_BAD_VALUE,
};struct BrightnessRange {uint32_t min;uint32_t max;
};

添加完后,执行hardware/interfaces/update-makefiles.sh 会自动生成编译编译脚本,然后在

hardware/interfaces/led/1.0/ 路径下执行mm,会生成所需要得hidl库,接下来我们需要实现hidl interface,供client调用。

2. 实现Hidl Interface

首先实现ILed interface的子类ledImpl 得头文件和对应得cpp。

hardware/interfaces/led/1.0/default/ledImpl.h

#ifndef ANDROID_HARDWARE_LED_V1_0_LED_H
#define ANDROID_HARDWARE_LED_V1_0_LED_H
#include <android/hardware/led/1.0/ILed.h>#include <hidl/Status.h>#include <hidl/MQDescriptor.h>namespace android {
namespace hardware {
namespace led {
namespace V1_0 {
namespace implementation {using ::android::hardware::led::V1_0::LedStatus;
using ::android::hardware::led::V1_0::BrightnessRange;
using ::android::hardware::led::V1_0::ILed;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;struct ledImpl : public ILed {public:ledImpl();Return<LedStatus>  get() override ;Return<int32_t> set(LedStatus val) override;Return<void> on() override;Return<void> off() override;Return<void> getBrightnessRange(getBrightnessRange_cb _hidl_cb) override;Return<bool> setBrightnessValue(const hidl_vec<int32_t>& range) override;private:LedStatus state;
};extern "C" ILed* HIDL_FETCH_ILed(const char* name);
}  // namespace implementation
}  // namespace V1_0
}  // namespace led
}  // namespace hardware
}  // namespace android#endif //ANDROID_HARDWARE_LED_V1_0_LED_H
hardware/interfaces/led/1.0/default/ledImpl.cpp
#define LOG_TAG "LedService"#include <log/log.h>
#include "ledImpl.h"namespace android {
namespace hardware {
namespace led {
namespace V1_0 {
namespace implementation {ledImpl::ledImpl() {state = LedStatus::LED_BAD_VALUE;ALOGE("ledImpl Init status:%d", state);
}Return<void> ledImpl::on() {state = LedStatus::LED_ON;ALOGE("ledImpl on status:%d", state);return Void();
}Return<void> ledImpl::off() {state = LedStatus::LED_OFF;ALOGE("ledImpl off status:%d", state);    return Void();
}Return<LedStatus>  ledImpl::get() {return state;
}
Return<int32_t> ledImpl::set(LedStatus val) {if(val == LedStatus::LED_OFF || val == LedStatus::LED_ON)state = val;elsereturn -1;return 0;
}Return<void> ledImpl::getBrightnessRange(getBrightnessRange_cb _hidl_cb)
{ALOGE("ledImpl getBrightnessRange ");BrightnessRange range;range.max = 100;range.min = 1;_hidl_cb(true,range);return Void();}Return<bool> ledImpl::setBrightnessValue(const hidl_vec<int32_t>& range)
{ALOGE("ledImpl getBrightnessValue ");auto iter = range.begin();ALOGE("ledImpl getBrightnessValue range.begin: %d",*iter);iter = range.end();ALOGE("ledImpl getBrightnessValue range.end: %d",*iter);ALOGE("ledImpl getBrightnessValue range.size: %zu",range.size());return true;
}ILed* HIDL_FETCH_ILed(const char * /*name*/) {ALOGE("ledImpl HIDL_FETCH_ILed "); return new ledImpl();
}}  // namespace implementation
}  // namespace V1_0
}  // namespace led
}  // namespace hardware
}  // namespace android

hardware/interfaces/led/1.0/default/Android.bp

cc_library_shared {name: "android.hardware.led@1.0-impl",defaults: ["hidl_defaults"],srcs: ["ledImpl.cpp"],shared_libs: ["libhidlbase","libhidltransport","libhardware","liblog","libutils","android.hardware.led@1.0",],
}cc_binary {name: "android.hardware.led@1.0-service",init_rc: ["android.hardware.led@1.0-service.rc"],srcs: ["service.cpp","ledImpl.cpp"],shared_libs: ["liblog","libhardware","libhidlbase","libhidltransport","libutils","android.hardware.led@1.0",], }

3. 编写hdil service

接下来,使用相应功能填写存根并设置守护进程。可以使用passthrough方式和binder方式,示例:

hardware/interfaces/led/1.0/default/service.cpp

#define LOG_TAG "android.hardware.led@1.0-service"#include <android/hardware/led/1.0/ILed.h>
#include <hidl/LegacySupport.h>
#include "ledImpl.h"
using android::hardware::led::V1_0::ILed;
using android::hardware::led::V1_0::implementation::ledImpl;
using android::hardware::defaultPassthroughServiceImplementation;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;int main() {
#if 0
// Passthrough   dlopen so方式return defaultPassthroughServiceImplementation<Iled>();
#else
// Binder 方式sp<ILed> service = new ledImpl();configureRpcThreadpool(1, true /*callerWillJoin*/);if(android::OK !=  service->registerAsService())return 1; joinRpcThreadpool();
#endif
}

4. 配置manifest.xml

add the code to the manifest.xm 以至于hwservicemanager 查找到指定的hidl service

About HIDL configures

device/<vendorxxx>/<devicexxx>/manifest.xml

 <hal format="hidl"><name>android.hardware.led</name><transport>hwbinder</transport>  //hwbinder 或者passthrough (直通模式)  <version>1.0</version><interface><name>ILed</name><instance>default</instance></interface></hal>

5. hidl client端调用

hidl service运行后,可以通过C++和Java两种方式调用,非常方便,通过java直接访问,就省去了jni。

5.1 实现java调用hidl service的例子

将以下内容添加到 Android.mk 中:

 LOCAL_JAVA_LIBRARIES += android.hardware.led-V1.0-java/*LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.led-V1.0-java-static
*/

或将以下内容添加到 Android.bp 中:

  shared_libs: [/* … */"android.hardware.led-V1.0-java",],

该库还存在静态版:android.hardware.led-V1.0-java-static。

将以下内容添加到您的 Java 文件中:

  import android.hardware.led.V1_0.ILed;...// retry to wait until the service starts up if it is in the manifestILed server = ILed.getService(/* retry */); // throws NoSuchElementException if not availableserver.on();

5.2 实现C++ 调用hidl service的例子

首先将 HAL 库添加到 makefile 中:

  Make:LOCAL_SHARED_LIBRARIES += android.hardware.led@1.0Soong:shared_libs: [ …, android.hardware.led@1.0 ]

接下来,添加 HAL 头文件:

  #include <android/hardware/led/1.0/ILed.h>…// in code:sp<ILed> client = ILed::getService();client->on();

下面是我的Demo clinet

 #define LOG_TAG "LED_CLINET"
#include <android/hardware/led/1.0/ILed.h>
#include <log/log.h>using android::hardware::led::V1_0::ILed;
using android::hardware::led::V1_0::LedStatus;
using android::hardware::led::V1_0::BrightnessRange;
using android::hardware::hidl_vec;
using android::sp;int main(){// BrightnessRange range;sp<ILed> service = ILed::getService();if( service == nullptr ){ALOGE("Can't find ILed service...");return -1;}ALOGE("ILed ON");service->on();ALOGE("ILed OFF");service->off();ALOGE("ILed set");service->set(LedStatus::LED_ON);ALOGE("ILed get");LedStatus ret = service->get();ALOGE("ILed get: %d",ret);service->getBrightnessRange([](bool ret1,BrightnessRange range){ALOGE("ILed getBrightnessRange ret: %d",ret1);ALOGE("ILed getBrightnessRange Max: %d",range.max);ALOGE("ILed getBrightnessRange Min: %d",range.min);});int32_t array[] = {5, 6, 7};hidl_vec<int32_t> hv1 = std::vector<int32_t>(array, array + 3);bool ret2 = service->setBrightnessValue(hv1);ALOGE("ILed getBrightnessValue bool: %d",ret2);return 0;
}

6. github地址

需要看代码的可以去我的github,里面有相关的hidl代码,和C++调用示例

gitHub地址链接

在Android 8.0之后版本上添加Hidl Service相关推荐

  1. Android 7.0 开发者版本

    Android 7.0 Nougat 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能. 请务必查阅 Android 7.0 行为变更以了解平台变更可能影响您的应用的领域. 要详细了解 A ...

  2. Android 4.0.4-在build.prop中添加属性

    Android 4.0.4-在build.prop中添加属性 2013-10-07 16:40:56|  分类: 默认分类|举报|字号 订阅 1.在*.rc文件中用setprop添加,例如在源码and ...

  3. 解决Picasso在Android 5.0以下版本不兼容https导致图片不显示

    近期在项目中遇到了一个问题,使用picasso加载图片在Android5.0以下版本图片显示不来. 由于之前在几个项目中都使用过picasso而且未出现类似问题,觉得值得好好研究一下. 简单定位一下问 ...

  4. Android AppCompatCheckBox在低版本上不显示问题

    遇到一个问题,AppCompatCheckBox 在低版本显示不出来,但是在高版本可以显示出来.但是呢,应用的其他页面的AppCompatCheckBox 在同样的低版本手机上可以显示出来. 如下: ...

  5. 适用于android 4.0以上版本的子线程网络图片查看器

    android 4.0版本的新特性之一:加载网络内容时会自动判断是否在主线程中运行. 并且获取到内容时不能直接在子线程中设置主线程中的View,会报出以下异常 异常: CalledFromWrongT ...

  6. Windows下Nexus 5的Android 5.0以上版本官方ROM的刷机教程

    博客链接:http://blog.csdn.net/qq1084283172/article/details/52334452 折腾Android逆向的时候,经常需要给Nexus 5刷机.最近给Nex ...

  7. android 6.0 内核版本,ZUI 1.6版发布 内核居然是Android 6.0.1

    原标题:ZUI 1.6版发布 内核居然是Android 6.0.1 随着春季多款机型的发布,去年的手机界新兵ZUK也闲不住了.ZUK的第一款机型ZUI Z1自发布以来就以后辈的身份锐意进取,在国内手机 ...

  8. 氢os android 7.0,率先用上Android7.0,全新氢OS成国内最受好评系统

    原标题:率先用上Android7.0,全新氢OS成国内最受好评系统 近日,OnePlus 在官网发布了基于 Android 7.0 版本的氢OS.一经发布就获得了用户的一致好评.不少用户表示,能在第一 ...

  9. Android 9.0 (P版本) SystemServer中的服务配置se linux权限

    ## 1. SystemServer 的服务定义 Android P_9.0\frameworks\base\services\java\com\android\server\SystemServer ...

  10. Android 7.0修改PMS逻辑添加权限白名单

    今天有任务安排需要实现给任何一个应用在不动态申请权限的情况下,实现权限赋予,大体知道应用权限的赋予逻辑是在PMS中,于是大概研究了下,最终的手段就是在install安装时,就把应用程序AndroidM ...

最新文章

  1. ffmpeg java linux水印,Linux环境用FFmpeg给视频加水印详细步骤
  2. AI从入门到放弃2:CNN的导火索,用MLP做图像分类识别?
  3. 我来发美食啦,馋一下各位看官
  4. python私有方法应用场景_Python私有属性私有方法应用实例解析
  5. 数据结构与算法之判断一棵树是否为搜索二叉树、判断一棵树是否是完全二叉树
  6. php框架使用教程,php框架laravel excel包使用教程介绍
  7. Linux系统编程:验证kernel内核缓存区大小-4096字节
  8. datatable转list方法(有借鉴到他人)
  9. bzoj2038[2009国家集训队]小Z的袜子(hose)
  10. 速升级 Microsoft Word……且慢!
  11. Linux实战教学笔记29:MySQL数据库企业级应用实践
  12. unity 相机的问题
  13. 停课集训 11.27
  14. android时光轴相册,Android之RecyclerView实现时光轴效果示例
  15. Docker启动容器启动并映射端口号时报错:Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already
  16. docker配置代理pull报错:proxyconnect tcp: tls: first record does not look like a TLS handshake
  17. 如何计算给定二叉树中的叶节点数?
  18. 免疫学实验美图赏析馆(第三期)
  19. revit二次开发 材质相关
  20. 通用的商城系统后台管理ui框架模板

热门文章

  1. PHP问题Parse error: syntax error, unexpected end of file in
  2. centos 卸载 jdk
  3. gan网络损失函数_生成对抗网络的最新研究进展
  4. azkaban的最简版搭建
  5. 自定义音乐播放器的歌词显示view
  6. Android——selector背景选择器的使用详解(二)
  7. 如何学习angular.js
  8. 三层交换机SVI实现不同VLAN通信.
  9. 文本相似度计算--余弦定理和广义Jaccard系数
  10. 句柄的本质(整理-收藏) 选择自 feijj2002_ 的 Blog