当前位置: 首页 > news >正文

Hal aidl 模板

目录

背景:在AOSP14,模拟器下编写

1. 创建aidl目录

2. 创建对应的aidl文件

3.编写aidl Android.bp

4. 编译aidl

5. 编写aidl服务端

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

8. 编写SELinux权限

8.1添加接口SE类型

8.2添加可执行程序SE类型

8.3定义这些类型并添加策略

9. 将模块加入到整机编译

10. 使用testcmd测试

11. 编写App进行测试


背景:在AOSP14,模拟器下编写

source build/envsetup.sh

lunch sdk_phone64_x86_64-trunk_staging-eng

1. 创建aidl目录

mkdir -p hardware/interfaces/mycmd/aidl

cd hardware/interfaces/mycmd/aidl

mkdir -p android/hardware/mycmd/

android/hardware/mycmd/目录其实就是包名,即android.hardware.mycmd

2. 创建对应的aidl文件

android/
└── hardware
    └── mycmd
        ├── IMyCmd.aidl
        └── MyCmdObj.aidl

IMyCmd.aidl

package android.hardware.mycmd;
import android.hardware.mycmd.MyCmdObj;@VintfStability
interface IMyCmd {int exeCmd(in MyCmdObj cmd);
}

MyCmdObj.aidl

package android.hardware.mycmd;
@VintfStabilityparcelable MyCmdObj {String cmd;
}

3.编写aidl Android.bp

touch hardware/interfaces/mycmd/aidl/Android.bp

Android.bp

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

4. 编译aidl

cd hardware/interfaces/mycmd/aidl/

mm -j12

如果出现以下错误,先执行m android.hardware.mycmd-update-api,再重新编译

编译完成后生成如下目录

└── aidl
    ├── aidl_api
    │   └── android.hardware.mycmd
    │       └── current
    │           └── android
    │               └── hardware
    │                   └── mycmd
    │                       ├── IMyCmd.aidl
    │                       └── MyCmdObj.aidl
    ├── android
    │   └── hardware
    │       └── mycmd
    │           ├── IMyCmd.aidl
    │           └── MyCmdObj.aidl
    ├── Android.bp

并且生成相应的库,目录在out下out/soong/.intermediates/hardware/interfaces/mycmd/aidl

包括Java和NDK的接口文件和库文件

5. 编写aidl服务端

mkdir hardware/interfaces/mycmd/aidl/default/

先创建好对应的文件

default/
├── Android.bp
├── android.hardware.mycmd.rc
├── main.cpp
├── mycmd-default.xml
├── MyCmdImpl.cpp
└── MyCmdImpl.h

Android.bp

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

android.hardware.mycmd.rc

service vendor.mycmd-default /vendor/bin/hw/android.hardware.mycmd.serviceclass haluser rootgroup root

MyCmdImpl.cpp

#define LOG_TAG "MyCmdImpl"
#define LOG_NDEBUG 0#include "MyCmdImpl.h"#include <log/log.h>
#include <android-base/logging.h>#include <stdio.h>namespace aidl::android::hardware::mycmd {::ndk::ScopedAStatus MyCmdImpl::exeCmd(const ::aidl::android::hardware::mycmd::MyCmdObj &obj, int * _aidl_return) {*_aidl_return = 1;LOG(INFO) << " MyCmdImpl::eceCmd " << obj.cmd.c_str();return ::ndk::ScopedAStatus::ok();
}}  // namespace aidl::android::hardware::mycmd

MyCmdImpl.h

#ifndef ANDROID_HARDWARE_MYCMDIMPL_H
#define ANDROID_HARDWARE_MYCMDIMPL_H#include <aidl/android/hardware/mycmd/BnMyCmd.h>namespace aidl::android::hardware::mycmd {class MyCmdImpl : public BnMyCmd {public:::ndk::ScopedAStatus exeCmd(const ::aidl::android::hardware::mycmd::MyCmdObj &obj, int * _aidl_return) override;};}  // namespace aidl::android::hardware::mycmd#endif

main.cpp

