Table of contents
4. Configure the package root of hidl
5. Generate .cpp and .h files under 1.0/default/
6. Generate Android.bp under 1.0/default/
7. Generate Android.bp under 1.0
8. Execute the following command in the main directory android to generate current.txt
9. Add vendor.qti.hardware.customizehidl-service.rc under 1.0/default/
10. Add vendor.qti.hardware.customizehidl-service.xml under 1.0/default/
11. Add the following content in device/qcom/common/vendor_compatibility_matrix.xml
12. Add service.cpp under 1.0/default/
14.1 Single compilation method:
15.2 Add a new directory to put hal service
16. Add custom Hal service Selinux
The purpose of the HIDL mechanism is mainly to isolate the framework (framework) from the HAL, so that the framework part can be directly overwritten and updated without recompiling the HAL. Parts of the HAL will be placed in the /vendor partition of the device and built by the device vendors (vendors) or the SOC manufacturer. This allows framework parts to be updated OTA without recompiling the HAL.
This design is called the Treble mechanism, introduced from Android 8.0. Before this, the framework needs to call dlopen to open the .so compiled by HAL in order to communicate with the HAL layer. In this way, the framework and HAL are in the same process, and the coupling between the two is serious, which causes the supplier to do a lot of adaptation work when the version is upgraded.
The Treble mechanism solves the problem of troublesome upgrades between Android versions. It separates the part of the vendor adapted by OEM from the part of the system part that google upgrades to the android framework. Once the vendor information of a version is adapted, subsequent versions can When upgrading, you can directly upgrade the system, which will not bring too much workload to the OEM manufacturer to upgrade, and directly upgrade the latest functions, which can solve the problem that the current Android version on the market is too messy.
The Treble mechanism has two modes in the Vendor partition, passthrough mode (Passthrough) and binding mode (Binderized). The general framework diagram is as follows. For devices before Android O, it corresponds to Figure 1. For the version upgraded from the previous device to O , corresponding to Figure 2 and Figure 3. For devices developed directly based on Android O, it corresponds to Figure 4.
Generally, new HIDL services are added under the vendor directory. It is best to add folders under your own product name and create corresponding HIDL services. Assuming that you want to add HIDL services under qcom, the process is as follows:
How to add HIDL service
1. Add hidl service folder
Add a new folder under vendor/qcom/opensource/interfaces, add a customizehidl folder here
Create a new 1.0 folder under customizehidl
Add a default folder under 1.0
2. Add .hal file
Add ICustomizehidl.hal and types.hal files under customizehidl
vendor/qcom/opensource/interfaces/ICustomizehidl.hal
package [email protected];
interface ICustomizeHidl{
resetOption(int32_t side) generates (Result result);
};
vendor/qcom/opensource/interfaces/types.hal
package [email protected];
enum Result : int32_t {
OK = 0,
ERR,
OUT_OF_RANGE,
};
3. Compile hidl-gen
source build/envsetup.sh
lunch xx
make filter-gen
In this way, the hidl-gen tool can be used later ,
4. Configure the package root of hidl
PACKAGE=vendor.qti.hardware.customizehidl@1.0
LOC=vendor/qcom/opensource/interfaces/customizehidl/1.0/default/
If there is an error as follows
ERROR: Package root not specified for [email protected]
ERROR: Could not get sources for [email protected].
You need to add the following code in the following directory:
vendor/qcom/opensource/interfaces/Android.bp
hidl_package_root {
name:"vendor.qti.hardware.customizehidl",
path:"vendor/qcom/opensource/interfaces/customizehidl",
}
5. Generate .cpp and .h files under 1.0/default/
Generate .cpp and .h files under vendor/qcom/opensource/interfaces/ customizehidl /1.0/default/:
hidl-gen -o $LOC -Lc++-impl -rvendor.qti.hardware:vendor/qcom/opensource/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
or
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
Then the CustomizeHidl.cpp and CustomizeHidl.h files are generated. Relevant modifications need to be made after generation. The modified content is as follows:
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 {
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
The contents of the header file are as follows:
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. Generate Android.bp under 1.0/default/
Generate Android.bp under vendor/qcom/opensource/interfaces/ customizehidl /1.0/default/:
hidl-gen -o $LOC -Landroidbp-impl -rvendor.qti.hardware:vendor/qcom/opensource/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
Relevant modifications need to be made after generation. The modified content is as follows:
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",
"[email protected]",
],
}
cc_library_shared {
name: "[email protected]",
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: "[email protected]",
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",
"[email protected]",
],
}
7. Generate Android.bp under 1.0
Generate Android.bp under vendor/qcom/opensource/interfaces/ customizehidl /1.0
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
Relevant modifications need to be made after generation. The modified content is as follows:
hidl_interface {
name: "[email protected]",
root: "vendor.qti.hardware.customizehidl",
//根据需求进行设置
//product_specific: true,
system_ext_specific: true,
srcs: [
"types.hal",
"ICustomizeHidl.hal",
],
interfaces: [
"[email protected]",
],
gen_java: true,
}
8. Execute the following command in the main directory android to generate 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. Add vendor.qti.hardware.customizehidl -service.rc under 1.0/default/
Add the following content
service vendor.qti.hardware.customizehidl-1-0 /vendor/bin/hw/[email protected]
class hal
user system
group system
10. Add vendor.qti.hardware.customizehidl-service.xml under 1.0/default/
<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. Add the following content in device/qcom/common/vendor_compatibility_matrix.xml (I didn’t add it here, it can still run)
<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. Add service.cpp under 1.0/default/
If the Binderized method is used, as follows
#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;
}
If you want to use the Passthrough method, you need to write main as follows, but at the same time you need to release the HIDL_FETCH_ICustomizeHidl method in CustomizeHidl.cpp and CustomizeHidl.h.
#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. Write a test bin program
Add a hidl_test_bin directory under vendor/qcom/opensource/interfaces/ customizehidl /, and add Android.bp
cc_binary {
name: "hidl_test_bin",
srcs: [
"hidl_test_bin.cpp",
],
shared_libs: [
"libcutils",
"libutils",
"liblog",
//以下so一定要添加,否则可能会有报错
"libbinder",
"libhidlbase",
"libbase",
"libhidltransport",
"[email protected]",
],
cflags: [
"-Werror",
"-Wno-error=deprecated-declarations",
"-Wno-unused-parameter",
"-Wall",
],
}
Add hidl_test_bin.cpp file
#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. Test
14.1 Single compilation method:
source build/envsetup.sh
lunch xxx
cd vendor/qcom/opensource/interfaces/customizehidl
mma (compiling hidl service related)
cd vendor/qcom/opensource/interfaces/customizehidl/hidl_test_bin
mma (compiled test bin related)
14.2 Test method:
1. adb pull vendor/etc/vintf/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>
2. Push back again
adb root
adb remount
adb push compatibility_matrix.xml vendor/etc/vintf/compatibility_matrix.xml
3. Execute under out/target/product/qssi
adb push ./product/lib/[email protected] product/lib/
adb push ./product/lib64/[email protected] product/lib64/
adb push ./vendor/lib/hw/[email protected] vendor/lib/hw/
adb push ./vendor/lib/[email protected] vendor/lib/
adb push ./vendor/lib64/hw/[email protected] vendor/lib64/hw/
adb push ./vendor/lib64/[email protected] vendor/lib64/
adb push ./vendor/etc/vintf/manifest/vendor.qti.hardware.customizehidl-service.xml vendor/etc/vintf/manifest
adb push ./vendor/bin/hw/[email protected] vendor/bin/hw/
adb push ./system_ext/lib/[email protected] system_ext/lib/
adb push ./system_ext/lib64/[email protected] system_ext/lib64/
adb push system/ bin/hidl_test_bin system/bin (tested bin program)
and then execute
adb reboot
to restart and
close selinux: adb shell setenforce 0
window 1: start hidl service
adb shell
cd vendor/bin/hw
./[email protected] -service
Window 2: Start the test bin program
adb shell
hidl_test_bin 100
Then observe what is output in window 2.
If the output is as follows, it means the communication between the two is successful.
get hal service scuess
value is 100
15. Possible problems
15.1 Error 1
04-14 12:27:02.103 599 599 I hwservicemanager: getTransport: Cannot find entry [email protected]::ICustomizeHidl/default in either framework or device VINTF manifest.
04-14 12:27:02.104 4169 4169 E HidlServiceManagement: Service [email protected]::ICustomizeHidl/default must be in VINTF manifest in order to register/get
That is, there is a problem with the configuration related to the vintf manifest. You can check whether there is a push corresponding manifest file, whether the content of the interface is written correctly, etc.
15.2 Add a new directory to put hal service
If the newly created directory cannot compile the relevant hidl out related files, you need to add the update-makefiles.sh file, which can be copied from other hidl directories and modify the directory.
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"
16. Add custom Hal service Selinux
Please refer to my other article
Add custom Hal service selinux permissions_Come on (◍>∇<◍)ノ゙'s Blog