> 技术文档 > android 12 的 aidl for HAL 开发示例_android 完整的写一个自定义aidl到hal层

android 12 的 aidl for HAL 开发示例_android 完整的写一个自定义aidl到hal层

说明:aidl for HAL 这种机制,可以自动生成java代码,app调用可以获取中间过程的jar包,结合反射调用 ServiceManager.getService 方法,直接获取 HAL 服务,不再需要费力在framework层添加代码,方便快捷。

1. 定义aidl接口

hardware/interfaces/test/aidl/android/hardware/test/ITest.aidl

package android.hardware.test;@VintfStabilityinterface ITest { String getMsg(); void setMsg(in String msg);}

2. 创建Android.bp
hardware/interfaces/test/aidl/Android.bp

aidl_interface { name: \"android.hardware.test\", vendor: true, srcs: [\"android/hardware/test/*.aidl\"], stability: \"vintf\", owner: \"test\", backend: { cpp: { enabled: true, }, java: { platform_apis: true, }, ndk: { enabled: true, } },}

3. 编译
mmm hardware/interfaces/test/

4. 编译报错,根据提示重新编译生成 aidl api

m android.hardware.test-update-api

5. 生成成功后重新编译

mmm hardware/interfaces/test/

编译成功

6. 实现HAL接口

hardware/interfaces/test/aidl/default/Test.h

#pragma once#include namespace aidl {namespace android {namespace hardware {namespace test{class Test: public BnTest { public: //String getMsg(); ndk::ScopedAStatus getMsg(std::string* _aidl_return); //void setMsg(in String msg); ndk::ScopedAStatus setMsg(const std::string& msg); private: std::string message = \"\";};} // namespace test} // namespace hardware} // namespace android} // namespace aidl

hardware/interfaces/test/aidl/default/Test.cpp

#define LOG_TAG \"Test\"#include #include #include \"Test.h\"namespace aidl {namespace android {namespace hardware {namespace test{ndk::ScopedAStatus Test::getMsg(std::string* _aidl_ret) { *_aidl_ret = message; return ndk::ScopedAStatus::ok();}ndk::ScopedAStatus Test::setMsg(const std::string& msg) { message = msg; return ndk::ScopedAStatus::ok();}} // namespace test} // namespace hardware} // namespace android} // namespace aidl

7. 添加服务

hardware/interfaces/test/aidl/default/main.cpp

#define LOG_TAG \"Test\"#include #include #include #include \"Test.h\"using aidl::android::hardware::test::Test;int main() { ABinderProcess_setThreadPoolMaxThreadCount(0); ABinderProcess_startThreadPool(); std::shared_ptr test = ndk::SharedRefBase::make(); const std::string desc = std::string() + Test::descriptor + \"/default\"; if (test != nullptr) { if(AServiceManager_addService(test->asBinder().get(), desc.c_str()) != STATUS_OK) { return -1; } } else { return -1; } ABinderProcess_joinThreadPool(); return EXIT_FAILURE;}

8. init rc

hardware/interfaces/test/aidl/default/android.hardware.test-service.rc

service android.hardware.test-service /vendor/bin/hw/android.hardware.test-service interface aidl android.hardware.test.ITest/default class hal user system group system

9. manifest

hardware/interfaces/test/aidl/default/android.hardware.test-service.xml

  android.hardware.test 1   ITest  default  

10. 编译脚本

hardware/interfaces/test/aidl/default/Android.bp

cc_binary { name: \"android.hardware.test-service\", vendor: true, relative_install_path: \"hw\", init_rc: [\"android.hardware.test-service.rc\"], vintf_fragments: [\"android.hardware.test-service.xml\"], srcs: [ \"Test.cpp\", \"main.cpp\", ], shared_libs: [ \"liblog\", \"libbase\", \"libbinder_ndk\", \"android.hardware.test-V1-ndk_platform\", ],}

10. 参与编译
device\\xxx\\xxx\\project.mk

PRODUCT_PACKAGES += \\ android.hardware.test \\ android.hardware.test-service

11. 模块添加到兼容性矩阵中

hardware/interfaces/compatibility_matrices/compatibility_matrix.x.xml

hardware/interfaces/compatibility_matrices/compatibility_matrix.current.xml

 android.hardware.test 1  ITest default 

12. 解决selinux的问题

参考:Android12 AIDL native层实现_android native aidl-CSDN博客

13. 编译,烧录

14. 测试

开机后,先看看服务是否起来 adb shell \"service list | grep test\"

C++ 测试在这里忽略,参考:Android12 AIDL native层实现_android native aidl-CSDN博客

15. java 测试

取出 out\\soong\\.intermediates\\hardware\\interfaces\\test\\aidl\\android.hardware.test-V1-java\\android_common\\javac下的jar包,放到android工程里边。

由于android.os.ServiceManager是个隐藏类,我们用反射

public static IBinder getService(String name) { try { Class c = Class.forName(\"android.os.ServiceManager\"); Method getService = c.getMethod(\"getService\", String.class); return (IBinder) getService.invoke(c, name); } catch (Exception e) { e.printStackTrace(); return null; }}

java 测试代码:

IBinder binder = getService(\"android.hardware.test.ITest/default\");ITest test = ITest.Stub.asInterface(binder);Log.d(\"TestHal\", \"binder: \" + test);try { test.setMsg(\"test message\"); String msg = test.getMsg(); Log.d(\"TestHal\", \"HAL message: \" + msg);} catch (Exception e) { e.printStackTrace();}

>> 为什么 getService 是 android.hardware.test.ITest/default 这个可以用 service list | grep test 获取。

这是在 aidl 服务实现时候 add service 时候传入的:

const std::string desc = std::string() + Test::descriptor + \"/default\";

>> 另外 selinux 的解决,可以参考:

SELinux 权限问题调试_audit(0.0:343): avc: denied { create }-CSDN博客

>> 在apk导入framework.jar的方式调用 ServiceManager

在 libs 同级目录下创建 libsconly 把 framework.jar 放入,build.gradle 添加:

compileOnly fileTree(dir: \'libsconly\', include: [\'*.jar\'])

sync 之后就可以使用 android.os.ServiceManager 的静态方法了。

参考:RK3568 Android11 增加HAL层的AIDL_android hal aidl-CSDN博客

感谢参考文献的各位,算是在 Android 12 上跑通了。