小工具知识网

当前位置: 首页 > 行业知识 > hal深入剖析之aidl实战-android framework车机车载手机系统开发

行业知识

hal深入剖析之aidl实战-android framework车机车载手机系统开发

2026-11-07 00:02:09 来源:互联网转载

1、创建相关的目录hal目录及aidl存放目录

~/nx563j_xiaomi$ mkdir hardware/interfaces/mytest~/nx563j_xiaomi$ cd hardware/interfaces/mytest/

这个是hal工程根目录

接下来要创建aidl的文件存放目录

test@test:~/nx563j_xiaomi/hardware/interfaces/mytest$ mkdir aidltest@test:~/nx563j_xiaomi/hardware/interfaces/mytest$ cd aidl/test@test:~/nx563j_xiaomi/hardware/interfaces/mytest/aidl$ mkdir -p  android/hardware/mytest

注意mkdir -p android/hardware/mytest其实就是包名目录,即模块包名就是android.hardware.mytest.

提示:这个如果为了项目的更加好的维护性建议到自己项目目标的vendor下面进行,目前只是为了演示方便,直接在system的hardware下面

2、创建定义对应aidl文件

创建最重要的aidl接口文件,需要在第一步创建的目录下

test@test:~/nx563j_xiaomi/hardware/interfaces/mytest/aidl/android/hardware/mytest$ touch IMyTest.aidltest@test:~/nx563j_xiaomi/hardware/interfaces/mytest/aidl/android/hardware/mytest$ touch MyTestObj.aidltest@test:~/nx563j_xiaomi/hardware/interfaces/mytest/aidl$ tree.`-- android    `-- hardware        `-- mytest            |-- IMyTest.aidl            `-- MyTestObj.aidl

编写aidl内容:

IMyTest.aidl

package android.hardware.mytest; import android.hardware.mytest.MyTestObj; @VintfStability interface IMyTest {    MyTestObj test();}

MyTestObj.aidl

package android.hardware.mytest; @VintfStability parcelable MyTestObj {    String key;    int value;}

其实和普通的aidl基本一样,唯一差别就是要多一些稳定性的声明比如@VintfStability这个注解官方解释如下:

VintfStabilityVintfStability declares that a user-defined type (interface, parcelable, and enum) can be used across the system and vendor domains.

还是就是parcelable都是需要进行结构化,成员属性写清楚到aidl

3、编写顶层aidl的Android.bp

最开始的aidl目录创建一个Android.bp

test@test:~/nx563j_xiaomi/hardware/interfaces/mytest/aidl$ touch Android.bp

Android.bp

aidl_interface {    name: "android.hardware.mytest",    vendor_available: true,    srcs: ["android/hardware/mytest/*.aidl"],    stability: "vintf",    owner:"qianli.ma",    backend: {        cpp: {            enabled: false,        },        java: {            sdk_version: "module_current",        },    },}

需要注意以下几个点:

1、要写aidl_interface目标

2、设置成 vendor_available: true即代表vendor和system都可以用,不是vendor独享

3、stability: “vintf” stability保证接口是稳定的属性,目前只支持vintf

4、backend 这里的后端有4个,C++/JAVA/NDK/RUST, 我们将使用NDK和java,因此将CPP声明为false,为啥不使用c++呢?为啥出来个ndk呢?这个google官方给出了解释

https://source.android.google.cn/docs/core/architecture/aidl/aidl-hals#choosing-runtime

Building against the AIDL runtimeAIDL has three different backends: Java, NDK, CPP. To use Stable AIDL, you must always use the system copy of libbinder at system/lib*/libbinder.so and talk on /dev/binder. For code on the vendor image, this means that libbinder (from the VNDK) cannot be used: this library has an unstable C++ API and unstable internals. Instead, native vendor code must use the NDK backend of AIDL, link against libbinder_ndk (which is backed by system libbinder.so), and link against the -ndk_platform libraries created by aidl_interface entries.

大概意思就是一般aidl的vendor和system跨进程中不使用libbinder的包,因为一般vendor使用是vndk下面的包,故无法访问dev/binder,访问其实是dev/vndbinder,所有一般使用是NDK

4、编译接口文件

编译命令:

test@test:~/nx563j_xiaomi$ mmm hardware/interfaces/mytest

但是出现如下错误

