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

六、 编译运行

相关推荐
alexhilton9 小时前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
冬奇Lab12 小时前
InputManagerService:输入事件分发与ANR机制
android·源码阅读
张小潇15 小时前
AOSP15 Input专题InputManager源码分析
android·操作系统
RdoZam17 小时前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
奥陌陌1 天前
android 打印函数调用堆栈
android
用户985120035831 天前
Compose Navigation 3 深度解析(二):基础用法
android·android jetpack
恋猫de小郭1 天前
Android 官方正式官宣 AI 支持 AppFunctions ,Android 官方 MCP 和系统级 OpenClaw 雏形
android·前端·flutter
黄林晴1 天前
Android 17 Beta 2,隐私这把锁又拧紧了
android
Kapaseker1 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin
bqliang1 天前
Compose 媒体查询 (Media Query API) 🖱️👇🕹️
android·android jetpack