HIDL Hal 开发笔记10----添加硬件访问服务(Java 层调用 HIDL)

目录


|-----------------------------|
| 添加硬件访问服务(Java 层调用 HIDL) |

此前的代码中,我们仅生成了 hellohal 的C++层HAL代码,在 Framework 层是通过 JNI 的方式,调用 IHello.h 生成的getService()方法,进而从hwservicemanager中获取到 HelloService对应的 HIDL 服务实例。

c 复制代码
out$ find ./ -name "IHello.*"
./soong/.intermediates/vendor/henry/hardware/interfaces/hello_hidl/1.0/henry.hardware.hello_hidl@1.0_genc++_headers/gen/henry/hardware/hello_hidl/1.0/IHello.h.d
./soong/.intermediates/vendor/henry/hardware/interfaces/hello_hidl/1.0/henry.hardware.hello_hidl@1.0_genc++_headers/gen/henry/hardware/hello_hidl/1.0/IHello.h

本章我们将采用 Framework 层中更常用的Java HAL 方式直接获取 HelloService的 HIDL 服务,摒弃 JNI 层的调用链路,进一步加深对 HIDL HAL 的整体理解与实际应用。

以下所有代码均基于此前的工程代码进行改造,关于原有代码的实现细节,本文不再过多赘述。

一、生成IHello.java

打开文件 vendor/henry/hardware/interfaces/hello_hidl/1.0/Android.bp

确认文件是否有java封装配置

c 复制代码
hidl_interface {
    name: "henry.hardware.hello_hidl@1.0",
    root: "henry.hardware",
    system_ext_specific: true,
    srcs: [
        "IHello.hal",
    ],
    interfaces: [
        "android.hidl.base@1.0",
    ],
    gen_java: true, // ✅ 核心开关:开启自动生成Java层封装类
}

gen_java: true :必须加的配置,告诉 Soong 编译系统:为这个 HIDL 接口,自动生成 Java 层的所有封装类(IHello.java + 回调类 + 异常类);

此前这个配置已经加了,但是out目录并没有自动生成IHello.java相关文件,需要我们自己手动单编一下。

c 复制代码
source build/envsetup.sh
lunch 你的编译版本
mmm vendor/henry/hardware/interfaces/hello_hidl/1.0/ 

编译完成后进入out目录确认一下

c 复制代码
/out$ find ./ -name "IHello.*"
./soong/.intermediates/vendor/henry/hardware/interfaces/hello_hidl/1.0/henry.hardware.hello_hidl-V1.0-java_gen_java/gen/srcs/henry/hardware/hello_hidl/V1_0/IHello.java
./soong/.intermediates/vendor/henry/hardware/interfaces/hello_hidl/1.0/henry.hardware.hello_hidl-V1.0-java/android_common/javac/classes/henry/hardware/hello_hidl/V1_0/IHello.class
./soong/.intermediates/vendor/henry/hardware/interfaces/hello_hidl/1.0/henry.hardware.hello_hidl@1.0_genc++_headers/gen/henry/hardware/hello_hidl/1.0/IHello.h.d
./soong/.intermediates/vendor/henry/hardware/interfaces/hello_hidl/1.0/henry.hardware.hello_hidl@1.0_genc++_headers/gen/henry/hardware/hello_hidl/1.0/IHello.h
./soong/.intermediates/vendor/henry/hardware/interfaces/hello_hidl/1.0/henry.hardware.hello_hidl-V1.0-java-shallow/android_common/javac/classes/henry/hardware/hello_hidl/V1_0/IHello.class

二、删除所有 JNI 相关代码

c 复制代码
git checkout frameworks/base/services/core/jni/Android.bp
c 复制代码
git checkout frameworks/base/services/core/jni/onload.cpp
c 复制代码
rm frameworks/base/services/core/jni/com_android_server_HelloService.cpp

三、添加依赖

使framework核心模块能够正常引入IHello

