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();
}

六、 编译运行

相关推荐
传奇开心果编程38 分钟前
【Jetpack Compose基础语法学与练】第8课 rememberSaveable,页面旋转/系统重建保留状态
android·学习·ui·kotlin·android jetpack
>Andre<1 小时前
UFS5.0标准中文全译·卷一:范围、术语与架构
android·linux·嵌入式硬件
事圆则缓2 小时前
Java 8 Lambda、Stream、Optional 与 Android 边界:从回调语法到运行时兼容
android·java
mmsx2 小时前
Android 地图十万要素不卡顿:空间网格 + 渐进式加载的移动端实践
android·大数据·opengl
Godikov3 小时前
Android 工业终端保活实战:前台服务 + 开机自启 + 更新自启的三重保障
android
字节暗面4 小时前
SO加固强度怎么量化?腾讯ACE与FairGuard静态分析实测
android·逆向
终端安全笔记5 小时前
描述文件、企业证书、MDM 不是三个名字,是三层
android·ios·智能手机
字节暗面6 小时前
一次游戏安全SO静态分析记录:腾讯ACE与FairGuard加固强度对比
android·逆向工程·游戏加固
传奇开心果编程6 小时前
【Jetpack Compose基础语法学与练】第9课 SideEffect副作用 + LaunchedEffect,处理异步任务和生命周期
android·学习·ui·kotlin·android jetpack
2401_833269308 小时前
RecyclerView多布局详解
android