In this step, we will develop the AIDL-HAL service based on the AIDL interface we implemented before. It’s a backend AIDL service that we want to implement with C++.
Let’s break it down into some steps:
- Implement/Extend a class from the AIDL interface
- Get a binder from the implemented class and add it as a service
- Add the required configuration to the new variant
Implement the AIDL interface
First, we need to include a header file like below to import the definitions of the AIDL into our project:
#include <aidl/aospinsight/hardware/dummy_device/BnDummy.h>
Then we will develop a new class and will use BnDummy as the base class. In order to implement it, we should override the methods of the AIDL interface. Here you can find the header file of DummyImpl.
class DummyImpl : public BnDummy {
virtual ndk::ScopedAStatus getPacketByCallback(const std::shared_ptr<IDummyCallback>& cb) override;
virtual ndk::ScopedAStatus getPacket(DummyPacket* dummyPacket) override;
protected:
std::shared_ptr<IDummyCallback> dummyCallback = nullptr;
std::mutex dummyMutex;
void onPacketEvent(DummyPacket* dummyPacket);
};
dummyCallback is defined to keep the callback pointer to make it possible to invoke the methods from the application.
How to use the callback and invoke a remote method
void DummyImpl::onPacketEvent(DummyPacket* dummyPacket) {
LOG(INFO) << "onNewPacket called!";
dummyCallback->onGetPacket(*dummyPacket);
}
onPacketEvent is a sample of how we can use the callback pointer in the daemon. onGetPacket is a remote method that can be invoked by the callback pointer. We will implement onGetPacket later in an Android app. On receiving a packet the daemon cal call onPacketEvent that will invoke a remote method to send a packet to the client.
Get a binder and add the service
To create a binder we should create a new object of DummyImpl class. This will take place in the main functions of the projects.
std::shared_ptr<DummyImpl> dummy = ndk::SharedRefBase::make<DummyImpl>();
Now we need to use the AIDL descriptor to take the next step.
const std::string instance = std::string() + DummyImpl::descriptor + "/default";
And now will take the last step:
binder_status_t status = AServiceManager_addService(dummy->asBinder().get(), instance.c_str());
The service is added successfully If _status_t equals STATUS_OK.
Manifest files
We’ve added the AIDL interface to be built. But we need to define the device manifest file and the framework compatibility manifest file as well.
The daemon will be started automatically
To start the daemon automatically we can add a .rc file in Android.bp that will be processed by the system. You can find dummy-default.rc in the init folder. That’s how it’s defined in the Android.bp file:
init_rc: ["init/dummy-default.rc"],
Build configuration
The dummy service and the manifest files should be added to the build system manually. You can find the configuration in aospinsight_car.mk.
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE += \
$(VENDOR_PATH)/hardware/dummy_service/manifest/dummy_framework_compatibility_matrix.xml \
PRODUCT_PACKAGES += \
dummy-service \
How to check the daemon
The first step is that run the emulator. In order to do that, you need to open a new terminal and run the commands below:
source build/envsetup.sh
lunch aospinsight_car-userdebug
emulator -wipe-data -no-audio
To see if the HAL service is started automatically you can run the command below in your terminal after running the emulator.
adb logcat | grep -i -e dummy
Then you will see something like the screenshot below in your terminal.
could you please provide any other aidl for hal,i didn’t got it
If you can explain more about the problem or what you’re looking for I might be able to help. The source code I’ve provided in Github includes everything you need to put it up and running. But of course, based on the implementation of the HAL service or the app you might need to add some SEPolicies.
it ws giving an error like this
[ 67% 661/985] Verify hardware/interfaces/dummy_device/aidl/aidl_api/android.hardware.dummy_device/1 files have not been modified
FAILED: out/soong/.intermediates/hardware/interfaces/dummy_device/aidl/android.hardware.dummy_device-api/checkhash_1.timestamp
if [ $(cd ‘hardware/interfaces/dummy_device/aidl/aidl_api/android.hardware.dummy_device/1’ && { find ./ -name “*.aidl” -print0 | LC_ALL=C sort -z | xargs -0 sha1sum && echo latest-version; } | sha1sum | cut -d ” ” -f 1) = $(read -r <'hardware/interfaces/dummy_device/aidl/aidl_api/android.hardware.dummy_device/1/.hash' hash extra; printf %s $hash) ]; then touch out/soong/.intermediates/hardware/interfaces/dummy_device/aidl/android.hardware.dummy_device-api/checkhash_1.timestamp; else cat 'system/tools/aidl/build/message_check_integrity.txt' && exit 1; fi
###############################################################################
# ERROR: Modification detected of stable AIDL API file #
###############################################################################
Above AIDL file(s) has changed, resulting in a different hash. Hash values may
be checked at runtime to verify interface stability. If a device is shipped
with this change by ignoring this message, it has a high risk of breaking later
when a module using the interface is updated, e.g., Mainline modules.
17:05:07 ninja failed with: exit status 1
it ws giving an error like this
[ 67% 661/985] Verify hardware/interfaces/dummy_device/aidl/aidl_api/android.hardware.dummy_device/1 files have not been modified
FAILED: out/soong/.intermediates/hardware/interfaces/dummy_device/aidl/android.hardware.dummy_device-api/checkhash_1.timestamp
if [ $(cd ‘hardware/interfaces/dummy_device/aidl/aidl_api/android.hardware.dummy_device/1’ && { find ./ -name “*.aidl” -print0 | LC_ALL=C sort -z | xargs -0 sha1sum && echo latest-version; } | sha1sum | cut -d ” ” -f 1) = $(read -r <'hardware/interfaces/dummy_device/aidl/aidl_api/android.hardware.dummy_device/1/.hash' hash extra; printf %s $hash) ]; then touch out/soong/.intermediates/hardware/interfaces/dummy_device/aidl/android.hardware.dummy_device-api/checkhash_1.timestamp; else cat 'system/tools/aidl/build/message_check_integrity.txt' && exit 1; fi
###############################################################################
# ERROR: Modification detected of stable AIDL API file #
###############################################################################
Above AIDL file(s) has changed, resulting in a different hash. Hash values may
be checked at runtime to verify interface stability. If a device is shipped
with this change by ignoring this message, it has a high risk of breaking later
when a module using the interface is updated, e.g., Mainline modules.
17:05:07 ninja failed with: exit status 1
If you have changed anything in the AIDL file, you need to generate the hash and put it in .hash. You can find the command to generate the hash file in https://aospinsight.com/how-to-implement-the-aidl-interface/. Otherwise the build system identifies it as unwanted change and make an error. Also the hash is being used for compatibility usage.
could you please provide the details of where to ad the sepolicies
You can find the sepolicy folders/files in device/devboard/sepolicy. Find the right file to add the new domain/rule/etc.
You can take a look at Using audit2allow section on https://source.android.com/docs/security/features/selinux/validate.
Afterwards, you will have the required sepolicies for your change and can add them to the files.
Could you please help to resolve this error.
FAILED: out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows
/bin/bash -c “(ASAN_OPTIONS=detect_leaks=0 out/host/linux-x86/bin/checkpolicy -M -c 30 -o out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/policy.conf ) && (out/host/linux-x86/bin/sepolicy-analyze out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp neverallow -w -f out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/policy_2.conf || ( echo \”\” 1>&2; echo \”sepolicy-analyze failed. This is most likely due to the use\” 1>&2; echo \”of an expanded attribute in a neverallow assertion. Please fix\” 1>&2; echo \”the policy.\” 1>&2; exit 1 ) ) && (touch out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp ) && (mv out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp out/target/product/AGN_H164YO_MT8788R/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows )”
‘ on line 110424:t6771/sepolicy/basic/hal_wifi_default.te:3:WARNING ‘unrecognized character’ at token ‘
allow hal_wifi_default self:capability sys_module;
#============= hal_wifi_default ==============
‘ on line 110425:t6771/sepolicy/basic/hal_wifi_default.te:4:WARNING ‘unrecognized character’ at token ‘
allow hal_wifi_default self:capability sys_module;
allow hal_wifi_default vendor_file:system module_load;
system/sepolicy/public/hal_hongxi.te:4:ERROR ‘unknown type hal_hongxi_service’ at token ‘;’ on line 18523:
#line 4
allow hal_hongxi_server hal_hongxi_service:service_manager { add find };
checkpolicy: error(s) encountered while parsing configuration
It means that hal_hongxi_service is not defined, or it’s defined but the sequence of processing the SELinux files is incorrect. To process that rule both of hal_hongxi_server and hal_hongxi_service should be seen before by the build system. Otherwise, it raises an error.
Hi Arun ,
I am facing same problem could you please help me out ?
Is it possible to connect with you via mail or call ?
The email is sent!
I have recently started working on Android side and end up with one issue. As from Android U onwards all Android HALs will be migrated to AIDLs, I am currently trying to do this migration for my project. With the hidl2aidl tool I am successfully able to generate *.aidl files.
But I am observing the below fixme line in my generated aidl file.
// FIXME: AIDL does not allow int to be an out parameter. // Move it to return, or add it to a Parcelable.
Is there any know fix for these kind of FixMes? Is there any issue in setting out parameter with AIDL? What if I have multiple out parameters from a function?
Yeah, it’s not allowed to use the out parameter. So what you can do is this:
– create a new aidl file and define a parcelable. You can find an example of that in the example in my Github.
– Then, use that parcelable as a return type for the method in your aidl interface.The parcelable includes all the parameters you want to return. The build system will create a class based on the parcelable.
https://github.com/Heydarchi/AIDL-HAL-Service
https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/light/aidl/aidl_api/android.hardware.light/1/android/hardware/light/
Hi, Great post. I’m finding the error that I see you also have in your last screenshot above!
“Could not start service dummy-server” Take a look above. Any idea how to fix?
Hi,
The screenshot is for an emulator running in SELinux enforcement. As a temporary solution you should run the emulator or device in permissive mode.
But if you can have a llok at the source code located in Github you can find the SELinux policies required to solve it. You will find those files in the device folder.
https://github.com/Heydarchi/AIDL-HAL-Service
Hi,
I really appreciate your topics. But I don’t understand why we have the below header, and where it’s generated
#include
Thanks
Though your message is not complete and the header file is missed, I think you meant:
BnDummy.h
If yes, creating the AIDL interface produced this header file as one of the results. I would say that the AIDL interface module that we add to AOSP would generate some libraries and header files. Its Andoird.bp file contains a definition of the created libraries. Afterward, based on it, the necessary source code will also be accessible.
For instance, the AOSP build system will provide the header and source code if you request C++/NDK libraries so that you can include them in your project.
Thank you for your quick response.
That’s exactly what I need.
Could you write the article to use AIDL Service from the user application?
Thanks
No worries!
If you mean to communicate from a user app to an AIDL HAL service I would say that it’s not a good idea.
But, I have planne to implement AIDL interface for the user applications as well when I can find some time.
Hello. I have a question after reading these posts that I was wondering about. If I built the AOSP, can I use these same concepts that you showed us to call an AIDL interface that is already on the device? For example, the camera HAL?
I am wondering if I can create my own daemon and then from there control the camera or microphone using the HAL already on the device. Thank you.