c 复制代码
git diff frameworks/base/services/core/Android.bp 
diff --git a/frameworks/base/services/core/Android.bp b/frameworks/base/services/core/Android.bp
index 1c818c0981..934f51438c 100644
--- a/frameworks/base/services/core/Android.bp
+++ b/frameworks/base/services/core/Android.bp
@@ -155,6 +155,7 @@ java_library_static {
         "android.hardware.soundtrigger-V2.3-java",
         "android.hardware.power.stats-V1-java",
         "android.hidl.manager-V1.2-java",
+        "henry.hardware.hello_hidl-V1.0-java",
         "capture_state_listener-aidl-java",
         "icu4j_calendar_astronomer",
         "netd-client",
xuejie@vt-PowerEdge-R740:~/A11a133a12$ 

四、修改服务端HelloService

文件路径

c 复制代码
frameworks/base/services/core/java/com/android/server/HelloService.java

3.1 原代码

c 复制代码
package com.android.server;
  
import android.os.IHelloService;

// 硬件服务的服务端实现
public class HelloService extends IHelloService.Stub {

    public native void natvieWrite(String str);
    public native String nativeRead();

    public void write(String str) throws android.os.RemoteException  {
        natvieWrite(str);
    }

    public String read() throws android.os.RemoteException  {
        return nativeRead();
    }
}

3.2 修改后代码

删除native方法声明,引入IHello,直接获取服务调用hal接口

c 复制代码
package com.android.server;

import android.util.Log;
import henry.hardware.hello_hidl.V1_0.IHello;
import android.os.IHelloService;
import android.os.RemoteException;

// 硬件服务的服务端实现
public class HelloService extends IHelloService.Stub {
    private static final String TAG = "HelloService";
    private IHello mHelloHal;

    public HelloService() {
    }

    private void getHidlService() {
        if (mHelloHal == null) {
            try {
                mHelloHal = IHello.getService();
            } catch (RemoteException  e) {
                Log.e(TAG, "获取HIDL服务失败: 服务未注册");
            }
        }
    }

    public void write(String str) {
        getHidlService(); // 每次调用先检查并获取服务
        if (mHelloHal == null) {
            Log.e(TAG, "write: mHelloHal is null");
            return;
        }
        try {
            mHelloHal.write(str);
        } catch (RemoteException e) {
            Log.e(TAG, "write RemoteException");
            mHelloHal = null; // 异常时置空,下次调用重新获取
        }
    }

    public String read() {
        getHidlService();
        if (mHelloHal == null) return null;
        try {
            return mHelloHal.read();
        } catch (RemoteException e) {
            Log.e(TAG, "read RemoteException");
            mHelloHal = null;
            return null;
        }
    }
}

五、应用层调用

应用层代码无需修改,我这里是在settings其中的一个页面调用的

c 复制代码
Hello helloHal = (Hello)getSystemService(Context.HELLO_SERVICE);
try {
   helloHal.write("nihao");
    Log.d("HelloHal_test",helloHal.read());
} catch (Exception e) {
    e.printStackTrace();
}

六、 编译运行

相关推荐
数智工坊3 小时前
机器人运动控制:采样、优化与学习三大流派深度对比与实战
android·学习·机器人
故渊at5 小时前
第二板块:Android 四大组件标准化学理 | 第八篇:Service 后台执行实体与优先级
android·gitee·service·前台服务·后台服务
会Tk矩阵群控的小木5 小时前
安卓群控系统对于游戏工作室实战教程
android·运维·游戏·adb·开源软件·个人开发
qeen876 小时前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
故渊at6 小时前
第二板块:Android 四大组件标准化学理 | 第九篇:BroadcastReceiver 事件分发与有序广播
android·gitee·broadcast·广播·动态注册·静态注册
JohnnyDeng946 小时前
【Android】Room 数据库高级用法与性能调优:从查询瓶颈到毫秒级响应
android·性能优化·kotlin·room
zeqinjie6 小时前
Flutter 折叠屏 iPad / 宽屏适配实践
android·前端·flutter
ab_dg_dp6 小时前
Android 17+ 提取 AIDL 生成 Java 文件的实用脚本
android·java·python
Arrom7 小时前
DLNA 渲染端排障实战:从 20s 卡顿到 stale subscriber 的两周追凶之旅
android·java