[ 62% 200/319] echo "API dump for the current version of AIDL interface android.hardware.mytest does not exist." && echo Run "m android.hardware.mytest-update-api", or add "unstable: true" to the build rFAILED: out/soong/.intermediates/hardware/interfaces/mytest/aidl/android.hardware.mytest-api/checkapi_current.timestampecho "API dump for the current version of AIDL interface android.hardware.mytest does not exist." && echo Run "m android.hardware.mytest-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: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855API dump for the current version of AIDL interface android.hardware.mytest does not exist.Run m android.hardware.mytest-update-api, or add unstable: true to the build rule for the interface if it does not need to be versioned12:38:45 ninja failed with: exit status 1#### failed to build some targets (01:04 (mm:ss)) ####

大概意思我们的接口是不存在的需要更新api执行:

m android.hardware.mytest-update-api

下面执行新的编译命令:

m android.hardware.mytest-update-api

成功后如下打印

out/soong/Android-lineage_nx563j.mk was modified, regenerating...[100% 190/190] //hardware/interfaces/mytest/aidl:android.hardware.mytest-api Updating AIDL API dump version current for android.hardware.mytest (see hardware/interfaces/mytest/aidl/aidl_api/android.hardw#### build completed successfully (06:57 (mm:ss)) ####

此时的目录已经被生成了aidl_api目录

test@test:~/nx563j_xiaomi/hardware/interfaces/mytest$ tree.`-- aidl    |-- Android.bp    |-- aidl_api    |   `-- android.hardware.mytest    |       `-- current    |           `-- android    |               `-- hardware    |                   `-- mytest    |                       |-- IMyTest.aidl    |                       `-- MyTestObj.aidl    `-- android        `-- hardware            `-- mytest                |-- IMyTest.aidl                `-- MyTestObj.aidl

然后在进行刚才的编译

test@test:~/nx563j_xiaomi$ mmm hardware/interfaces/mytest

成功后会有如下打印

============================================[100% 128/128] Install: out/target/product/nx563j/system/framework/android.hardware.mytest-V1-java.jar#### build completed successfully (03:20 (mm:ss)) ####

这里主要是在编译相关目录生成相关接口代码和库,具体路径如下:

test@test:~/nx563j_xiaomi/out/soong/.intermediates/hardware/interfaces/mytest/aidl$ ls -ltotal 20drwxrwxr-x  3 test test 4096 Dec 12 13:07 android.hardware.mytest-V1-javadrwxrwxr-x  3 test test 4096 Dec 12 13:07 android.hardware.mytest-V1-java-sourcedrwxrwxr-x 16 test test 4096 Dec 12 13:07 android.hardware.mytest-V1-ndkdrwxrwxr-x  3 test test 4096 Dec 12 13:07 android.hardware.mytest-V1-ndk-sourcedrwxrwxr-x  3 test test 4096 Dec 12 13:07 android.hardware.mytest-apitest@test:~/nx563j_xiaomi/out/soong/.intermediates/hardware/interfaces/mytest/aidl$ 

因为bp中backend只对ndk和java有开放,c++已经关闭了

android.hardware.mytest-V1-ndk 代表aidl相关的库

android.hardware.mytest-V1-ndk-source 代表aidl相关的源文件比如一些头文件或者bp,bn文件

有了上面的生成代码和库,我们就可以写一个服务端的程序了

5、编写服务端程序代码

准备好相关的源文件和xml,rc配置文件

test@test:~/nx563j_xiaomi/hardware/interfaces/mytest/aidl/default$ tree.|-- Android.bp|-- MyTestImpl.cpp|-- MyTestImpl.h|-- android.hardware.mytest.rc|-- main.cpp`-- mytest-default.xml0 directories, 6 files

分为两部分:

源码部分

MyTestImpl.cpp —Binder服务端的具体实现部分cpp

#define LOG_TAG "MyTestImpl"#define LOG_NDEBUG 0#include "MyTestImpl.h"#include #include namespace aidl::android::hardware::mytest {    ::ndk::ScopedAStatus MyTestImpl::test(::aidl::android::hardware::mytest::MyTestObj* _aidl_return) {        *_aidl_return = mObj;        ALOGE(" MyTestImpl::test ok");        return ::ndk::ScopedAStatus::ok();}}  // namespace aidl::android::hardware::mytest

MyTestImpl.h—Binder服务端的具体实现部分头文件

#ifndef ANDROID_HARDWARE_MYTESTIMPL_H#define ANDROID_HARDWARE_MYTESTIMPL_H#include namespace aidl::android::hardware::mytest {class MyTestImpl : public BnMyTest {  public:    ::aidl::android::hardware::mytest::MyTestObj  mObj = {"hello",1};    ::ndk::ScopedAStatus test(::aidl::android::hardware::mytest::MyTestObj* _aidl_return) override;};}  // namespace aidl::android::hardware::mytest#endif  

