系列文章
Android 12 S ServiceManager原理
Android 12 S Native Service的创建流程
Android 12 S Binder原理之BpBinder,BnBinder以及IInterface介绍
Android 12 S HIDL Service创建流程
Android 12 S 自定义Hal服务selinux权限添加
Android 12 S 自定义Native服务selinux权限添加
Android 12 S java服务调用native服务
Android 12 S 自定义native服务访问java服务
目录
如何新增HIDL服务
1.新增hidl服务文件夹
2. 新增.hal文件
3. 编译hidl-gen
4. 配置hidl的package root
5. 在1.0/default/下生成.cpp和.h文件
6. 在1.0/default/下面生成Android.bp
7. 在1.0下生成Android.bp
8. 在主目录android下执行如下命令生成current.txt
9. 在1.0/default/下添加vendor.qti.hardware.customizehidl-service.rc
10. 在1.0/default/下添加vendor.qti.hardware.customizehidl-service.xml
11. 在vendor/qcom/opensource/core-utils/vendor_framework_compatibility_matrix.xml中添加如下内容
12. 在1.0/default/下添加service.cpp
13. 编写测试bin程序
14. 测试
14.1 单编方法:
14.2 测试方法:
15. 如果测试通过则需要将hidl服务加入到系统中,然后进行整编测试
16. 可能碰到的问题
16.1 错误1
16.2 新增目录放hal服务
17. 自定义Hal 服务Selinux添加
HIDL 这个机制的目的,主要是为了把框架(framework)与 HAL 进行隔离,使得框架部分可以直接被覆盖、更新,而不需要重新对 HAL 进行编译。HAL 的部分将会放在设备的 /vendor 分区中,并且是由设备供应商(vendors)或 SOC 制造商来构建。这使得框架部分可以通过 OTA 方式更新,同时不需要重新编译 HAL。
这种设计被称为Treble机制,从Android 8.0引入。在此之前framework需要调用dlopen打开HAL编译的.so才能和HAL 层通信,这样framework 与 HAL 处在同一个进程 , 两者耦合严重,导致版本升级时供应商需要做大量的适配工作。
Treble机制解决目前Android 版本之间升级麻烦的问题,将OEM适配的部分vendor与google 对android 大框架升级的部分system部分做了分离,一旦适配了一个版本的vendor信息之后,之后的版本再进行升级时,直接升级system即可,这个就不会给OEM厂商升级带来太大的工作量,直接升级最新功能,可以解决目前市面上Android版本过于凌乱的问题。
Treble机制在Vendor分区中有两种模式,直通模式(Passthrough)和绑定模式(Binderized),大致框架图如下,对于Android O之前的设备,对应图1,对于从之前的设备升级到O的版本,对应图2、图3. 对于直接基于Android O开发的设备,对应图4。
一般新增HIDL Service都是在vendor目录下新增,最好在自己的产品名下新增文件夹,创建相应的HIDL服务,假设目前要在qcom下新增HIDL服务,流程如下:
如何新增HIDL服务
1.新增hidl服务文件夹
在vendor/qcom/opensource/interfaces下新增文件夹,这里新增customizehidl文件夹
在customizehidl下新建1.0文件夹
在1.0下新增default文件夹
2. 新增.hal文件
在customizehidl/1.0下新增ICustomizeHidl.hal以及types.hal文件
vendor/qcom/opensource/interfaces/1.0/ICustomizehidl.hal
package vendor.qti.hardware.customizehidl@1.0;
interface ICustomizeHidl{
resetOption(int32_t side) generates (Result result);
};
vendor/qcom/opensource/interfaces/1.0/types.hal
package vendor.qti.hardware.customizehidl@1.0;
enum Result : int32_t {
OK = 0,
ERR,
OUT_OF_RANGE,
};
3. 编译hidl-gen
source build/envsetup.sh
lunch xx
make hidl-gen
这样后面就可以用hidl-gen工具了,
4. 配置hidl的package root
PACKAGE=vendor.qti.hardware.customizehidl@1.0
LOC=vendor/qcom/opensource/interfaces/customizehidl/1.0/default/
如果有如下报错的话
ERROR: Package root not specified for vendor.qti.hardware.customizehidl@1.0
ERROR: Could not get sources for vendor.qti.hardware.customizehidl@1.0.
需要在以下目录下添加如下代码:
vendor/qcom/opensource/interfaces/Android.bp
hidl_package_root {
name:"vendor.qti.hardware.customizehidl",
path:"vendor/qcom/opensource/interfaces/customizehidl",
}
5. 在1.0/default/下生成.cpp和.h文件
在vendor/qcom/opensource/interfaces/customizehidl/1.0/default/下生成.cpp和.h文件:
hidl-gen -o $LOC -Lc++-impl -rvendor.qti.hardware:vendor/qcom/opensource/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
或者
hidl-gen -o vendor/qcom/opensource/interfaces/customizehidl/1.0/default -Lc++-impl -rvendor.qti.hardware:vendor/qcom/opensource/interfaces –randroid.hidl:system/libhidl/transport vendor.qti.hardware.customizehidl@1.0
然后会生成CustomizeHidl.cpp和CustomizeHidl.h文件。生成后需要做相关修改,修改后内容如下:
vendor/qcom/opensource/interfaces/customizehidl/1.0/default/CustomizeHidl.cpp
#include "CustomizeHidl.h"
#include <pthread.h>
#include <sched.h>
#include <map>
#include <fcntl.h>
#include <unistd.h>
namespace vendor {
namespace qti {
namespace hardware {
namespace customizehidl {
namespace V1_0 {
namespace implementation {
//也可以用vendor::qti::hardware::customizehidl::V1_0::implementation替代
CustomizeHidl::CustomizeHidl() {
}
CustomizeHidl::~CustomizeHidl() {
}
Return<::vendor::qti::hardware::customizehidl::V1_0::Result> CustomizeHidl::resetOption(int32_t side) {
return ::vendor::qti::hardware::customizehidl::V1_0::Result {};
}
// Methods from ::android::hidl::base::V1_0::IBase follow.
//ICustomizeHidl* HIDL_FETCH_ICustomizeHidl(const char* /* name */) {
// return new CustomizeHidl();
//}
//
} // implementation
} // V1_0
} // customizehidl
} // hardware
} // qti
} // vendor
头文件内容如下:
vendor/qcom/opensource/interfaces/customizehidl/1.0/default/CustomizeHidl.h
#include <vendor/qti/hardware/customizehidl/1.0/ICustomizeHidl.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <fstream>
#include <iostream>
namespace vendor {
namespace qti {
namespace hardware {
namespace customizehidl {
namespace V1_0 {
namespace implementation {
using namespace std;
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 CustomizeHidl : public ICustomizeHidl {
CustomizeHidl();
~CustomizeHidl();
Return<::vendor::qti::hardware::customizehidl::V1_0::Result> resetOption(int32_t side) override;
};
// FIXME: most likely delete, this is only for passthrough implementations
// extern "C" ICustomizeHidl* HIDL_FETCH_ICustomizeHidl(const char* name);
} // implementation
} //customizehidl
} // V1_0
} // hardware
} // qti
} // vendor
6. 在1.0/default/下面生成Android.bp
在vendor/qcom/opensource/interfaces/customizehidl/1.0/default/下面生成Android.bp:
hidl-gen -o $LOC -Landroidbp-impl -rvendor.qti.hardware:vendor/qcom/opensource/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
生成后需要做相关修改,修改后内容如下:
cc_binary {//cc_library_shared修改为cc_binary
// 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.monet.hardware.historicaldata@1.0-impl",
relative_install_path: "hw",
// FIXME: this should be 'vendor: true' for modules that will eventually be
// on AOSP.
proprietary: true,
//新增
compile_multilib: "both",
relative_install_path: "hw",
init_rc: ["vendor.qti.hardware.customizehidl.rc"],
vintf_fragments: ["vendor.qti.hardware.customizehidl.xml"],
srcs: [
"service.cpp",
"CustomizeHidl.cpp",
],
shared_libs: [
"libhidlbase",
"libutils",
"liblog",
"libbase",
"libhidltransport",
"vendor.qti.hardware.customizehidl@1.0",
],
}
或者修改为如下,将不同的so放入不同的地方,我是修改为如下:
cc_defaults{
name: "customizehidl_defaults",
//relative_install_path: "hw",
defaults: ["hidl_defaults"],
//根据项目需求
//vendor: true,
proprietary: true,
cflags: [
"-Wno-unused-parameter",
"-Wall",
],
shared_libs: [
"libcutils",
"liblog",
"libbase",
"libsysutils",
"libhidlbase",
"libhidltransport",
"libutils",
"vendor.qti.hardware.customizehidl@1.0",
],
}
cc_library_shared {
name: "vendor.qti.hardware.customizehidl@1.0-impl",
relative_install_path: "hw",
//根据项目需求
//vendor: true,
proprietary: true,
cflags: [
"-Wno-unused-parameter",
"-Wall",
"-Wunused-variable",
"-Wunused-const-variable",
"-Wunused-variable",
],
srcs: [
"CustomizeHidl.cpp",
],
defaults: ["customizehidl_defaults"],
}
cc_binary {
name: "vendor.qti.hardware.customizehidl@1.0-service",
proprietary: true,
compile_multilib: "both",
relative_install_path: "hw",
defaults: ["customizehidl_defaults"],
//rc引用
init_rc: ["vendor.qti.hardware.customizehidl-service.rc"],
//vintf_fragments引用
vintf_fragments: ["vendor.qti.hardware.customizehidl-service.xml"],
srcs: [
"service.cpp",
],
shared_libs: [
"libcutils",
"liblog",
"libbase",
"libsysutils",
"libhidlbase",
"libhidltransport",
"libutils",
"vendor.qti.hardware.customizehidl@1.0-impl",
],
}
7. 在1.0下生成Android.bp
在vendor/qcom/opensource/interfaces/customizehidl/1.0下生成Android.bp
source system/tools/hidl/update-makefiles-helper.sh
do_makefiles_update vendor.qti.hardware:vendor/qcom/opensource/interfaces android.hardware:hardware/interfaces android.hidl:system/libhidl/transport
生成后需要做相关修改,修改后内容如下:
hidl_interface {
name: "vendor.qti.hardware.customizehidl@1.0",
root: "vendor.qti.hardware.customizehidl",
//根据需求进行设置
//product_specific: true,
system_ext_specific: true,
srcs: [
"types.hal",
"ICustomizeHidl.hal",
],
interfaces: [
"android.hidl.base@1.0",
],
gen_java: true,
}
8. 在主目录android下执行如下命令生成current.txt
hidl-gen -Lhash -rvendor.qti.hardware:vendor/qcom/opensource/interfaces -randroid.hidl:system/libhidl/transport vendor.qti.hardware.customizehidl@1.0 > vendor/qcom/opensource/interfaces/customizehidl/current.txt
9. 在1.0/default/下添加vendor.qti.hardware.customizehidl-service.rc
添加如下内容
service vendor.qti.hardware.customizehidl-1-0 /vendor/bin/hw/vendor.qti.hardware.customizehidl@1.0-service
class hal
user system
group system
10. 在1.0/default/下添加vendor.qti.hardware.customizehidl-service.xml
<manifest version="1.0" type="device">
<hal format="hidl">
<name>vendor.qti.hardware.customizehidl</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>ICustomizeHidl</name>
<instance>default</instance>
</interface>
</hal>
</manifest>
11. 在vendor/qcom/opensource/core-utils/vendor_framework_compatibility_matrix.xml中添加如下内容
<hal format="hidl" optional="true">
<name>vendor.qti.hardware.customizehidl</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>ICustomizeHidl</name>
<instance>default</instance>
</interface>
</hal>
12. 在1.0/default/下添加service.cpp
如果采用Binderized方式,如下
#include <android-base/logging.h>
#include <hidl/HidlTransportSupport.h>
#include "CustomizeHidl.h"
#include <utils/Log.h>
#include <hidl/LegacySupport.h>
using namespace android;
using vendor::qti::hardware::customizehidl::V1_0::ICustomizeHidl;
using vendor::qti::hardware::customizehidl::V1_0::implementation::CustomizeHidl;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;
int main(int /* argc */, char ** /* argv */) {
sp<ICustomizeHidl> service = new CustomizeHidl();
configureRpcThreadpool(1, true /*callerWillJoin*/);
if (::android::OK != service->registerAsService()) {
return -1;
}
joinRpcThreadpool();
return 0;
}
如果要采用Passthrough方式的话,则需要按如下方法写main,但同时需要将CustomizeHidl.cpp以及CustomizeHidl.h中的HIDL_FETCH_ICustomizeHidl方法放开才可以。
#include <android-base/logging.h>
#include <hidl/HidlTransportSupport.h>
#include "CustomizeHidl.h"
#include <utils/Log.h>
#include <hidl/LegacySupport.h>
using namespace android;
using vendor::qti::hardware::customizehidl::V1_0::ICustomizeHidl;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::defaultPassthroughServiceImplementation;
using android::hardware::registerPassthroughServiceImplementation;
int main() {
android::status_t status;
configureRpcThreadpool(10, false);
status = registerPassthroughServiceImplementation<ICustomizeHidl>();
LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering ICustomizeHidl: %d", status);
joinRpcThreadpool();
return status;
}
13. 编写测试bin程序
vendor/qcom/opensource/interfaces/customizehidl/下新增hidl_test_bin目录,并添加Android.bp
cc_binary {
name: "hidl_test_bin",
srcs: [
"hidl_test_bin.cpp",
],
shared_libs: [
"libcutils",
"libutils",
"liblog",
//以下so一定要添加,否则可能会有报错
"libbinder",
"libhidlbase",
"libbase",
"libhidltransport",
"vendor.qti.hardware.customizehidl@1.0",
],
cflags: [
"-Werror",
"-Wno-error=deprecated-declarations",
"-Wno-unused-parameter",
"-Wall",
],
}
添加hidl_test_bin.cpp文件
#define LOG_TAG "hidl_test_bin"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <cutils/properties.h>
#include <fcntl.h>
#include <utils/Log.h>
#include <iostream>
#include <vendor/qti/hardware/customizehidl/1.0/ICustomizeHidl.h>
#include <vendor/qti/hardware/customizehidl/1.0/types.h>
using namespace android;
using namespace std;
using vendor::qti::hardware::customizehidl::V1_0::ICustomizeHidl;
using vendor::qti::hardware::customizehidl::V1_0::Result;
using android::hardware::Return;
using android::hardware::details::return_status;
using android::hardware::Void;
sp<ICustomizeHidl> halService;
int main(int argc, char* argv[]) {
halService = ICustomizeHidl::getService();
if (halService == NULL){
cout << "get hal service failed" <<endl;
return -1;
}
cout << "get hal service scuess" <<endl;
float value = stof(argv[1]);
cout << "value is " << value <<endl;
halService->resetOption(value);
return 0;
}
14. 测试
14.1 单编方法:
source build/envsetup.sh
lunch xxx
cd vendor/qcom/opensource/interfaces/customizehidl
mma(编译hidl服务相关)
cd vendor/qcom/opensource/interfaces/customizehidl/hidl_test_bin
mma(编译test bin相关)
14.2 测试方法:
1. adb pull vendor/etc/vintf/compatibility_matrix.xml
在最后增加,这个对应的是11步,因为我们是单编,所以是无法将11步单编进入的,故手动添加
<hal format="hidl" optional="true">
<name>vendor.qti.hardware.customizehidl</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>ICustomizeHidl</name>
<instance>default</instance>
</interface>
</hal>
2. 再push回去
adb root
adb remount
adb push compatibility_matrix.xml vendor/etc/vintf/compatibility_matrix.xml
3. 在out/target/product/qssi下执行
adb push ./product/lib/vendor.qti.hardware.customizehidl@1.0.so product/lib/
adb push ./product/lib64/vendor.qti.hardware.customizehidl@1.0.so product/lib64/
adb push ./vendor/lib/hw/vendor.qti.hardware.customizehidl@1.0-impl.so vendor/lib/hw/
adb push ./vendor/lib/vendor.qti.hardware.customizehidl@1.0.so vendor/lib/
adb push ./vendor/lib64/hw/vendor.qti.hardware.customizehidl@1.0-impl.so vendor/lib64/hw/
adb push ./vendor/lib64/vendor.qti.hardware.customizehidl@1.0.so vendor/lib64/
adb push ./vendor/etc/vintf/manifest/vendor.qti.hardware.customizehidl-service.xml vendor/etc/vintf/manifest
adb push ./vendor/bin/hw/vendor.qti.hardware.customizehidl@1.0-service vendor/bin/hw/
adb push ./system_ext/lib/vendor.qti.hardware.customizehidl@1.0.so system_ext/lib/
adb push ./system_ext/lib64/vendor.qti.hardware.customizehidl@1.0.so system_ext/lib64/
adb push system/bin/hidl_test_bin system/bin(测试的bin程序)
然后执行
adb reboot
重启后
关闭selinux: adb shell setenforce 0
窗口1:起hidl服务
adb shell
cd vendor/bin/hw
./vendor.qti.hardware.customizehidl@1.0-service
窗口2:起test bin程序
adb shell
hidl_test_bin 100
然后观察窗口2输出什么
如果输出如下则代表两者通信成功
get hal service scuess
value is 100
15. 如果测试通过则需要将hidl服务加入到系统中,然后进行整编测试
在device/qcom/qssi/qssi.mk中添加如下内容
PRODUCT_PACKAGES += \
vendor.qti.hardware.customizehidl@1.0 \
vendor.qti.hardware.customizehidl@1.0-service \
vendor.qti.hardware.customizehidl@1.0-impl
然后本地在代码主目录下进行source,lunch,make整编。
16. 可能碰到的问题
16.1 错误1
04-14 12:27:02.103 599 599 I hwservicemanager: getTransport: Cannot find entry vendor.qti.hardware.customizehidl@1.0::ICustomizeHidl/default in either framework or device VINTF manifest.
04-14 12:27:02.104 4169 4169 E HidlServiceManagement: Service vendor.qti.hardware.customizehidl@1.0::ICustomizeHidl/default must be in VINTF manifest in order to register/get
那就是vintf manifest相关的配置出现问题,可以检查下是否有push相应的manifest文件,接口的内容是否书写正确等。
16.2 新增目录放hal服务
如遇到新建的目录编译不出来相关hidl的out下相关文件,需要添加update-makefiles.sh文件,可以从其他hidl的目录中拷贝过来,修改其中的目录即可
set -e
if [ -z "$ANDROID_BUILD_TOP" ]; then
echo "Missing ANDROID_BUILD_TOP env variable. Run 'lunch' first."
exit 1
fisource $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh
do_makefiles_update \
"vendor/newname/interfaces/customizehidl"
17. 自定义Hal 服务Selinux添加
请参考我的另一篇文章文章来源:https://www.toymoban.com/news/detail-678671.html
自定义Hal服务selinux权限添加_加油干(◍>∇<◍)ノ゙的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-678671.html
到了这里,关于HIDL Service创建流程 - 基于Android 12 S分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!