Android HAL深入探索(5): 调试HAL报错与解决方案

简介: Android HAL深入探索(5): 调试HAL报错与解决方案

在我们学习Android HAL开发时,可能会遇到一些编译或运行时的错误,这些错误可能会影响探索脚本。为了有效地定位和解决这些错误,需要了解Android HAL的架构、工具和方法。本文将介绍一些我自己在学习Android HAL的调试技巧和常见错误的解决方案,希望能帮助到大家。

网上其他文章从不会告诉你 完整的调试过程, 最多只会告诉你结果 看着简单的内容 等你亲自尝试就知道有多少坑。本文只记录不到一半我遇到的问题,有些不是很通用 我就懒得记录了。

如果有错误 请指正,后面HAL相关的调试和解决方案将更新在此。有任何问题 欢迎咨询~

系列文章:

Android HAL深入探索(1): 架构概述

Android HAL深入探索(2): 传统HAL与文件加解密模拟

Android HAL深入探索(3): HIDL Passthrough模式与串口数据回调模拟

Android HAL深入探索(4): HIDL Binderized模式与CAN数据回调模拟

Android HAL深入探索(5): 调试HAL报错与解决方案

问题1:declares types rather than the expected interface type ‘ICanBus’

当尝试编译一个名为android.hardware.can_bus@1.0的HAL时,可能会遇到以下错误:

declares types rather than the expected interface type 'ICanBus'
ERROR: Could not parse android.hardware.can_bus@1.0::ICanBus. Aborting.

这个错误意味着我们的.hal文件中没有正确地定义ICanBus接口,而是声明了一些类型(如structenum)。这违反了HIDL语言的语法规则,因为.hal文件必须以接口定义开始,并且只能有一个接口定义。

简单的说就是hal文件里面必须以interface 开头,不然就会报这个错误。

原因: .hal文件的结构不符合HIDL语法规则

HIDL语言是一种用于定义Android HAL接口的语言,它有一些特定的语法规则和约定。其中之一是.hal文件必须以接口定义开始,并且只能有一个接口定义。比如 如果想要定义一个名为android.hardware.can_bus@1.0::ICanBus的接口,.hal文件应该像这样:

package android.hardware.can_bus@1.0;
interface ICanBus {
    // methods and types for the interface
}

如果在接口定义之前或之后声明了一些类型(如structenum),那么HIDL编译器(hidl-gen)就会报错,因为它无法解析我们的接口定义。如果我们的.hal文件像这样:

package android.hardware.can_bus@1.0;
struct CanFrame {
    // fields for the struct
}
interface ICanBus {
    // methods and types for the interface
}

那么HIDL编译器就会报错:

declares types rather than the expected interface type 'ICanBus'
ERROR: Could not parse android.hardware.can_bus@1.0::ICanBus. Aborting.

解决方案: 重新组织.hal文件或创建新的.hal文件

为了解决这个错误,有两种的方案:

  • 重新组织.hal文件:将接口定义移到文件的顶部,然后再放其他的类型定义。可以将上面的.hal文件修改为:
package android.hardware.can_bus@1.0;
interface ICanBus {
    // methods and types for the interface
}
struct CanFrame {
    // fields for the struct
}
  • 创建新的.hal文件:如果我们想要将类型定义和接口定义分开,可以创建一个新的.hal文件来存放类型定义,并在原来的.hal文件中导入它。可以创建一个名为CanTypes.hal的文件来存放类型定义:
package android.hardware.can_bus@1.0;
struct CanFrame {
    // fields for the struct
}

然后在原来的.hal文件中导入它:

package android.hardware.can_bus@1.0;
import android.hardware.can_bus@1.0.CanTypes;
interface ICanBus {
    // methods and types for the interface
}

问题2:Expecting only package name and version

尝试使用hidl-gen工具来生成HIDL接口的实现代码时,可能会遇到以下错误:

ERROR: Expecting only package name and version.
ERROR: output handler failed.

这个错误意味着我们的命令行参数不符合hidl-gen的要求,因为我们提供了多余的或错误的参数。

原因:命令行参数格式错误

