小工具知识网

当前位置: 首页 > 行业知识 > Android12 AIDL native层实现

行业知识

Android12 AIDL native层实现

2026-11-01 17:48:31 来源:互联网转载

本文主要是讲解如何实现一个完整的AIDL HAL层的例子,包括aidl文件的编写、service的实现、测试用例的实现、开机启动以及编译过程中和运行时的错误如何解决。此文不讲解AIDL的原理,具体原理的了解请参考官方资料:https://source.android.com/docs/core/architecture/aidl?hl=zh-cn

生成中间库

创建code路径:vendor/xxxx/proprietary/hardware/interfaces/helloworld

在上面的目录下创建子路径:aidl/vendor/hardware/helloworld

创建Android.bp和IHelloWorld.aidl,文件位置如下:

1.vendor/xxxx/proprietary/hardware/interfaces/helloworld$ tree  2..  3.└── aidl  4.    ├── Android.bp  5.    └── vendor  6.        └── hardware  7.            └── helloworld  8.                └── IHelloWorld.aidl  

Android.bp内容:

1.aidl_interface {  2.    name: "vendor.hardware.helloworld",  3.    vendor_available: true,  4.    srcs: ["vendor/hardware/ helloworld /*.aidl"],  5.    stability: "vintf",  6.    owner: "yezhiqiang",  7.    backend: {  8.        java: {  9.            enabled: true,  10.            platform_apis: true,  11.        },  12.        ndk: {  13.            enabled: true,  14.        },  15.        cpp: {  16.            enabled: true,  17.        },  18.    },  19.}  

IHelloWorld.aidl内容:

1.package vendor.hardware.helloworld;  2.  3.@VintfStability  4.interface IHelloWorld {  5.        void sayWhat(String what);  6.}  

尝试编译:mmm vendor/xxxx/proprietary/hardware/interfaces/helloworld/aidl/

发生错误如下:

FAILED: out/soong/.intermediates/vendor/xxxx/proprietary/hardware/interfaces/helloworld/aidl/vendor.hardware.helloworld-api/checkapi_current.timestamp  echo "API dump for the current version of AIDL interface vendor.hardware.helloworld does not exist." && echo Run "m vendor.hardware.helloworld-update-api", or add "unstable: true" to the build rule for the interface if it does not need to be versioned && false # hash of input list: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  API dump for the current version of AIDL interface vendor.hardware.helloworld does not exist.  Run m vendor.hardware.helloworld-update-api, or add unstable: true to the build rule for the interface if it does not need to be versioned  

虽然出错,但此时已经在out目录下创建了部分目录:

1.//out/soong/.intermediates/vendor/xxxx/proprietary/hardware/interfaces/helloworld/aidl/  2.vendor.hardware.helloworld-api/  3.vendor.hardware.helloworld-V1-java/  

根据提示,需要执行命令:m vendor.hardware.helloworld-update-api

成功时打印如下信息:

[100% 13/13] //vendor/xxxx/proprietary/hardware/interfaces/helloworld/aidl:vendor.hardware.helloworld-api Making AIDL API of vendor.hardware.helloworld as version c  

此时,会在aidl_api/vendor.hardware.helloworld/目录下生成current及其内部的内容。

回过头来,再次执行:

mmm vendor/xxxx/proprietary/hardware/interfaces/helloworld/aidl/,编译成功。

此时发现out目录下生成了很多目录:

那么执行到这一步,其实在out目录下已经生成了binder的各种类型的源文件以及各种IBinder库了。

编写services

创建default目录及相应服务程序,文件列表如下:

vendor/xxxx/proprietary/hardware/interfaces/helloworld/aidl/default$ tree  .  ├── Android.bp  ├── HelloWorld.cpp  ├── HelloWorld.h  ├── service.cpp  ├── vendor.hardware.helloworld-service.rc  └── vendor.hardware.helloworld-service.xml  

Android.bp内容:

1.cc_binary {  2.    name: "vendor.hardware.helloworld-service",  3.    relative_install_path: "hw",  4.    init_rc: ["vendor.hardware.helloworld-service.rc"],  5.    vintf_fragments: ["vendor.hardware.helloworld-service.xml"],  6.    vendor: true,  7.    srcs: [  8.        "service.cpp",  9.        "HelloWorld.cpp",  10.    ],  11.    shared_libs: [  12.        "vendor.hardware.helloworld-V1-ndk_platform",  13.         "liblog",  14.        "libbase",  15.        "libbinder_ndk",  16.    ],  17.}  

HelloWorld.h内容:

1.#pragma once  2.  3.#include   4.  5.namespace aidl {  6.namespace vendor {  7.namespace hardware {  8.namespace helloworld {  9.class HelloWorld : public BnHelloWorld {  10.public:  11.    HelloWorld() = default;  12.  13.    ::ndk::ScopedAStatus  sayWhat(const std::string& in_what);  14.};  15.  16.  17.}  // namespace helloworld  18.}  // namespace hardware  19.}  // namespace vendor  20.}  // namespace aidl  

HelloWorld.cpp内容:

1.#include "HelloWorld.h"  2.#include   3.#include 4.  5.namespace aidl {  6.namespace vendor {  7.namespace hardware {  8.namespace helloworld {  9.  10.::ndk::ScopedAStatus HelloWorld::sayWhat(const std::string& in_what) {  11.    ALOGI("client say:%s.", in_what.c_str());12.13.    return ::ndk::ScopedAStatus::ok();14.}  15.  16.}  // namespace helloworld  17.}  // namespace hardware  18.}  // namespace vendor  19.}  // namespace aidl  

service.cpp内容:

1.#include   2.#include   3.#include   4.  5.#include "HelloWorld.h"  6.  7.using ::aidl::vendor::hardware::helloworld::HelloWorld;  8.  9.int main() {  10.    ABinderProcess_setThreadPoolMaxThreadCount(0);  11.    std::shared_ptr hello = ndk::SharedRefBase::make();  12.  13.    const std::string instance = std::string() + HelloWorld::descriptor + "/default";  14.    binder_status_t status = AServiceManager_addService(hello->asBinder().get(), instance.c_str());  15.    CHECK(status == STATUS_OK);  16.  17.    ABinderProcess_joinThreadPool();  18.    return -1; // Should never be reached  19.}  

vendor.hardware.helloworld-service.rc内容:

1.service vendor_helloworld_default /vendor/bin/hw/vendor.hardware.helloworld-service  2.    class hal  3.    user root  4.    group root  

vendor.hardware.helloworld-service.xml内容:

1.  2.      3.        vendor.hardware.helloworld  4.        1  5.          6.            IHelloWorld  7.            default  8.          9.      10.  

解决启动问题

验证service能否正常启动,将如下文件分别push入系统:

1.//push to vendor/lib/  2.vendor.hardware.helloworld-V1-ndk_platform.so  3.//push to vendor/etc/vintf/manifest  4.vendor.hardware.helloworld-service.xml  5.//push to vendor/etc/init/  6.vendor.hardware.helloworld-service.rc  7.//push to vendor/bin/hw/  8.vendor.hardware.helloworld-service  

手动执行./vendor/bin/hw/vendor.hardware.helloworld-service,报错如下:

1.05-16 10:10:34.484   208   208 E servicemanager: Could not find vendor.hardware.hw.IHelloWorld/default in the VINTF manifest.  2.05-16 10:10:34.484  4696  4696 F vendor.hardware.helloworld-service: Check failed: status == STATUS_OK   3.--------- beginning of crash  4.05-16 10:10:34.484  4696  4696 F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 4696 (vendor.hardware), pid 4696 (vendor.hardware)  5.05-16 10:10:34.500  4701  4701 I crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto  6.05-16 10:10:34.501   258   258 I tombstoned: received crash request for pid 4696  7.05-16 10:10:34.501  4701  4701 I crash_dump32: performing dump of process 4696 (target tid = 4696)  8.05-16 10:10:34.520  4701  4701 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***  9.05-16 10:10:34.520  4701  4701 F DEBUG   : Build fingerprint: 'Xxxxx/xx_evb_xxxx/xx_evb_xxxx:12/SQ1D.220205.004/eng.E00023.20240314.110003:userdebug/release-keys'  10.05-16 10:10:34.520  4701  4701 F DEBUG   : Revision: '0'  11.05-16 10:10:34.520  4701  4701 F DEBUG   : ABI: 'arm'  12.05-16 10:10:34.520  4701  4701 F DEBUG   : Timestamp: 2024-05-16 10:10:34.503272142+0800  13.05-16 10:10:34.521  4701  4701 F DEBUG   : Process uptime: 0s  14.05-16 10:10:34.521  4701  4701 F DEBUG   : Cmdline: ./vendor.hardware.helloworld-service  15.05-16 10:10:34.521  4701  4701 F DEBUG   : pid: 4696, tid: 4696, name: vendor.hardware  >>> ./vendor.hardware.helloworld-service   2.    

上一篇:后台-vite中import.meta.glob的具体用法 与 动态路由和递归组件菜单栏

下一篇:云端服务器怎么设置?