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

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.xdnf.cn/news/19306.html

相关文章:

  • open webui源码分析12-Pipeline
  • 用docker安装rstudio-server
  • 【python开发123】三维地球应用开发方案
  • Adobe Acrobat 中通过 JavaScript 调用 Web 服务
  • ros、slam、激光雷达、自动驾驶相关学习内容和计划
  • 深度拆解判别式推荐大模型RankGPT!生成式精排落地提速94.8%,冷启动效果飙升,还解决了传统推荐3大痛点
  • Pointer--Learing MOOC-C语言第九周指针
  • “北店南下”热潮不减,企业赴港开拓业务如何站稳脚跟
  • springboot java开发的rocketmq 事务消息保证
  • SyncBack 安全备份: 加密文件名及文件内容, 防止黑客及未授权的访问
  • Ansible Playbook 实践
  • CPP学习之map和set
  • 99.数据大小端模式
  • KLARI-CORD5硬件应用:基于CAN总线的多通道电气测量与数据记录实战
  • Spring Boot自动装配机制的原理
  • SOME/IP-SD中”服务器服务组播端点”、“客户端服务组播端点”与“IPv4组播选项的区分
  • 面向企业级产品开发的自动化脚本实战
  • Java 获取淘宝关键词搜索(item_search)API 接口实战指南
  • 抖音电商首创最严珠宝玉石质检体系,推动行业规范与消费扩容
  • 拼多多商品信息批量获取及开放API接口调用指南
  • 使用Python脚本执行Git命令
  • vben admin5组件文档(豆包版)---VbenTree
  • 【C++】C++入门——(上)
  • 用docker实现Redis主从配置
  • Android14 init.qcom.usb.rc详解
  • 2025年渗透测试面试题总结-38(题目+回答)
  • WebRTC音频QoS方法五(音频变速算法之Expand算法实现)
  • 订餐后台管理系统 -day03 登录模块
  • Electron 项目来实现文件下载和上传功能(AI)
  • 前端网页源码模板 静态HTML源码网站