hidl-gen是一个用于生成HIDL接口的实现代码的工具,它有一些特定的命令行参数格式和选项。其中一个必需的参数是HIDL接口的包名和版本号,它应该是这样的:

package@version

比如 如果我们想要生成android.hardware.can_bus@1.0::ICanBus接口的实现代码,应该提供以下参数:

android.hardware.can_bus@1.0

在这个参数后面添加了其他的内容,例如接口名或文件名,那么hidl-gen就会报错,因为它只期望一个包名和版本号。

解决方案:修正命令行参数

为了解决这个错误,需要修正我们的命令行参数,只提供包名和版本号。比如 如果我们之前使用了这样的命令:

hidl-gen -o hardware/interfaces/can_bus/1.0/default -Landroidbp-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0::ICanBus

应该修改为:

hidl-gen -o hardware/interfaces/can_bus/1.0/default -Landroidbp-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Lc++-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0::ICanBus
这个命令会在输出目default录中生成C++或Android BP的接口代码
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Landroidbp-impl \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.hardware.can_bus@1.0
这个命令会在输出default目录中生成一个名为Android.bp的文件,包含了HIDL软件包的编译信息。
hardware/interfaces/can_bus$ tree
.
└── 1.0
    ├── Android.bp
    ├── default
    │   ├── Android.bp
    │   ├── CanBus.cpp
    │   └── CanBus.h
    └── ICanBus.hal

问题3:module “android.hardware.can_bus@1.0-service” variant “android_arm64_armv8-a_cortex-a55”: depends on //system/libhwbinder:libhwbinder which is not visible to this module

当尝试编译一个名为android.hardware.can_bus@1.0-service的HAL服务时,可能会遇到以下错误:

error: hardware/interfaces/can_bus/1.0/service/Android.bp:1:1: module "android.hardware.can_bus@1.0-service" variant "android_arm64_armv8-a_cortex-a55": depends on //system/libhwbinder:libhwbinder which is not visible to this module
10:08:10 soong bootstrap failed with: exit status 1

这个错误意味着我们的HAL服务模块依赖了一个对它不可见的库,即//system/libhwbinder:libhwbinder。这违反了Soong构建系统的可见性规则,因为每个模块都必须声明它可以访问的其他模块。

原因:可见性属性缺失或错误

Soong构建系统是Android用于编译源代码的工具,它使用一种名为Blueprint的语言来描述模块和它们之间的关系。Blueprint语言有一些属性和关键字来控制模块的可见性,即哪些模块可以访问哪些模块。

其中一个属性是visibility,它可以在一个模块的定义中指定哪些其他模块可以依赖它。如果想要让一个名为testhal的模块只对同一个包中的其他模块可见,可以这样写:

cc_library {
    name: "testhal",
    visibility: [":__subpackages__"],
}

如果想要让一个名为testhal2的模块对所有其他模块可见,可以这样写:

cc_library {
    name: "testhal2",
    visibility: ["//visibility:public"],
}

在上面的例子中,//表示根目录,:表示包内分隔符,__subpackages__表示同一个包中的所有子包。

如果一个模块没有指定visibility属性,那么它默认只对同一个包中的其他模块可见。如果一个模块指定了错误的或不匹配的visibility属性,那么它可能会导致编译错误。

在我的情况下,HAL服务模块依赖了一个位于系统分区的库,即//system/libhwbinder:libhwbinder。但这个库的visibility属性是这样的:

cc_library {
    name: "libhwbinder",
    visibility: [":__subpackages__"],
}

这个库只对同一个包中的其他模块可见,即只对位于//hardware/interfaces/can_bus/1.0/...(好像是吧 我猜不可能表示//system/libhwbinder/...)下的模块可见。而我的HAL服务模块位于//hardware/interfaces/can_bus/1.0/service/...下,所以它无法访问这个库。

解决方案:修改或添加可见性属性

为了解决这个错误,我尝试两种方案:

  • 修改库的可见性属性:修改系统分区中的库,可以修改它们的可见性属性,使其对需要的模块可见。如果想要让//hardware/interfaces/can_bus/1.0/service/...对所有HAL服务模块可见,可以这样修改它:
cc_library {
    name: "libhwbinder",
    export_include_dirs: ["include"],
    visibility: [
        ":__subpackages__",
        "//hardware/interfaces/...:service",
    ],
}

这样就可以在//hardware/interfaces/can_bus/1.0/...下的任何包含service的模块中依赖这个库。

或者

+++ b/system/libhwbinder/Android.bp
@@ -66,7 +66,11 @@ cc_library {
 
     export_include_dirs: ["include"],
 
-    visibility: [":__subpackages__"],
+//    visibility: [
+//    ":__subpackages__",
+//    ],
+visibility: ["//visibility:public"],
+
 }

这样就所有模块所有路径都能依赖这个库了。


问题4:VNDK library list has been changed

当我尝试编译一个名为android.hardware.can_bus@1.0.so的HAL时,遇到以下错误:

[ 10% 571/5241] build out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/check-list-timestamp
FAILED: out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/check-list-timestamp
/bin/bash -c "(( diff --old-line-format=\"Removed %L\"    --new-line-format=\"Added %L\"          --unchanged-line-format=\"\"    build/make/target/product/gsi/30.txt out/soong/vndk/vndk.libraries.txt         || ( echo -e \" error: VNDK library list has been changed.\\n\" \"       Changing the VNDK library list is not allowed in API locked branches.\"; exit 1 )) ) && (mkdir -p out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/ ) && (touch out/target/product/rk3568_r/obj/PACKAGING/vndk_intermediates/check-list-timestamp )"
Added VNDK-core: android.hardware.can_bus@1.0.so
 error: VNDK library list has been changed.
        Changing the VNDK library list is not allowed in API locked branches.
10:21:14 ninja failed with: exit status 1

这个错误表示我的HAL被添加到了VNDK库列表中,但在current.txt文件中并没有列出,导致了编译错误。current.txt文件是一个定义了当前Android版本所支持的VNDK库列表的文件,它位于build/make/target/product/vndk/目录下。30.txt文件是一个定义了Android 11所支持的VNDK库列表的文件,它位于build/make/target/product/gsi/目录下。

原因:VNDK库列表不一致或不合法

根据我查阅的资料:

VNDK库列表是一个用于保证供应商和系统之间接口稳定性的机制,它规定了哪些框架共享库可以被供应商模块使用,并且在不同的Android版本之间保持兼容性。VNDK库列表有以下几个特点:

  • VNDK库列表是按照字母顺序排列的。
  • VNDK库列表只包含符合条件的VNDK库(Eligible-VNDK)和VNDK-core库。
  • VNDK库列表不包含LL-NDK库、VNDK-SP库、VNDK-SP-Ext库、VNDK-Ext库、FWK-ONLY库和SP-HAL库。
  • VNDK库列表在API锁定分支中不允许更改。

API锁定分支是指已经发布或即将发布的Android版本分支,例如android-11或android-s-beta-2。在这些分支中,VNDK库列表已经被冻结,不能再添加或删除任何库。这是为了保证系统分区和供应商分区之间的兼容性,以及支持框架专用更新(即只更新系统分区而不更新供应商分区)。

如果我们在API锁定分支中尝试修改VNDK库列表,或者添加了不符合VNDK标准的库到VNDK库列表中,那么编译系统会报错,并停止构建。

解决方案:根据HAL的性质和用途决定是否添加到VNDK

为了解决这个错误,需要根据我的HAL的性质和用途来决定是否应该将其添加到VNDK中。如果我的HAL确实需要作为VNDK的一部分,可以按照以下步骤操作:

  1. 更新current.txt:在current.txt文件中,根据我的HAL的性质,将android.hardware.can_bus@1.0.so添加到合适的位置。如果它是一个核心VNDK库,可以将它添加到VNDK-core部分。必须注意按照字母顺序插入,不然会编译报错。
  2. 更新30.txt30.txt是Android 11的VNDK库列表。如果修改了current.txt,应该在30.txt中进行相同的修改,以确保两者保持一致。必须注意按照字母顺序插入。

