MTK Android 12 环境中编译生成 NVRAM 相关 JAR 文件调用的完整步骤

在本文中,我将详细介绍如何在 MTK 方案 Android 12 环境中,从初始配置到生成 vendor.mediatek.hardware.nvram@1.0-java_intermediates/classes.jar 文件给应用调用INvram agent = INvram.getService();的完整过程。

最开始想解决这个问题的原由,是因为想在AS里调用 INvram agent = INvram.getService();,这个文件之前的版本是在, out\target\common\obj\JAVA_LIBRARIES\vendor.mediatek.hardware.nvram@1.0-java_intermediates\classes.jar ,但是搜遍了out目录下没有,所以打算研究一下怎么生成。

1. 初始配置

首先,系统 NVRAM 源码在 vendor/mediatek/proprietary/hardware/interfaces/nvram/1.0 文件夹下有一个基本的 Android.bp 文件来描述 NVRAM 的 HAL 接口,并启用 Java 生成:

// This file is autogenerated by hidl-gen -Landroidbp.

hidl_interface {
    name: "vendor.mediatek.hardware.nvram@1.0",
    root: "vendor.mediatek.hardware",
    srcs: [
        "INvram.hal",
    ],
    interfaces: [
        "android.hidl.base@1.0",
    ],
    gen_java: true,
}

2. 生成 Java 文件

使用 hidl-gen 工具生成 Java 文件 INvram.java

hidl-gen -o ./gen -Ljava -r vendor.mediatek.hardware:vendor/mediatek/proprietary/hardware/interfaces vendor.mediatek.hardware.nvram@1.0

执行上述命令后,生成的 Java 文件应位于 vendor/mediatek/proprietary/hardware/interfaces/nvram/1.0/gen/vendor/mediatek/hardware/nvram/V1_0 目录中。

3. 修改 Android.bp 文件

为确保生成的 Java 文件能够被打包成 JAR 文件,需要在 Android.bp 文件中添加 java_libraryjava_library_static 模块:

// 增加 java_library 的定义
java_library {
    name: "vendor.mediatek.hardware.nvram@1.0-java",
    srcs: [
        "gen/vendor/mediatek/hardware/nvram/V1_0/*.java",
    ],
    sdk_version: "system_current",
    static_libs: [
        "android.hidl.base-V1.0-java",
        "android.hidl.manager-V1.0-java",
    ],
}

// 增加 java_library_static 的定义
java_library_static {
    name: "vendor.mediatek.hardware.nvram@1.0-java-static",
    srcs: [
        "gen/vendor/mediatek/hardware/nvram/V1_0/*.java",
    ],
    sdk_version: "system_current",
    static_libs: [
        "android.hidl.base-V1.0-java-static",
        "android.hidl.manager-V1.0-java-static",
    ],
}

4. 编译

在修改完 Android.bp 文件后,清理编译环境并重新编译项目:

rm -rf out/target/common/obj/JAVA_LIBRARIES/vendor.mediatek.hardware.nvram@1.0-java*

make vendor.mediatek.hardware.nvram@1.0-java
make vendor.mediatek.hardware.nvram@1.0-java-static // 不用编这个也可

5. 生成的输出

编译成功后,检查生成的 JAR 文件:

ls out/target/common/obj/JAVA_LIBRARIES/vendor.mediatek.hardware.nvram@1.0-java_intermediates/classes.jar
ls out/soong/.intermediates/vendor/mediatek/proprietary/hardware/interfaces/nvram/1.0/vendor.mediatek.hardware.nvram@1.0-java

输出目录中应包含以下内容:

vendor.mediatek.hardware.nvram@1.0                 vendor.mediatek.hardware.nvram@1.0-inheritance-hierarchy
vendor.mediatek.hardware.nvram@1.0_genc++          vendor.mediatek.hardware.nvram@1.0-java(新增)
vendor.mediatek.hardware.nvram@1.0_genc++_headers  vendor.mediatek.hardware.nvram@1.0-java-static(新增)

