HIDL接口定义
创建hidl目录
在aosp中的hardware/interfaces目录下创建自己的hal目录
mkdir -p hardware/interfaces/qmiller/1.0/default
创建hal文件
在我们刚才创建的hardware/interfaces/qmiller/1.0/目录下新建IQmiller.hal文件,传入string name,返回string类型的result。
package android.hardware.qmiller@1.0;
interface IQmiller {
helloWorld(string name) generates (string result);
};
生产HAL文件
使用hidl-gen工具来处理IQmiller.hal文件,这里可以写成一个shell脚本。
PACKAGE=android.hardware.qmiller@1.0
LOC=hardware/interfaces/qmiller/1.0/default/
make hidl-gen -j4 //工具已经安装
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
参数说明:
-L: 语言类型,包括c++, c++-headers, c++-sources, export-header, c++-impl,
java, java-constants, vts, makefile, androidbp, androidbp-impl, hash等。
hidl-gen可根据传入的语言类型产生不同的文件。
fqname: 完全限定名称的输入文件。比如本例中android.hardware.gunder@1.0,
要求在源码目录下必须有hardware/interfaces/ gunder /1.0/目录。
对于单个文件来说,格式如下:package@version::fileName,
比如android.hardware. gunder @1.0::types.Feature。
对于目录来说。格式如下package@version,
比如android.hardware. gunder @1.0。
-r: 格式package:path,可选,
对fqname对应的文件来说,用来指定包名和文件所在的目录到Android系统源码根目录的路径。
如果没有制定,前缀默认是:android.hardware,目录是Android源码的根目录。
-o:存放hidl-gen产生的中间文件的路径。
此时的文件树:
hardware/interfaces/qmiller/1.0/
├── default
│ ├── Android.bp
│ ├── Qmiller.cpp
│ └── Qmiller.h
└── IQmiller.hal
然后使用脚本来更新Makefile,自动生成Android,mk, Android.bp
./hardware/interfaces/update-makefiles.sh
此时的文件树:
hardware/interfaces/qmiller/1.0/
├── Android.bp
├── default
│ ├── Android.bp
│ ├── Qmiller.cpp
│ └── Qmiller.h
└── IQmiller.hal
新建两个空文件:
touch hardware/interfaces/qmiller/1.0/default/android.hardware.qmiller@1.0-service.rc
touch hardware/interfaces/qmiller/1.0/default/service.cpp
实现HAL的implementation库
自动生成的Qmiller.h文件,这里介绍的是绑定式HAL,而不是直通式。
#pragma once
#include <android/hardware/qmiller/1.0/IQmiller.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android::hardware::qmiller::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 Qmiller : public V1_0::IQmiller {
// Methods from ::android::hardware::qmiller::V1_0::IQmiller 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" IQmiller* HIDL_FETCH_IQmiller(const char* name);
} // namespace android::hardware::qmiller::implementation
自动生成的Qmiller.cpp
#include "Qmiller.h"
namespace android::hardware::qmiller::implementation {
// Methods from ::android::hardware::qmiller::V1_0::IQmiller follow.
Return<void> Qmiller::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {
// TODO implement
return Void();
}
// Methods from ::android::hidl::base::V1_0::IBase follow.
//IQmiller* HIDL_FETCH_IQmiller(const char* /* name */) {
//return new Qmiller();
//}
//
} // namespace android::hardware::qmiller::implementation
修改Android.bp文件,将-impl改成-service,将cc_library_shared改成cc_library,在-service后面加上vendor名称。
cc_library {
name: "android.hardware.qmiller@1.0-service-lzm",
relative_install_path: "hw",
vendor:true,
// FIXME: this should be 'vendor: true' for modules that will eventually be
// on AOSP.
proprietary: true,
srcs: [
"Qmiller.cpp",
],
shared_libs: [
"libhidlbase",
"libutils",
"android.hardware.qmiller@1.0",
],
}
实现service.cpp
#define LOG_TAG "android.hardware.qmiller@1.0-service-lzm"
#include <hidl/HidlLazyUtils.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include "Qmiller.h"
using ::android::OK;
using ::android::sp;
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::joinRpcThreadpool;
using ::android::hardware::LazyServiceRegistrar;
using ::android::hardware::qmiller::V1_0::IQmiller;
using ::android::hardware::qmiller::V1_0::implementation::Qmiller;
int main(int argc, char* []) {
sp<IQmiller> qmiller = new Qmiller;
configureRpcThreadpool(1, true);
auto registrar = LazyServiceRegistrar::getInstance();
if (registrar.registerService(qmiller) != OK) {
ALOGE("Could not register service.");
return 1;
}
joinRpcThreadpool();
ALOGE("Service exited!");
return 1;
}
实现Qmiller.cpp文件
#include "Qmiller.h"
namespace android::hardware::qmiller::implementation {
Return<void> Qmiller::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {
char buf[100];
::memset(buf, 0x00, 100);
::snprintf(buf, 100, "Hello World, %s", name.c_str());
hidl_string result(buf);
_hidl_cb(result);
return Void();
}
} // namespace android::hardware::qmiller::implementation
编译hal
mmm hardware/interfaces/qmiller/1.0/default/
最终会生成一个android.hardware.qmiller@1.0-service-lzm.so, 生成在/vendor/lib64/hw/下。