但如果我们的HAL不应该是VNDK的一部分,那么应该从构建配置中移除任何将其标记为VNDK的部分,并确保它不会被添加到VNDK库列表中。可以在HAL模块的Android.bp文件中添加一个属性(目前还没搞懂具体区别到底是啥,反正看网上这么说):

vndk: {
    enabled: false,
},

这样系统就不会将该模块视为VNDK库,而是一个普通的HAL模块。该模块就不会被系统分区和供应商分区共享,而是只能被供应商分区使用。

这个问题之前第一次搞HIDL的时候 搞了我好久,还好之前添加过 根据我查阅的笔记。。。

简而言之我告诉大家一个非常简单的办法out\soong\vndk\vndk.libraries.txt

build\target\product\gsi\30.txt 这两个文件用对比工具比完直接用out目录下的比到build目录下直接ok。

更多VNDK可以参考以下链接:


问题5:hwservicemanager找不到HAL接口的错误

09-09 15:24:22.448  8915  8915 I android.hardware.can_bus@1.0-service: CanBusService created
09-09 15:24:22.449   141   141 I hwservicemanager: getTransport: Cannot find entry android.hardware.can_bus@1.0::ICanBus/default in either framework or device manifest.
09-09 15:24:22.450  8915  8915 E HidlServiceManagement: Service android.hardware.can_bus@1.0::ICanBus/default must be in VINTF manifest in order to register/get.

这个错误表示我的HAL服务尝试注册到hwservicemanager,但是hwservicemanager在VINTF(Vendor Interface)清单中找不到相应的条目。VINTF清单是Android 8.0及更高版本中引入的,用于描述HAL和框架之间的接口。

为了解决这个错误,需要确保我们的HAL接口已经被添加到VINTF清单中。以下是如何做到这一点的步骤:

步骤1:创建或修改VINTF清单

在源代码目录中,通常在system目录下,找到一个名为manifest.xml的文件。这个文件用于描述我们的设备提供的HAL接口和版本,以及其他设备相关的信息,如SELinux政策版本等。

步骤2:添加HAL接口到清单

manifest.xml中,添加我们的HAL接口。需要指定接口的名称、传输方式、版本和实例。例如,如果我们想要添加一个名为android.hardware.can_bus@1.0::ICanBus的接口,并且它使用hwbinder作为传输方式,并且有一个名为default的实例,可以这样写:

<manifest version="1.0" type="device">
。。。
    <hal format="hidl">
        <name>android.hardware.can_bus</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ICanBus</name>
            <instance>default</instance>
        </interface>
    </hal>
    <!-- 其他HAL接口 -->
。。。
</manifest>

可以在一个<hal>标签中添加多个版本和实例,也可以添加其他格式的HAL接口,如AIDL或native。

更多关于hwservicemanager和VINTF清单的信息,你可以参考以下链接:

  • HIDL:介绍了HIDL语言和架构,以及如何使用hwservicemanager来管理HIDL服务。
  • 供应商接口对象:介绍了VINTF对象的设计和作用,以及如何使用清单和矩阵来描述和匹配HAL接口。

问题6:调试和解决extends属性引用非VNDK库的错误

error: hardware/interfaces/can_bus/1.0/service/Android.bp:2:1: module "android.hardware.can_bus@1.0-service" variant "android_vendor.30_arm64_armv8-a_cortex-a55": `extends` refers a non-vndk module "libhidltransport"
14:34:14 soong bootstrap failed with: exit status 1

这个错误提示我在system?分区中引用了一个非VNDK的库,即libhidltransport。在Android 8.0及更高版本中,为了确保设备向后兼容性,Google引入了VNDK概念。VNDK库是那些可以在vendor分区中安全使用的库。

为了解决这个问题,以下是我的尝试:

方法1:移除extends属性

如果不需要继承libhidltransport的属性,可以简单地从vndk块中移除extends属性。比如 HAL模块的Android.bp文件中,可以这样写:

