android 12 的 aidl for 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;@VintfStability
interface 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 <aidl/android/hardware/test/BnTest.h>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 <utils/Log.h>
#include <iostream>
#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 <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include "Test.h"using aidl::android::hardware::test::Test;int main() {ABinderProcess_setThreadPoolMaxThreadCount(0); ABinderProcess_startThreadPool();std::shared_ptr<Test> test = ndk::SharedRefBase::make<Test>();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-serviceinterface aidl android.hardware.test.ITest/defaultclass haluser systemgroup system

9. manifest

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

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

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

<hal format="aidl" optional="true"><name>android.hardware.test</name><version>1</version><interface><name>ITest</name><instance>default</instance></interface>
</hal>

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 上跑通了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/915656.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/915656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全渗透攻击案例实战:某公司内网为目标的渗透测试全过程

目录一、案例背景二、目标分析&#xff08;信息收集阶段&#xff09;&#x1f310; 外部信息搜集&#x1f9e0; 指纹识别和端口扫描三、攻击流程&#xff08;渗透测试全过程&#xff09;&#x1f3af; 步骤1&#xff1a;Web漏洞利用 —— 泛微OA远程命令执行漏洞&#xff08;CV…

AI视频-剧本篇学习笔记

1.提示词万能框架是什么:ai扮演的角色做什么&#xff1a;解决什么问题怎么做&#xff1a;标准2、剧本模版假设你是一位拥有30年电影拍摄经验的世界顶级导演&#xff0c;拥有丰富的电影拍摄经验和高超的电影拍摄技术&#xff0c;同时也擅长各种影片的剧本创作。我需要你仔细阅读…

A316-HF-DAC-V1:专业USB HiFi音频解码器评估板技术解析

引言 随着高解析度音频的普及&#xff0c;对高品质音频解码设备的需求日益增长。本文将介绍一款专为USB HiFi音频解码器设计的专业评估板——A316-HF-DAC-V1&#xff0c;这是一款基于XMOS XU316技术的高性能音频解码评估平台。产品概述 A316-HF-DAC-V1是一款专业的USB HiFi音频…

超低延迟RTSP播放器在工业机器人远程控制中的应用探索

技术背景 在智能制造高速发展的今天&#xff0c;工业机器人已经从单一的生产作业工具&#xff0c;转变为协作化、智能化的生产伙伴。无论是高精度的多关节机械臂、自主导航的移动机器人&#xff0c;还是与人协同工作的协作机器人&#xff0c;都越来越多地被应用于智能工厂、仓…

Elasticsearch Java 8.x 的聚合 API 及子聚合的用法

背景 Elasticsearch 版本发布的很勤&#xff0c; API 客户端的用法各个版本之间差异也是很大。尤其是 Elasticsearch 8.x 版本直接废弃了 RestHighLevelClient 对象。 Query 和 Aggregation 的 Builder 的用法也有变化。 本文记录项目升级 Elasticsearch API 到 8.x 版本时聚合…

Dify功能熟悉

Dify功能熟悉 文章目录Dify功能熟悉一、介绍1.1 快速开始1.2 官方文档二、workflow2.1 开始和结束2.2 简单示例三、节点3.1 节点一览表3.2 节点-----开始3.3 节点-----LLM3.4 知识检索&#xff08;增强回答准确性&#xff09;3.5 Agent智能体3.6 问题分类器3.7 http四、工具&am…

app引导页设计要点与交互细节详解

在移动应用的设计中&#xff0c;用户第一次打开APP时看到的往往就是app引导页。它不仅是品牌与用户接触的第一道界面&#xff0c;也是决定用户是否愿意继续探索的关键入口。一个设计合理、信息传达清晰的app引导页&#xff0c;能够帮助产品建立专业感与品牌价值&#xff0c;同时…

香港服务器SSH安全加固方案与密钥认证实践

香港服务器SSH安全加固方案与密钥认证实践在数字化时代&#xff0c;服务器安全成为企业不可忽视的重要议题。香港服务器因其地理位置和网络自由优势备受青睐&#xff0c;但同时也面临各种网络安全威胁。本文将深入探讨香港服务器SSH安全加固的核心方案&#xff0c;重点解析密钥…

Python的界面美化库 QDarkStyleSheet

Python的界面美化库 QDarkStyleSheet1、官网先看效果2、github地址3、动态切换主题用法效果代码1、官网先看效果 2、github地址 https://github.com/ColinDuquesnoy/QDarkStyleSheet?tabreadme-ov-file https://qdarkstylesheet.readthedocs.io/en/latest/screenshots.html …

同步本地文件到服务器上的Docker容器