main.cpp ----主程序入口cpp

#include "MyTestImpl.h"#define LOG_TAG "MyTestImpl"#define LOG_NDEBUG 0#include #include #include #include #include using aidl::android::hardware::mytest::MyTestImpl;int main() {    ABinderProcess_setThreadPoolMaxThreadCount(0);    std::shared_ptr test = ::ndk::SharedRefBase::make();    const std::string instance = std::string() + MyTestImpl::descriptor + "/default";    printf("MyTestImpl instance =%s  sde =%p \n", instance.c_str(),test->asBinder().get());    binder_status_t status =          AServiceManager_addService(test->asBinder().get(), instance.c_str());    CHECK_EQ(status, STATUS_OK);    printf("MyTestImpl AServiceManager_addService status=%d \n", status);    fflush(stdout);    ABinderProcess_joinThreadPool();    return EXIT_FAILURE;  // should not reach}
bp和配置文件部分

Android.bp --编译可执行文件的bp

cc_binary {    name: "android.hardware.mytest.example",    relative_install_path: "hw",    vendor: true,    init_rc: ["android.hardware.mytest.rc"],    vintf_fragments: ["mytest-default.xml"],    shared_libs: [        "android.hardware.mytest-V1-ndk",         "liblog",        "libbase",        "libcutils",        "libutils",        "libbinder_ndk",    ],    srcs: [        "main.cpp",        "MyTestImpl.cpp",    ],}

android.hardware.mytest.rc --开机自启动

service vendor.mytest-default /vendor/bin/hw/android.hardware.mytest.example    class hal    user root    group root

mytest-default.xml ----声明接口到vintf中

            android.hardware.mytest        1                IMyTest        default        

然后再执行编译命令:

 mmm hardware/interfaces/mytest/

出现如下成功提示:

aservices============================================[100% 10/10] Install: out/target/product/nx563j/vendor/bin/hw/android.hardware.mytest.example#### build completed successfully (5 seconds) ####

到此基本上aidl业务模块就完成了,一个简单接口实现就好了

6、模块加入到兼容性矩阵中

应该添加到的目录即文件

hardware/interfaces/compatibility_matrices

test@test:~/nx563j_xiaomi/hardware/interfaces/compatibility_matrices$ lltotal 188drwxrwxr-x  4 test test  4096 Dec 12 11:39 ./drwxrwxr-x 54 test test  4096 Dec 12 11:43 ../-rw-rw-r--  1 test test  2764 Mar  4  2023 Android.bp-rw-rw-r--  1 test test  4860 Mar  4  2023 Android.mk-rw-rw-r--  1 test test  2440 Mar  4  2023 CleanSpec.mkdrwxrwxr-x  2 test test  4096 Mar  4  2023 build/-rw-rw-r--  1 test test   942 Mar  4  2023 clear_vars.mk-rw-rw-r--  1 test test 15448 Mar  4  2023 compatibility_matrix.3.xml-rw-rw-r--  1 test test 16709 Mar  4  2023 compatibility_matrix.4.xml-rw-rw-r--  1 test test 18568 Mar  4  2023 compatibility_matrix.5.xml-rw-rw-r--  1 test test 21273 Mar  4  2023 compatibility_matrix.6.xml-rw-rw-r--  1 test test 26116 Dec 12 11:39 compatibility_matrix.7.xml-rw-rw-r--  1 test test 26380 Dec 12 11:39 compatibility_matrix.current.xml-rw-rw-r--  1 test test    56 Mar  4  2023 compatibility_matrix.empty.xml-rw-rw-r--  1 test test  5349 Mar  4  2023 compatibility_matrix.mkdrwxrwxr-x  3 test test  4096 Mar  4  2023 exclude/-rw-rw-r--  1 test test    41 Mar  4  2023 manifest.empty.xml

这里应该选数字最大的7和current两个xml文件

compatibility_matrix.7.xml

compatibility_matrix.current.xml

2个文件加入如下内容:

            android.hardware.mytest        1                IMyTest        default            

7、增加对应selinux权限

这里直接做成了一个patch方便大家直接apply

到system/sepolicy/然后apply下面这个patch

add-selinux.patch