cc_binary {
    name: "android.hardware.can_bus@1.0-service",
    vendor: true,
    vndk: {
        enabled: true,
        support_system_process: false,
    },
    srcs: ["CanBus.cpp"],
    shared_libs: [
        "android.hardware.can_bus@1.0",
        "libhidltransport",
        "libhidlbase",
        "libutils",
        "libcutils",
        "liblog",
    ],
}

这样 就不会引用非VNDK库的属性,而是使用默认的属性。

方法2:使用VNDK版本的库

如果libhidltransport有一个VNDK版本,例如libhidltransport_vndk,我们应该在shared_libs中使用它,并在extends中指定它。在我们的HAL模块的Android.bp文件中,可以这样写:

cc_binary {
    name: "android.hardware.can_bus@1.0-service",
    vendor: true,
    vndk: {
        enabled: true,
        support_system_process: false,
        extends: "libhidltransport_vndk",
    },
    srcs: ["CanBus.cpp"],
    shared_libs: [
        "android.hardware.can_bus@1.0",
        "libhidltransport_vndk",
        "libhidlbase",
        "libutils",
        "libcutils",
        "liblog",
    ],
}

就可以继承VNDK库的属性,并且不会引用非VNDK库。

还有一种办法,和问题3类似,就是其实libhidltransport也是有个可见的属性,需要在源码中搜下,反正在Android.bp中 搞了老半天 头有点晕,我直接把这个libhidltransport依赖库给干掉了,也没啥影响 也没搞懂原因。这个就当作坑吧 后面再填上。

问题7:如何调试和解决init进程无法启动服务的错误

09-09 15:50:30.479     0     0 E init    : Control message: Could not ctl.start for 'vendor.hw_canbus' from pid: 2563 (start vendor.hw_canbus): File /system/bin/hw/android.hardware.can_bus@1.0-service(labeled "u:object_r:system_file:s0") has incorrect label or no domain transition from u:r:init:s0 to another SELinux domain defined. Have you configured your service correctly? https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials
09-09 15:50:30.357  2563  2563 W libc    : Unable to set property "ctl.start" to "vendor.hw_canbus": error code: 0x20

这个错误表示HAL服务无法通过init进程启动,因为它没有正确的SELinux上下文或域转换。init进程是Android系统中负责启动和管理服务的核心进程,它有自己的SELinux上下文(通常是u:r:init:s0),并且需要遵循SELinux策略来执行服务的启动和停止。

为了解决这个错误,需要确保以下几点:

步骤1:确认文件上下文

文件上下文是SELinux用来标记文件的安全属性的一种机制,它包括用户、角色、类型和可选的等级。文件上下文可以通过ls -Z命令查看,例如:

$ ls -Z /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x root root u:object_r:system_file:s0 /system/bin/hw/android.hardware.can_bus@1.0-service

这里可以看到文件的类型是system_file,这是一个通用的类型,不适合用于我们的HAL服务。我们需要为HAL服务定义一个专门的类型,比如can_bus_exec,并且在编译时将文件上下文设置为该类型。

步骤2:服务定义

服务定义是在.rc文件中指定HAL服务的启动和停止方式、依赖关系、优先级、资源限制等信息的一种机制。.rc文件通常位于我们的设备特定的源代码目录中,例如system/etc/init/android.hardware.can_bus@1.0-service.rc。在.rc文件中,需要为我们的HAL服务添加一个类似于以下的标签:

service vendor.hw_canbus /system/bin/hw/android.hardware.can_bus@1.0-service
    class hal
    user system
    group system
    seclabel u:object_r:hal_canbus_default_exec:s0

也可以在file_contexts文件中添加以下行:

/(vendor|system)/bin/hw/android\.hardware\.canbus@1\.0-service   u:object_r:hal_canbus_default_exec:s0

这个段落表示,定义了一个名为vendor.hw_canbus的服务,它执行了一个名为/system/bin/hw/android.hardware.can_bus@1.0-service的程序。它属于main类别,以系统用户和系统组运行,并且有一个名为 seclabel u:object_r:hal_canbus_default_exec:s0的SELinux上下文。它是一个一次性服务,即只运行一次而不会重启。

