版权声明
凡未经作者授权,任何媒体、网站及个人不得转载、复制、重制、改动、展示或使用局部或全部的内容或服务。如果已转载,请自行删除。同时,我们保留进一步追究相关行为主体的法律责任的权利。
© 2023 小酥肉不加辣,All rights reserved.
本文基于 AOSP android13-release 分支代码进行修改,并采用 AIDL 方式实现。
作为 OEM,在 AOSP Automotive OS 的基础上添加 Vehicle 自定义属性是必须要做的事情。虽然 AOSP 提供了大量的 Vehicle 属性,但是不同品牌和型号的汽车还是有其区别于其他产品的特别功能。在这种场景下,就需要我们修改 AOSP 的源码,增加自定义属性。
1. 添加新属性
hardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -2839,5 +2839,10 @@ enum VehicleProperty {
VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ VEHICLE_TEST_PROPERTY = 0x0F50 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
}
2. 更新 AIDL API
因为修改了系统的AIDL,为了API的稳定,系统要求执行 update-api 的操作,执行命令
make android.hardware.automotive.vehicle-update-api
执行成功之后会在hardware/interfaces/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl中生成更新后的 aidl 定义
@@ -206,4 +206,7 @@ enum VehicleProperty {
EV_REGENERATIVE_BRAKING_STATE = 289410884,
TRAILER_PRESENT = 289410885,
VEHICLE_CURB_WEIGHT = 289410886,
+ VEHICLE_TEST_PROPERTY = 289410896,
}
注意不要手动修改这个文件
3. 由 AIDL 生成对应的 .h 文件
回到 AOSP 根目录,执行命令
mmm hardware/interfaces/autmotive/vehicle
编译整个 vehicle 模块,成功之后会在
out/soong/.intermediates/hardware/interfaces/automotive/vehicle/aidl/android.hardware.automotive.vehicle-V2-ndk-source/gen/include/aidl/android/hardware/automotive/vehicle/VehicleProperty.h 文件中生成了 VEHICLE_TEST_PROPERTY 相关的代码。
4. 配置属性
hardware/interfaces/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
@@ -1974,6 +1974,44 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
},
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::VEHICLE_TEST_PROPERTY),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ .initialValue = {.int32Values = {123}},
+ },
这里设置属性 VEHICLE_TEST_PROPERTY 既可读也可写、changeMode 和初始值。如果这个属性的 area 不是global,那么还需要设置 .areaConfig 和 .initialAreaValues,可参考源码中其他属性的设置。
5. 添加 owner 信息
由于修改了系统的 AIDL,需要添加 owner 到 bp 文件中。
hardware/interfaces/automotive/vehicle/aidl/Android.bp
@@ -24,6 +24,7 @@ package {
aidl_interface {
name: "android.hardware.automotive.vehicle",
vendor_available: true,
+ owner:"xsr",
srcs: [
"android/hardware/automotive/vehicle/**/*.aidl",
],
由于 emulator 中的 aidl 直接依赖了 vehicle 中的 aidl,因此也需要在 emulator 的 Android.bp 中添加 owner 信息
device/generic/car/emulator/vhal_v2_0/interfaces/aidl/Android.bp
@@ -12,6 +12,7 @@ package {
aidl_interface {
name: "device.generic.car.emulator-aidl",
vendor_available: true,
+ owner: "xsr",
srcs: ["device/generic/car/emulator/*.aidl"],
imports: [
"android.hardware.automotive.vehicle",
6.升级其他模块中的依赖的版本
完成以上步骤之后编译的时候,会报错找不到 VEHICLE_TEST_PROPERTY,这是因为第3步的时候,会生成 android.hardware.automotive.vehicle-V2-ndk,AOSP 中还有很多其他模块依赖它,但是依赖的版本还是 V1。所以我们需要手动修改所有依赖的地方。
hardware/interfaces/automotive/vehicle/aidl/impl/Android.bp
@@ -22,7 +22,7 @@ cc_defaults {
name: "VehicleHalDefaults",
static_libs: [
"android-automotive-large-parcelable-lib",
- "android.hardware.automotive.vehicle-V1-ndk",
+ "android.hardware.automotive.vehicle-V2-ndk",
"libmath",
],
shared_libs: [
device/generic/car/emulator/vhal_aidl/VehicleEmulator/Android.bp
@@ -38,7 +38,7 @@ cc_library {
"libutils",
"libprotobuf-cpp-lite",
"libbinder_ndk",
- "device.generic.car.emulator-aidl-V1-ndk",
+ "device.generic.car.emulator-aidl-V2-ndk",
],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
device/generic/car/emulator/vhal_aidl/Android.bp
@@ -52,6 +52,6 @@ cc_binary {
"libutils",
"libprotobuf-cpp-lite",
"libbinder_ndk",
- "device.generic.car.emulator-aidl-V1-ndk",
+ "device.generic.car.emulator-aidl-V2-ndk",
],
}
device/generic/car/emulator/vhal_aidl/VehicleEmulator/Android.bp
@@ -38,7 +38,7 @@ cc_library {
"libutils",
"libprotobuf-cpp-lite",
"libbinder_ndk",
- "device.generic.car.emulator-aidl-V1-ndk",
+ "device.generic.car.emulator-aidl-V2-ndk",
],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
device/generic/car/emulator/vhal_aidl/VehicleEmulator/test/Android.bp
@@ -39,7 +39,7 @@ cc_test {
"libutils",
"libprotobuf-cpp-lite",
"libbinder_ndk",
- "device.generic.car.emulator-aidl-V1-ndk",
+ "device.generic.car.emulator-aidl-V2-ndk",
],
defaults: [
"VehicleHalDefaults",
感觉这一步可能没有必要,但是我没有找到修改 AIDL 之后不执行 update-api 的方法。
7. 验证结果
此处以 x86_64 平台为例,以下文件路径中的 x86_64 替换为相应平台即可
方法1 全量编译
回到项目根目录,使用 m 命令重新编译整个项目。
使用 make emu_img_zip 重新编译模拟器镜像。
编译好的镜像文件在 out/target/product/emulator_car_x86_64/sdk-repo-linux-system-images-eng.$(whoami).zip。
将生成的 zip 文件复制出来,解压之后替换本地 SDK 中的镜像 ~/Library/Android/sdk/system-images/android-33/android-automotive/x86_64, 然后把模拟器 wipe data 并重新启动模拟器。
打开模拟器
方法2 增量编译
回到项目根目录,使用 mmm device/generic/car 编译这个模块。
编译成功之后可以
找到out/target/product/emulator_car_x86_64/vendor/bin/hw/android.hardware.automotive.vehicle@V1-emulator-service 文件,并 push 到模拟器的 vendor/bin/hw 目录下。
找到 out/target/product/emulator_car_x86_64/vendor/lib64/android.hardware.automotive.vehicle-V2-ndk.so 文件, 并 push 到模拟器 vendor/lib64 目录下。
找到 out/target/product/emulator_car_x86_64/vendor/lib64/device.generic.car.emulator-aidl-V2-ndk.so,将这个文件push到模拟器 vendor/lib64 目录下。
重启模拟器即可生效。
最后
虽然使用这个方法可以自定义 Vehicle Property,也可以在模拟器中读取和设置属性。但是当我们在应用层调用 CarPropertyManager 的 getIntProperty 和 setIntProperty 方法时还是会抛出 property id 不存在的异常。 如果想解决这个问题还需要在 CarService 层为自定义属性添加自定义权限。请查看我的关于自定义权限的文章。
如果你对车机开发感兴趣,可以关注我的车机开发专栏。