#include "MyCmdImpl.h"
#define LOG_TAG "MyCmdImpl"
#define LOG_NDEBUG 0
#include <iostream>#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>#include <stdio.h>using aidl::android::hardware::mycmd::MyCmdImpl;int main(){ABinderProcess_setThreadPoolMaxThreadCount(0);std::shared_ptr<MyCmdImpl> test = ::ndk::SharedRefBase::make<MyCmdImpl>();const std::string instance = std::string() + MyCmdImpl::descriptor + "/default";LOG(INFO) << "MyCmdImpl instance " << instance.c_str();binder_status_t status = AServiceManager_addService(test->asBinder().get(), instance.c_str());CHECK_EQ(status, STATUS_OK);LOG(INFO) << "MyCmdImpl status " << status;ABinderProcess_joinThreadPool();return EXIT_FAILURE;
}

mycmd-default.xml

<manifest version="1.0" type="device"><hal format="aidl"><name>android.hardware.mycmd</name><version>1</version><interface><name>IMyCmd</name><instance>default</instance></interface></hal>
</manifest>

编译server端

cd hardware/interfaces/mycmd/aidl/default

mm -j12

编译完成后生成如下文件

out/target/product/emu64x/vendor/etc/vintf/manifest/mycmd-default.xml

out/target/product/emu64x/vendor/etc/init/android.hardware.mycmd.rc

out/target/product/emu64x/vendor/bin/hw/android.hardware.mycmd.service

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

cd hardware/interfaces/compatibility_matrices

加到最新的一个文件中

    <hal format="aidl"><name>android.hardware.mycmd</name><version>1</version><interface><name>IMyCmd</name><instance>default</instance></interface></hal>

7. 编写测试程序

mkdir hardware/interfaces/mycmd/aidl/testcmd

testcmd/
├── Android.bp
└── main.cpp

Android.bp

cc_binary {name: "testcmd",shared_libs: ["android.hardware.mycmd-V1-ndk","liblog","libbase","libcutils","libutils","libbinder_ndk",],srcs: ["main.cpp",],vendor: true,
}

main.cpp

#define LOG_TAG "Test-HAL"
#define LOG_NDEBUG 0
#include <iostream>#include <log/log.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <aidl/android/hardware/mycmd/IMyCmd.h>
#include <android-base/logging.h>#include <stdio.h>
using aidl::android::hardware::mycmd::IMyCmd;int main() {LOG(INFO) << "hal test mycmd main";std::shared_ptr<IMyCmd> service = IMyCmd::fromBinder(ndk::SpAIBinder(AServiceManager_getService("android.hardware.mycmd.IMyCmd/default")));LOG(INFO) << "my service";if(service == nullptr){LOG(INFO) << "service is null";return -1;}int result = 0;::aidl::android::hardware::mycmd::MyCmdObj obj;obj.cmd = "logcat";service->exeCmd(obj, &result);LOG(INFO) << "return value " << result;return EXIT_FAILURE;
}

8. 编写SELinux权限

cd device/generic/goldfish/sepolicy/vendor/

8.1添加接口SE类型

service_contexts

android.hardware.mycmd.IMyCmd/default                               u:object_r:hal_mycmd_service:s0

hwservice_contexts

android.hardware.mycmd::IMyCmd                        u:object_r:hal_mycmd_hwservice:s0

8.2添加可执行程序SE类型

file_contexts

/(vendor|system/vendor)/bin/hw/android\.hardware\.mycmd\.service                 u:object_r:hal_mycmd_server_exec:s0
/(vendor|system/vendor)/bin/testcmd                                              u:object_r:hal_mycmd_client_exec:s0

8.3定义这些类型并添加策略

hal_mycmd_server.te

type hal_mycmd_server, domain, mlstrustedsubject;
type hal_mycmd_server_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_mycmd_server);type hal_mycmd_client, domain, mlstrustedsubject;
type hal_mycmd_client_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_mycmd_client);binder_call(hal_mycmd_client, hal_mycmd_server)type hal_mycmd_service, service_manager_type;
type hal_mycmd_hwservice, hwservice_manager_type, protected_hwservice;add_service(hal_mycmd_server, hal_mycmd_service)
add_hwservice(hal_mycmd_server, hal_mycmd_hwservice)allow hal_mycmd_client hal_mycmd_hwservice:hwservice_manager find;allow hal_mycmd_server servicemanager:binder {call transfer };allow system_app hal_mycmd_server:binder { call };