遇到的问题及解决方案

问题1

编译出 vendor.mediatek.hardware.nvram@1.0-java_intermediates/classes.jar 后,放到 AS 准备调试接口时,遇到以下错误:

SNParamUtils.java:22: error: cannot access IHwInterface
            INvram agent = INvram.getService();
                                 ^
  class file for android.os.IHwInterface not found

提示找不到 IHwInterface.java。在 Android 8.1 中,该文件位于 hwbinder_intermediates 目录中,而在 Android 12 中则使用 framework-minus-apex_intermediates 中的 classes.jar

解决方法

最开始的解决办法是,将 framework-minus-apex_intermediates 中的 classes.jarvendor.mediatek.hardware.nvram@1.0-java_intermediates 中的 classes.jar 同时拷入到 AS 项目中。后来决定将这些类打包成一个 classes.jar,最终在 framework/base/Android.bp 增加一个名为 hwbinderjava_library

问题2

在编译 vendor.mediatek.hardware.nvram@1.0-java-static 时,遇到以下错误:

make vendor.mediatek.hardware.nvram@1.0-java-static
module vendor.mediatek.hardware.nvram@1.0-java-static missing dependencies: android.hidl.base-V1.0-java-static

提示缺少 android.hidl.base-V1.0-java-static 依赖项。

解决方法

确保在 Android.bp 文件中正确引用并添加 android.hidl.base-V1.0-java-static 模块:

java_library_static {
    name: "vendor.mediatek.hardware.nvram@1.0-java-static",
    srcs: [
        "gen/vendor/mediatek/hardware/nvram/V1_0/*.java",
    ],
    sdk_version: "system_current",
    static_libs: [
        "android.hidl.base-V1.0-java-static",
        "android.hidl.manager-V1.0-java-static",
    ],
}
问题3

编译 hwbinder 模块时,遇到依赖文件缺失问题:

java_library {
    name: "hwbinder",
    srcs: [
        "core/java/android/os/HidlSupport.java",
        "core/java/android/annotation/NonNull.java",
        "core/java/android/os/HwBinder.java",
        "core/java/android/os/HwBlob.java",
        "core/java/android/os/HwParcel.java",
        "core/java/android/os/IHwBinder.java",
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/util/AndroidException.java",
    ],
    sdk_version: "module_current", // 调整为 module_current
    dxflags: ["--core-library"],
    installable: false,
}

因为在编译名为 hwbinderjava_library 时,少了一些依赖文件导包,导致编译报错:

@NonNull
 ^
符号:   类 NonNull
位置: 类 RemoteException
frameworks/base/core/java/android/os/HwParcel.java:54: 错误: 找不到符号
@UnsupportedAppUsage
 ^
符号:   类 UnsupportedAppUsage
位置: 类 HwParcel
frameworks/base/core/java/android/os/HwParcel.java:141: 错误: 找不到符号
public native final void writeNativeHandle(@Nullable NativeHandle val);
                                            ^
