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 小时前
绘制K线第三章:拖拽功能实现
android·前端·ios
我命由我123453 小时前
Android 项目路径包含非 ASCII 字符问题:Your project path contains non-ASCII characters
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
wszy18094 小时前
rn_for_openharmony_空状态与加载状态:别让用户对着白屏发呆
android·javascript·react native·react.js·harmonyos
城东米粉儿4 小时前
JobScheduler 相关笔记
android
城东米粉儿4 小时前
android 耗电优化 笔记
android
张小潇4 小时前
AOSP15的Zygote启动流程源码分析
android
毕设源码-钟学长4 小时前
【开题答辩全过程】以 基于安卓的医疗健康查询系统为例,包含答辩的问题和答案
android
归真仙人4 小时前
【UE】UMG安卓相关问题
android·ue5·游戏引擎·ue4·虚幻·unreal engine