步骤3:重新编译并确认

完成更改后,在设备上运行以下命令来检查我们的HAL服务是否已经被正确启动

如果一切正常,可以看到类似以下的输出:

09-11 09:07:46.421  9125  9125 I android.hardware.can_bus@1.0-service: CanBusService created
09-11 09:07:46.424  9125  9125 I HidlServiceManagement: Registered android.hardware.can_bus@1.0::ICanBus/default
09-11 09:07:46.424  9125  9125 I HidlServiceManagement: Removing namespace from process name android.hardware.can_bus@1.0-service to can_bus@1.0-service.
09-11 09:07:46.424  9125  9125 I android.hardware.can_bus@1.0-service: CanBusService is ready.
rk
#输出结果显示了一个名为android.hardware.can_bus@1.0-service的进程,其进程ID为3435,它是由root用户启动的,并且当前处于睡眠状态(S)
3568_r:/ # ps -A | grep can
root           3435    567 10773968  2788 binder_thread_read  0 S android.hardware.can_bus@1.0-service
#输出结果显示了一个名为android.hardware.can_bus@1.0::ICanBus/default的HAL服务。这表示系统上有一个实现了android.hardware.can_bus@1.0接口的HAL服务,并且它的实例名为default。
rk3568_r:/ # lshal | grep can
FM    N android.hardware.can_bus@1.0::ICanBus/default                             0/1        3435   148

标签调试过程

rk3568_r:/system # find -name "*can*.rc"
./etc/init/android.hardware.can_bus@1.0-service.rc
rk3568_r:/system # cat ./etc/init/android.hardware.can_bus@1.0-service.rc
on boot
    start vendor.hw_canbus
service vendor.hw_canbus /system/bin/hw/android.hardware.can_bus@1.0-service
    class hal
    user system
    group system
    seclabel u:object_r:hal_canbus_default_exec:s0
rk3568_r:/system # start vendor.hw_canbus
Unable to start service 'vendor.hw_canbus'
See dmesg for error reason.
rk3568_r:/ # ls -llZ  /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x 1 root shell u:object_r:system_file:s0  16616 2023-09-09 15:06:27.000000000 +0800 /system/bin/hw/android.hardware.can_bus@1.0-service
rk3568_r:/ # restorecon /system/bin/hw/android.hardware.can_bus@1.0-service
SELinux: Loaded file_contexts
rk3568_r:/ # ls -llZ  /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x 1 root shell u:object_r:system_file:s0  16616 2023-09-09 15:06:27.000000000 +0800 /system/bin/hw/android.hardware.can_bus@1.0-service
rk3568_r:/ # chcon u:object_r:hal_canbus_default_exec:s0 /system/bin/hw/android.hardware.can_bus@1.0-service
r:hal_canbus_default_exec:s0 /system/bin/hw/android.hardware.can_bus@1.0-servic^C                                     <
130|rk3568_r:/ # ls -llZ  /system/bin/hw/android.hardware.can_bus@1.0-service
-rwxr-xr-x 1 root shell u:object_r:hal_canbus_default_exec:s0  16616 2023-09-09 15:06:27.000000000 +0800 /system/bin/hw/android.hardware.can_bus@1.0-service

这表示我们的HAL服务已经成功启动,并且有正确的SELinux上下文。

问题8:提示android/hardware/can_bus/1.0/ICanBus.h文件找不到

我在增加native的时候 编译frameworks/base/services/core/jni/com_android_server_SystemCanBusService.cpp时,遇到了一个错误,提示android/hardware/can_bus/1.0/ICanBus.h文件找不到。

frameworks/base/services/core/jni/com_android_server_SystemCanBusService.cpp:6:10: fatal error: 'android/hardware/can_bus/1.0/ICanBus.h' file not found
#include <android/hardware/can_bus/1.0/ICanBus.h>
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

原因:没有被正确生成

android/hardware/can_bus/1.0/ICanBus.h头文件没有被正确生成或者其路径没有被正确包含在编译时的头文件搜索路径中。