9. 将模块加入到整机编译

vi device/generic/goldfish/board/emu64x/details.mk

PRODUCT_PACKAGES += \android.hardware.mycmd \android.hardware.mycmd.service \testcmd

10. 使用testcmd测试

08-29 17:17:33.582  2237  2237 I Test-HAL: hal test mycmd main
08-29 17:17:33.584  2237  2237 I Test-HAL: my service
08-29 17:17:33.584   318   318 I MyCmdImpl:  MyCmdImpl::exeCmd logcat
08-29 17:17:33.584  2237  2237 I Test-HAL: return value 1

11. 编写App进行测试

将out/soong/.intermediates/hardware/interfaces/mycmd/aidl/android.hardware.mycmd-V1-java/android_common/javac/android.hardware.mycmd-V1-java.jar拷贝到工程app/libs/下

build.gradle.kts中添加

implementation(files("libs/android.hardware.mycmd-V1-java.jar")

编写Java测试代码

    private void runServiceCmd(){IBinder binder = getService("android.hardware.mycmd.IMyCmd/default");IMyCmd test =  IMyCmd.Stub.asInterface(binder);Log.d(TAG, "binder: " + test);try {MyCmdObj obj = new MyCmdObj();obj.cmd = "logcat";int result = test.exeCmd(obj);Log.d(TAG, "Result message: " + result);} catch (Exception e) {e.printStackTrace();}}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;}}

测试结果

08-29 18:27:45.320  2285  2285 D CCDEBUG : binder: android.hardware.mycmd.IMyCmd$Stub$Proxy@319fd6
08-29 18:27:45.321   318   318 I MyCmdImpl:  MyCmdImpl::eceCmd logcat
08-29 18:27:45.323  2285  2285 D CCDEBUG : Result message: 1

http://www.dtcms.com/a/357470.html

相关文章:

  • Django开发规范:构建可维护的AWS资源管理应用
  • 第八章 惊喜01 测试筹备会
  • 【Flask】测试平台开发,产品管理实现编辑功能-第六篇
  • 对接连连支付(七)-- 退款查询
  • CSS设置滚动条显示时机及样式
  • R 语言 + 卒中 Meta 分析(续):机器学习 Meta 与结构方程 Meta 完整实现
  • STM32之IIC详解
  • GY-BMP280压强传感器完整工程stm32控制
  • 嵌入式滤波算法模块
  • 换公司如何快速切入软件项目工程
  • vant Overlay 遮罩层内元素无法滚动解决方案
  • 命令扩展与重定向
  • 【完整源码+数据集+部署教程】硬币分类与识别系统源码和数据集:改进yolo11-SWC
  • 【序列晋升】20 Spring Cloud Function 函数即服务(FaaS)
  • 明远智睿 RK3568 核心板:以硬核性能解锁多领域应用新可能
  • java_web 日志配置
  • KNN算法(K近邻算法)
  • leetcode 191 位1的个数
  • Maven 从 0 到 1:安装、配置与依赖管理一站式指南
  • Ubuntu下的压缩及解压缩
  • 基于SpringBoot的高校科研项目管理系统【2026最新】
  • 《生成式AI消费级应用Top 100——第五版》| a16z
  • Redis-分布式缓存
  • LBM——大型行为模型助力波士顿人形Atlas完成多任务灵巧操作:CLIP编码图像与语义,之后DiT去噪扩散生成动作
  • 中级统计师-统计实务-第二章 统计调查设计
  • 鸿蒙FA/PA架构:打破设备孤岛的技术密钥
  • PHP的md5()函数分析
  • Java 8核心特性详解:从Lambda到Stream的革命性升级
  • B树的概述以及插入逻辑
  • 淘宝四个月造了一个超越美团的“美团”