同步本地文件到服务器上的Docker容器 要将本地文件同步到服务器上的Docker容器中&#xff0c;有几种常用方法&#xff1a; 1. 使用 docker cp 命令 # 将本地文件复制到运行中的容器 docker cp /本地/文件/路径 容器名或ID:/容器内/路径# 示例 docker cp ./app.py mycontainer:/…

[学习] 笛卡尔坐标系的任意移动与旋转详解

笛卡尔坐标系的任意移动与旋转详解 文章目录笛卡尔坐标系的任意移动与旋转详解**1. 笛卡尔坐标系基础****2. 坐标变换原理****2.1 平移变换****2.2 旋转变换****3. 组合变换**Python仿真与动态展示**动画说明**&#xff1a;**关键数学原理**&#xff1a;1. 笛卡尔坐标系基础 笛…

论文笔记:Parameter Competition Balancing for Model Merging

neurips 20241 intro近年来&#xff0c;模型融合&#xff08;model merging&#xff09;技术迅速发展&#xff0c;使得可以将多个分别针对不同任务微调后的模型直接集成为一个统一模型&#xff0c;从而实现多任务处理能力&#xff0c;而无需重新访问原始训练数据。然而&#xf…

逆向难度真相:仅用IDA静态分析的极限挑战

逆向难度真相&#xff1a;仅用IDA静态分析的极限挑战 纯IDA逆向难度重排&#xff08;从难到易&#xff09; Python > Go > Java > E语言 > CPython (地狱级难度) IDA困境&#xff1a; 主逻辑完全封装在PYZ/PYC资源中&#xff0c;IDA无法解析字节码结构字符串表只显…

vxe-table 通过配置 ajax 方式自动请求数据,适用于简单场景的列表

vxe-table 通过配置 ajax 方式自动请求数据&#xff0c;适用于简单场景的列表 当系统中很多页面都是简单列表时&#xff0c;每次都要手动去请求接口后再赋值&#xff0c;过程就会比较冗余繁琐。解决方式一般就是将封装一下。本章的方式是通过 vxe-grid 配置 ajax 来实现自动请求…

Zabbix 企业级分布式监控系统深度解析

一、监控系统核心认知1.1 监控的本质与价值监控&#xff08;Monitoring&#xff09;的核心是 “检测与预防”&#xff0c;在 IT 运维中占据约 30% 的权重。其核心价值体现在&#xff1a;风险预判&#xff1a;通过实时监测指标异常&#xff0c;提前发现潜在故障&#xff08;如服…

使用 .NET 6.0 的简单 WebSocket 客户端和服务器应用程序

几个月前&#xff0c;有同事来找我&#xff0c;问能否用 .NET 创建一个简单的 WebSocket 服务器&#xff08;以及之后的客户端&#xff09;。据我了解&#xff0c;他想用它来控制对方电脑上的进程。或许对其他人也有用&#xff0c;所以我把它发布在这里。让我们从服务器开始。我…

【ASP.NET Core】ASP.NET Core中Redis分布式缓存的应用

系列文章目录 链接: 【ASP.NET Core】REST与RESTful详解&#xff0c;从理论到实现 链接: 【ASP.NET Core】深入理解Controller的工作机制 链接: 【ASP.NET Core】内存缓存&#xff08;MemoryCache&#xff09;原理、应用及常见问题解析 文章目录系列文章目录前言一、Redis1.1 …

5.6 指令流水线 (答案见原书 P267)

5.6 指令流水线 (答案见原书 P267) 01. 下列关于流水CPU基本概念的描述中&#xff0c;正确的是&#xff08; D &#xff09;。 题目原文 下列关于流水CPU基本概念的描述中&#xff0c;正确的是&#xff08; &#xff09;。 A. 流水CPU是以空间并行性为原理构造的处理器 B. 流水…

NIO简单介绍和运用

NIO简单介 NIO 非阻塞IO模型&#xff0c;基于缓冲区(Buffer)读写数据&#xff0c;读写后的数据通过通道(Channel)进行传输&#xff0c;采用选择器(Selector)管理多个通道从而实现高并发。 核心组件&#xff1a;1. Buffer 为一个内存数组作为数据容器&#xff0c;代替传统的Inpu…

LeetCode 658.找到K个最接近的元素

给定一个 排序好 的数组 arr &#xff0c;两个整数 k 和 x &#xff0c;从数组中找到最靠近 x&#xff08;两数之差最小&#xff09;的 k 个数。返回的结果必须要是按升序排好的。 整数 a 比整数 b 更接近 x 需要满足&#xff1a; |a - x| < |b - x| 或者 |a - x| |b - x| …