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

六、 编译运行

相关推荐
私人珍藏库5 分钟前
[Android] 亿连车机版V7.0.1
android·app·软件·车机
用户69371750013841 小时前
315曝光AI搜索问题:GEO技术靠内容投喂操控答案,新型营销操作全揭秘
android·前端·人工智能
进击的cc1 小时前
彻底搞懂 Binder:不止是 IPC,更是 Android 的灵魂
android·面试
段娇娇1 小时前
Android jetpack LiveData (三) 粘性数据(数据倒灌)问题分析及解决方案
android·android jetpack
用户2018792831672 小时前
TabLayout被ViewPager2遮盖部分导致Tab难选中
android
法欧特斯卡雷特2 小时前
Kotlin 2.3.20 现已发布,来看看!
android·前端·后端
闻哥2 小时前
深入理解 MySQL InnoDB Buffer Pool 的 LRU 冷热数据机制
android·java·jvm·spring boot·mysql·adb·面试
ii_best2 小时前
安卓/ios开发辅助软件按键精灵小精灵实现简单的UI多配置管理
android·ui·ios·自动化
码农xo2 小时前
android 设备实时传输相机采集的视频到电脑pc端 通过内网wifi 方案
android·数码相机·音视频
常利兵2 小时前
解锁Android的隐藏超链接:Deep Link与App Link探秘
android·gitee