符号:   类 Nullable
位置: 类 HwParcel
frameworks/base/core/java/android/os/HwParcel.java:314: 错误: 找不到符号
public final void writeNativeHandleVector(@NonNull ArrayList<NativeHandle> val) {
解决方法

找到这些文件,追加引用。假设 SystemApi.java 等文件位于 frameworks/libs/modules-utils/java/android/annotation/ 目录中,设置相对路径。在 frameworks/base/Android.bp 文件中定义 hwbinder 模块:

// 在 frameworks/base/Android.bp 文件中定义 hwbinder 模块

java_library {
    name: "hwbinder",
    srcs: [
        "core/java/android/os/HidlSupport.java",
        "core/java/android/annotation/NonNull.java",
        "core/java/android/os/HwBinder.java",
        "core/java/android/os/HwBlob.java",
        "core/java/android/os/HwParcel.java",
        "core/java/android/os/IHwBinder.java",
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/util/AndroidException.java",
        // 添加对 android.annotation 包的依赖
        "../../libs/modules-utils/java/android/annotation/SystemApi.java",
        "../../libs/modules-utils/java/android/annotation/NonNull.java",
        "../../libs/modules-utils/java/android/annotation/Nullable.java",
        "../../libs/modules-utils/java/android/compat/annotation/UnsupportedAppUsage.java",
    ],
    sdk_version: "module_current",
    dxflags: ["--core-library"],
    installable: false,
}

继续编译,出现问题 4。

问题4

在编译过程中,遇到路径引用错误:

Path is outside directory: ../../libs/modules-utils/java/android/annotation/SystemApi.java

提示引用路径错误,路径不能在模块目录之外。

解决方法

使用 filegroup 来定义文件集合并引用这些文件:

  1. frameworks/libs/modules-utils 中创建或更新 Android.bp

    filegroup {
        name: "modules-utils-annotation",
        srcs: [
            "java/android/annotation/SystemApi.java",
            "java/android/annotation/NonNull.java",
            "java/android/annotation/Nullable.java",
            "java/android/annotation/IntDef.java",
        ],
        visibility: ["//frameworks/base"], // 设置可见性
    }
    
  2. 更新 hwbinder 模块

    frameworks/base/Android.bp 文件中定义 hwbinder 模块:

    java_library {
        name: "hwbinder",
        srcs: [
            "core/java/android/os/HidlSupport.java",
            "core/java/android/os/HwBinder.java",
            "core/java/android/os/HwBlob.java",
            "core/java/android/os/HwParcel.java",
            "core/java/android/os/IHwBinder.java",
            "core/java/android/os/IHwInterface.java",
            "core/java/android/os/DeadObjectException.java",
            "core/java/android/os/DeadSystemException.java",
            "core/java/android/os/RemoteException.java",
            "core/java/android/util/AndroidException.java",
            ":modules-utils-annotation", // 引用 filegroup
        ],
        sdk_version: "module_current",
        dxflags: ["--core-library"],
        installable: false,
    }
    

继续编译,出现问题 5。

问题5

在编译过程中,遇到以下错误:

frameworks/base/core/java/android/os/HwBinder.java:20: 错误: 程序包 android.compat.annotation 不存在
import android.compat.annotation.UnsupportedAppUsage;

还需要创建一个包含 UnsupportedAppUsagefilegroup 并将其添加到 hwbinder 模块中来解决这个问题。但是文件位于 tools/platform-compat/java/android/compat/annotation/UnsupportedAppUsage.java,只能在 tools/platform-compat/Android.mk 中增加一个名为 modules-utils-compat-annotationjava_library

解决方法
+++ b/tools/platform-compat/Android.mk

# 在 tools/platform-compat/Android.mk 文件中增加
LOCAL_PATH := $(call my-dir)

# 定义一个文件组
include $(CLEAR_VARS)
LOCAL_MODULE := modules-utils-compat-annotation
LOCAL_SRC_FILES := \
    java/android/compat/annotation/UnsupportedAppUsage.java
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
include $(BUILD_JAVA_LIBRARY)
问题6

在编译过程中,遇到以下错误:

tools/platform-compat/Android.mk: error: modules-utils-compat-annotation: Invalid LOCAL_SDK_VERSION 'module_current' Choices are: 10 11 12 13 14 15 16 17 18 19 20 21 22 23 system_23 24 25 26 27 28 system_28 29 system_29 test_29 30 system_30 test_30 31 system_31 test_31 4 5 6 7 8 9 core_current current system_current test_current 

提示 LOCAL_SDK_VERSION 设置无效。

解决方法

确保在 Android.mk 文件中使用有效的 LOCAL_SDK_VERSION。例如,可以使用 system_current 或其他有效值:

  1. 更新 Android.mk 文件

    # 在 tools/platform-compat/Android.mk 文件中
    
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := modules-utils-compat-annotation
    LOCAL_SRC_FILES := \
        java/android/compat/annotation/UnsupportedAppUsage.java
    LOCAL_MODULE_CLASS := JAVA_LIBRARIES
    LOCAL_SDK_VERSION := system_current
    include $(BUILD_JAVA_LIBRARY)
    

确保依赖模块的 sdk_version 一致,检查 modules-utils-compat-annotationhwbinder 模块的 Android.bp 文件,确保它们的 sdk_versionhwbinder 一致。

问题7

在编译过程中遇到了一些问题,最终决定不使用 tools/platform-compat/Android.mk 添加 java_library,而是引用现有的库。

解决方法
// 在 frameworks/base/Android.bp 文件中定义 hwbinder 模块

java_library {
    name: "hwbinder",
    srcs: [
        "core/java/android/os/HidlSupport.java",
        "core/java/android/os/HwBinder.java",
        "core/java/android/os/HwBlob.java",
        "core/java/android/os/HwParcel.java",
        "core/java/android/os/IHwBinder.java",
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/util/AndroidException.java",
        ":modules-utils-annotation", // 引用 filegroup
        // ":modules-utils-compat-annotation", // 引用新的 filegroup
    ],
    libs: [
        // 引用新的解决 UnsupportedAppUsage.java 报错问题
        "app-compat-annotations",
        "framework-updatable-stubs-module_libs_api",
        "unsupportedappusage",
    ],
    sdk_version: "module_current",
    dxflags: ["--core-library"],
    installable: false,
}
问题8

在调用 HAL 服务时遇到 NoSuchElementException 错误:

java.util.NoSuchElementException
    at android.os.HwBinder.getService(Native Method)
    at android.os.HwBinder.getService(HwBinder.java:81)
    at vendor.mediatek.hardware.nvram.V1_0.INvram.getService(INvram.java:132)

提示未找到服务。

解决方法

单独编译了这些 JAR,放到 AS,但运行的系统没有更新到最新已包含这些 JAR 的固件系统,所以需要将系统升级到最新的固件。

总结

通过正确配置 Android.bp 文件,添加必要的依赖项,并清理和重新编译项目,成功生成了 vendor.mediatek.hardware.nvram@1.0-java_intermediates/classes.jar 文件。这个文件可以提供给应用程序使用,从而实现与 NVRAM 相关的功能调用。这篇文章详细记录了从问题发现到解决的完整过程,希望对在 MTK Android 12 环境中进行类似开发的兄弟萌有所帮助。如果有更多问题,欢迎交流讨论。

  • 31
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android框架,NVRAM(非易失性随机存储器)被用于存储系统相关的配置和参数,如无线通信模块的MAC地址、IMEI号码等。NVRAM的读写在Android设备的系统级别发挥重要作用。 首先,NVRAM读取功能在Android框架由系统服务提供,通过封装底层的硬件接口和驱动程序来实现。Android的系统服务负责与硬件之间的通信,从NVRAM读取所需的参数。在读取过程,通过定义和使用适当的API,应用程序或系统组件可以请求读取特定的NVRAM值,以进行相关的操作和功能。 其次,NVRAM的写入功能也是由系统服务提供的。当应用程序或系统组件需要修改某个NVRAM参数时,可以通过调用相应的API来实现。系统服务将接收到的修改请求转发给硬件接口和驱动程序,然后将新值写入NVRAM。这样,NVRAM对应的参数将被更新,以满足新的需求。 在Android框架,NVRAM读写功能的正确实现对于系统的正常运行非常重要。它确保各种系统组件可以正确访问配置和参数信息,并确保设备在启动时能够正确初始化。同时,NVRAM的读写操作需要受到适当的权限控制,只有具备足够权限的应用程序或系统组件才能进行相关的操作。 综上所述,Android框架的NVRAM读写功能通过系统服务提供,并且在系统级别发挥重要作用。这种功能确保了系统配置和参数的正确访问和修改,从而保障设备的正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一歲抬頭

点赞1元,收藏免费,打赏随意。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值