brief description
When you use different hardware devices (such as cameras, sensors, audio devices, etc.) in the Android system, you need to HAL
communicate with the hardware abstraction layer ( ). HAL
is an intermediate layer that acts as a bridge between hardware and applications. However, due to different hardware devices, the HAL interface will also vary between different hardware. This is where Android HAL
Interface Definition Language ( HIDL
) comes in.
HIDL
Allows developers to define their own interfaces for each hardware device. These interfaces define the functions and characteristics of the hardware device, including input parameters, return values, and exceptions. Using these interfaces, applications can communicate directly with hardware devices without knowing specific hardware details. In Android
, HIDL
is widely used to HAL
communicate with .
It Android Project Treble
was proposed in , and android O
was pushed comprehensively in . The purpose of designing HIDL
this mechanism is to isolate the framework ( )framework
from , so that the framework part can be directly overwritten and updated without recompiling .HAL
HAL
HIDL
It is actually used for inter-process communication ( Inter-process Communication,IPC
). Inter-process communication can be called Binder
call ( Binderized
). For libraries that must be linked into a process, passthough
mode (but not supported in Java).
Write code
Aosp
Create a directory in the code directory ( hardware/interfaces/stksensor/1.0
for 1.0
version-related, you can check the version management concept on the official website ),
1. Create a new fileIStksensor.hal
package android,[email protected];
improt IStksensorCallBack;
interface IStksensor {
setCallBack(IStksensorCallBack callback);
write(string data) generates (bool res);
init() generates (MyResult result);
};
2. Create UDT
(user-defined type),types.hal
package [email protected];
enum ResultCode : int32_t {
UNKNOWN = -1,
ERROR = 0,
OK = 1,
};
struct MyResult{
ResultCode resultCode;
string msg;
};
3. Create a new file callback fileIStksensorCallBack.hal
package [email protected];
interface IStksensorCallBack {
passData(uint32_t data) generates (MyResult result);
};
Use hidl-gen to generate related files
Execute the following command in the terminal to set the temporary variable
PACKAGE=[email protected]
LOC=hardware/interfaces/stksensor/1.0/default
AOSP
Execute the files in the hidl-gen
generated default
directory in the root directory of the source codec++
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
AOSP
Execute the files in the hidl-gen
generated default
directory in the root directory of the source codeAndroid.bp
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
Executing in AOSP
the root directory of the source code ./hardware/interfaces/update-makefiles.sh
will generate the files hardware/interfaces/stksensor/1.0/
in the directoryAndroid.bp
Implement the interface code
Modification hardware/interfaces/stksensor/1.0/default/Stksensor.cpp
, the implementation here is simply to print the log
// FIXME: your file license if you have one
#include "Stksensor.h"
#include <log/log.h>
namespace android::hardware::stksensor::implementation {
// Methods from ::android::hardware::stksensor::V1_0::IStksensor follow.
Return<void> Stksensor::setCallBack(const sp<::android::hardware::stksensor::V1_0::IStksensorCallBack>& callback) {
// TODO implement
ALOGE("stksensor service have called the funtion of setCallBack");
return Void();
}
Return<::android::hardware::stksensor::V1_0::ResultCode> Stksensor::write(const hidl_string& data) {
// TODO implement
ALOGE("stksensor service have called the funtion of write");
return ::android::hardware::stksensor::V1_0::ResultCode {};
}
Return<void> Stksensor::init(init_cb _hidl_cb) {
// TODO implement
ALOGE("stksensor service have called the funtion of init");
return Void();
}
// Methods from ::android::hidl::base::V1_0::IBase follow.
//IStksensor* HIDL_FETCH_IStksensor(const char* /* name */) {
//return new Stksensor();
//}
//
} // namespace android::hardware::stksensor::implementation
Add startup service
1. When hardware/interfaces/stksensor/1.0/default/
creatingservice.cpp
#define LOG_TAG "[email protected]"
#include <hidl/HidlTransportSupport.h>
#include <log/log.h>
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardwara::stksensor::V1_0::IStksensor;
using android::hardware::stksensor::V1_0::implementation::Stksensor;
using namespace android;
int main() {
configureRpcThreadpool(1, true);
sp<IStksensor> service = new Stksensor();
status_t status = service->registerAsService("stksensor");
if (status != OK) {
ALOGE("Error registering stksensor as service: %d", status);
return status;
}
ALOGE("Ok to registering stksensor as service");
joinRpcThreadpool();
return 1;
}
2. hardware/interfaces/stksensor/1.0/default/
Create [email protected]
a startup script
service stksensor-hal-1-0 /vendor/bin/hw/[email protected]
class hal
user system
group system
3. In the hardware/interfaces/stksensor/1.0/default/
created[email protected]
vintf
<manifest version="1.0" type="device">
<hal format="hidl">
<name>android.hardware.stksensor</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>IStksensor</name>
<instance>stksensor</instance>
</interface>
</hal>
</manifest>
Modify the compilation script
1. Modify againhardware/interfaces/stksensor/1.0/default/Android.bp
// FIXME: your file license if you have one
cc_library_shared {
// 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: "[email protected]",
relative_install_path: "hw",
// FIXME: this should be 'vendor: true' for modules that will eventually be
// on AOSP.
proprietary: true,
srcs: [
"Stksensor.cpp",
"StksensorCallBack.cpp",
],
shared_libs: [
"libhidlbase",
"libutils",
"[email protected]",
],
}
cc_binary {
name: "[email protected]",
relative_install_path: "hw",
defaults: ["hidl_defaults"],
proprietary: true,
init_rc: ["[email protected]"],
vintf_fragments: ["[email protected]"],
srcs: [
"SerialPort.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"liblog",
"libdl",
"libutils",
"libhardware",
"libhidlbase",
"libhidltransport",
"[email protected]",
],
}
2. device/$your_company/$SOC/device.mk
Adding
PRODUCT_PACKAGES += \
[email protected] \
[email protected]
current stksensor
directory structure
stksensor/
└── 1.0
├── Android.bp
├── default
│ ├── Android.bp
│ ├── [email protected]
│ ├── [email protected]
│ ├── service.cpp
│ ├── StksensorCallBack.cpp
│ ├── StksensorCallBack.h
│ ├── Stksensor.cpp
│ └── Stksensor.h
├── IStksensorCallBack.hal
├── IStksensor.hal
└── types.hal
Note: Some avc
permissions will be reported, you need to add them yourself