解决方案:修改jni Android.bp 让库被正确地包含在编译依赖中

  1. 使用hidl-gen命令手动生成所需的头文件。这个命令会在hardware/interfaces/can_bus/1.0/default目录下生成一个gen子目录,其中包含android/hardware/can_bus/1.0/ICanBus.h文件。
hidl-gen -o hardware/interfaces/can_bus/1.0/default -Lc++-headers \
  -randroid.hardware:hardware/interfaces \
  -randroid.hidl:system/libhidl/transport \
  android.hardware.can_bus@1.0
hardware$ find -name "ICanBus.h"
./interfaces/can_bus/1.0/default/android/hardware/can_bus/1.0/ICanBus.h
  1. 修改frameworks/base/services/core/jni/Android.bp文件,确保android.hardware.can_bus@1.0库被正确地包含在编译依赖中。
@@ -155,6 +156,7 @@ cc_defaults {
        "android.hardware.gnss.visibility_control@1.0",
        "android.hardware.input.classifier@1.0",
        "android.hardware.ir@1.0",
+        "android.hardware.can_bus@1.0",
        "android.hardware.light@2.0",
        "android.hardware.power@1.0",
        "android.hardware.power@1.1",

通过上述步骤 可以解决编译时找不到ICanBus.h文件的问题。

相关文章
|
4月前
|
Shell Linux 开发工具
"开发者的救星:揭秘如何用adb神器征服Android设备,开启高效调试之旅!"
【8月更文挑战第20天】Android Debug Bridge (adb) 是 Android 开发者必备工具,用于实现计算机与 Android 设备间通讯,执行调试及命令操作。adb 提供了丰富的命令行接口,覆盖从基础设备管理到复杂系统操作的需求。本文详细介绍 adb 的安装配置流程,并列举实用命令示例,包括设备连接管理、应用安装调试、文件系统访问等基础功能,以及端口转发、日志查看等高级技巧。此外,还提供了常见问题的故障排除指南,帮助开发者快速解决问题。掌握 adb 将极大提升 Android 开发效率,助力项目顺利推进。
114 0
|
29天前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
45 8
|
1月前
|
开发框架 前端开发 Android开发
探索安卓和iOS应用开发中的跨平台解决方案
【10月更文挑战第42天】在移动应用开发的广阔天地中,安卓和iOS系统如同两座巍峨的山峰,分别占据着半壁江山。开发者们在这两座山峰之间穿梭,努力寻找一种既能节省资源又能提高效率的跨平台开发方案。本文将带你走进跨平台开发的世界,探讨各种解决方案的优势与局限,并分享一些实用的代码示例,助你在应用开发的道路上更加游刃有余。
|
1月前
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。
|
2月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
92 7
|
3月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
2月前
|
Android开发
Android开发显示头部Bar的需求解决方案--Android应用实战
Android开发显示头部Bar的需求解决方案--Android应用实战
24 0
|
4月前
|
网络安全 图形学 Android开发
Unity与安卓丨AS报错:SSL peer shut down incorrectly
Unity与安卓丨AS报错:SSL peer shut down incorrectly
Unity与安卓丨AS报错:SSL peer shut down incorrectly
|
4月前
|
前端开发 开发工具 Android开发
探索安卓与iOS应用开发:跨平台解决方案的崛起
【8月更文挑战第27天】在移动设备日益普及的今天,安卓和iOS系统占据了市场的主导地位。开发者们面临着一个重要问题:是选择专注于单一平台,还是寻找一种能够同时覆盖两大系统的解决方案?本文将探讨跨平台开发工具的优势,分析它们如何改变了移动应用的开发格局,并分享一些实用的开发技巧。无论你是新手还是资深开发者,这篇文章都将为你提供有价值的见解和建议。
|
4月前
|
Ubuntu Android开发
安卓系统调试与优化:(一)bootchart 的配置和使用
本文介绍了如何在安卓系统中配置和使用bootchart工具来分析系统启动时间,包括安装工具、设备端启用bootchart、PC端解析数据及分析结果的详细步骤。
227 0
安卓系统调试与优化:(一)bootchart 的配置和使用