在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
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
-
-
#include
-
-
#include
-
-
-
-
-
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
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
-
#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
ledImpl::get() {
-
return state;
-
}
-
Return<
int32_t> ledImpl::
set(LedStatus val) {
-
if(val == LedStatus::LED_OFF || val == LedStatus::LED_ON)
-
state = val;
-
else
-
return
-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:
"[email protected]",
-
defaults: [
"hidl_defaults"],
-
srcs: [
"ledImpl.cpp"],
-
shared_libs: [
-
"libhidlbase",
-
"libhidltransport",
-
"libhardware",
-
"liblog",
-
"libutils",
-
-
],
-
}
-
-
cc_binary {
-
name:
"[email protected]",
-
init_rc: [
"[email protected]"],
-
srcs: [
"service.cpp",
-
"ledImpl.cpp"],
-
-
shared_libs: [
-
"liblog",
-
"libhardware",
-
"libhidlbase",
-
"libhidltransport",
-
"libutils",
-
-
],
-
-
}
3. 编写hdil service
接下来,使用相应功能填写存根并设置守护进程。可以使用passthrough方式和binder方式,示例:
hardware/interfaces/led/1.0/default/service.cpp
-
-
#define LOG_TAG "[email protected]"
-
-
#include
-
#include
-
#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
();
-
#else
-
// Binder 方式
-
sp
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/
-
<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 manifest
-
ILed server =
ILed.getService(
/* retry */);
// throws NoSuchElementException if not available
-
server.on();
5.2 实现C++ 调用hidl service的例子
首先将 HAL 库添加到 makefile 中:
-
Make:LOCAL_SHARED_LIBRARIES += android.hardware.led@1.
0
-
Soong:shared_libs: [ …, android.hardware.led@1.
0 ]
接下来,添加 HAL 头文件:
-
#include
-
…
-
// in code:
-
sp
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;
-
}
需要看代码的可以去我的github,里面有相关的hidl代码,和C++调用示例
gitHub地址链接