commit 7b459a68fe188b9f051850ac0629c868a31de2c2Author: Your Name Date:   Sun Oct 8 10:03:22 2023 +0800    add selinux for hal mytest        Change-Id: I5feeec2aa30cd7fe0d306922225d512c10a0725ediff --git a/prebuilts/api/33.0/private/hwservice_contexts b/prebuilts/api/33.0/private/hwservice_contextsindex 4a44dc58b..8092f0485 100644--- a/prebuilts/api/33.0/private/hwservice_contexts+++ b/prebuilts/api/33.0/private/hwservice_contexts@@ -6,6 +6,7 @@ android.frameworks.schedulerservice::ISchedulingPolicyService   u:object_r:fwk_s android.frameworks.sensorservice::ISensorManager                u:object_r:fwk_sensor_hwservice:s0 android.frameworks.stats::IStats                                u:object_r:fwk_stats_hwservice:s0 android.hardware.atrace::IAtraceDevice                          u:object_r:hal_atrace_hwservice:s0+android.hardware.mytest::IMyTest                                u:object_r:hal_mytest_hwservice:s0 android.hardware.audio.effect::IEffectsFactory                  u:object_r:hal_audio_hwservice:s0 android.hardware.audio::IDevicesFactory                         u:object_r:hal_audio_hwservice:s0 android.hardware.authsecret::IAuthSecret                        u:object_r:hal_authsecret_hwservice:s0diff --git a/prebuilts/api/33.0/private/service_contexts b/prebuilts/api/33.0/private/service_contextsindex 72fa16629..936638f18 100644--- a/prebuilts/api/33.0/private/service_contexts+++ b/prebuilts/api/33.0/private/service_contexts@@ -15,6 +15,7 @@ android.hardware.contexthub.IContextHub/default                      u:object_r: android.hardware.drm.IDrmFactory/clearkey                            u:object_r:hal_drm_service:s0 android.hardware.drm.ICryptoFactory/clearkey                         u:object_r:hal_drm_service:s0 android.hardware.dumpstate.IDumpstateDevice/default                  u:object_r:hal_dumpstate_service:s0+android.hardware.mytest.IMyTest/default                       u:object_r:hal_mytest_service:s0 android.hardware.gnss.IGnss/default                                  u:object_r:hal_gnss_service:s0 android.hardware.graphics.allocator.IAllocator/default               u:object_r:hal_graphics_allocator_service:s0 android.hardware.graphics.composer3.IComposer/default                u:object_r:hal_graphics_composer_service:s0diff --git a/private/hwservice_contexts b/private/hwservice_contextsindex 4a44dc58b..8092f0485 100644--- a/private/hwservice_contexts+++ b/private/hwservice_contexts@@ -6,6 +6,7 @@ android.frameworks.schedulerservice::ISchedulingPolicyService   u:object_r:fwk_s android.frameworks.sensorservice::ISensorManager                u:object_r:fwk_sensor_hwservice:s0 android.frameworks.stats::IStats                                u:object_r:fwk_stats_hwservice:s0 android.hardware.atrace::IAtraceDevice                          u:object_r:hal_atrace_hwservice:s0+android.hardware.mytest::IMyTest                                u:object_r:hal_mytest_hwservice:s0 android.hardware.audio.effect::IEffectsFactory                  u:object_r:hal_audio_hwservice:s0 android.hardware.audio::IDevicesFactory                         u:object_r:hal_audio_hwservice:s0 android.hardware.authsecret::IAuthSecret                        u:object_r:hal_authsecret_hwservice:s0diff --git a/private/service_contexts b/private/service_contextsindex 72fa16629..936638f18 100644--- a/private/service_contexts+++ b/private/service_contexts@@ -15,6 +15,7 @@ android.hardware.contexthub.IContextHub/default                      u:object_r: android.hardware.drm.IDrmFactory/clearkey                            u:object_r:hal_drm_service:s0 android.hardware.drm.ICryptoFactory/clearkey                         u:object_r:hal_drm_service:s0 android.hardware.dumpstate.IDumpstateDevice/default                  u:object_r:hal_dumpstate_service:s0+android.hardware.mytest.IMyTest/default                       u:object_r:hal_mytest_service:s0 android.hardware.gnss.IGnss/default                                  u:object_r:hal_gnss_service:s0 android.hardware.graphics.allocator.IAllocator/default               u:object_r:hal_graphics_allocator_service:s0 android.hardware.graphics.composer3.IComposer/default                u:object_r:hal_graphics_composer_service:s0diff --git a/vendor/file_contexts b/vendor/file_contextsindex 392a750fd..b87914600 100644--- a/vendor/file_contexts+++ b/vendor/file_contexts@@ -105,6 +105,7 @@ /(vendor|system/vendor)/bin/hw/wpa_supplicant                                 u:object_r:hal_wifi_supplicant_default_exec:s0 /(vendor|system/vendor)/bin/install-recovery\.sh                              u:object_r:vendor_install_recovery_exec:s0 /(vendor|system/vendor)/bin/vndservicemanager                                 u:object_r:vndservicemanager_exec:s0+/(vendor|system/vendor)/bin/hw/android\.hardware\.mytest\.example          u:object_r:hal_mytest_default_exec:s0  ############################# # Same process HALs installed by platform into /vendordiff --git a/vendor/hal-aidl-mytest.te b/vendor/hal-aidl-mytest.tenew file mode 100644index 000000000..378df3826--- /dev/null+++ b/vendor/hal-aidl-mytest.te@@ -0,0 +1,39 @@+# type hal_mytest, domain;+# type hal_mytest_service, vendor_service, service_manager_type;+# type hal_mytest_hwservice, hwservice_manager_type, protected_hwservice;+# type hal_mytest_default_exec, exec_type, vendor_file_type, file_type;+# init_daemon_domain(hal_mytest);++++# get_prop(hal_mytest, hwservicemanager_prop)+# add_hwservice(hal_mytest, hal_mytest_hwservice)+# hwbinder_use(hal_mytest);+++# allow platform_app hal_mytest_hwservice:hwservice_manager { find };+# allow platform_app hal_mytest:binder {call};+++hal_attribute(mytest);+type hal_mytest_default, domain, mlstrustedsubject;+hal_server_domain(hal_mytest_default, hal_mytest);+type hal_mytest_default_exec, exec_type, vendor_file_type, file_type;+init_daemon_domain(hal_mytest_default);++#Allow hwbinder call form hal client to server+binder_call(hal_mytest_client, hal_mytest_default_exec)++#add hwservice related rules+type hal_mytest_service, vendor_service, service_manager_type;+type hal_mytest_hwservice, hwservice_manager_type, protected_hwservice;+get_prop(hal_mytest, hwservicemanager_prop)+add_service(hal_mytest_default, hal_mytest_service)+add_hwservice(hal_mytest_server, hal_mytest_hwservice)+allow hal_mytest_client hal_mytest_hwservice:hwservice_manager find;+hal_client_domain(system_server, hal_mytest)+hwbinder_use(hal_mytest);++allow hal_mytest_default servicemanager:binder { call transfer };+allow {  platform_app shell } hal_mytest_hwservice:hwservice_manager { find };+allow {  platform_app shell } hal_mytest:binder {call};

8、编写一个测试模块,来测试一下aidl的hal是否正常运行

aidl目录下创建一个test_hal目录:

test_hal/|-- Android.bp`-- main.cpp

Android.bp

cc_binary {    name: "test-hal-mytest",    shared_libs: [        "android.hardware.mytest-V1-ndk",         "liblog",        "libbase",        "libcutils",        "libutils",        "libbinder_ndk",    ],    srcs: [        "main.cpp",    ],}

主要就是需要引入 “android.hardware.mytest-V1-ndk”, 这个依赖库

main.cpp

#define LOG_TAG "Test-HAL"#define LOG_NDEBUG 0#include #include #include #include #include #include using aidl::android::hardware::mytest::IMyTest;int main() {    printf("test hal mytest main 1\n");    std::shared_ptr service = IMyTest::fromBinder(ndk::SpAIBinder(AServiceManager_getService("android.hardware.mytest.IMyTest/default")));    printf("test hal mytest service = %p\n",service.get());    ALOGE("Test hal  MyTest");    if (service == nullptr) {        return -1;    }    ::aidl::android::hardware::mytest::MyTestObj obj;    service->test(&obj);    printf("test hal mytest main  test result  %s %d \n",obj.key.c_str(),obj.value);    fflush(stdout);    return EXIT_FAILURE;  // should not reach}

9、device下面加入相关的程序进入编译到整机

device/nubia/nx563j/device.mk文件中加入如下:

PRODUCT_PACKAGES += \    android.hardware.mytest \    android.hardware.mytest.example \    test-hal-mytest \

10、测试部分

测试方法

1、先看看是否mytest的hal服务是否开机自启动了

2、执行test-hal-mytest看看是否输出正常

本文章对应视频手把手教你学framework:

https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg

私聊作者+v(androidframework007)

点击这里 https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频:https://www.bilibili.com/video/BV1wc41117L4/

上一篇:【真机Bug】异步加载资源未完成访问单例导致资源创建失败

下一篇:采访服务器事件怎么写?