对接服务框架车辆信号手册

信号对接概要

(1)APP侧与服务框架(Framework)对接各种车辆信号,APP就需要依赖Framework的开发

(2)车辆信号在framework中的实现逻辑是在仓库 platform/android/services/MiVehicleService,负责同学是 @姚鹏

(3)MiVehicleService负责业务:

  • 接入中间件的CAN信号
  • 对信号进行处理/转换,比如转换为CarPropertyValue等
  • … …

(4)为了统一与便于APP接入信号, @姚鹏 统一做了一个 vehicle.support.jar,里面包含所有信号名 / 信号值的定义

MiVehicleService的编译与安装

🏖️ MiVehicleService已预装在ROM中,如果需要最新版本,可以自行编译 或者 联系研发要APK

2.1 下载代码

git clone "http://gaoyi@gerrit.auto.mioffice.cn/a/cockpit/core/platform/android/services/MiVehicleService" && (cd "MiVehicleService" && mkdir -p .git/hooks && curl -Lo `git rev-parse --git-dir`/hooks/commit-msg http://gaoyi@gerrit.auto.mioffice.cn/tools/hooks/commit-msg; chmod +x `git rev-parse --git-dir`/hooks/commit-msg)

2.2 编译

(1)MiVehicleService已解偶,可以通过Android Studio直接编译

(2)也可以找姚鹏要一个他编译的最新的 MiVehicleService.apk

2.3 push安装

adb push MiVehicleService.apk /system/priv-app/MiVehicleService/MiVehicleService.apk
adb reboot

3. vehicle.support.jar

3.1 引入jar包

build.gradle中添加:

implementation 'mi.car:vehicle.support:0.0.12-SNAPSHOT'

添加混淆:

#android car
-keep class android.car.** {*;}

3.2 查询jar版本号

最新的 mi.car:vehicle.support 会同步到 maven 仓库,暂时是 snapshots 形式。

maven仓库地址:

https://pkgs.d.xiaomi.net/artifactory/webapp/#/search/quick/eyJzZWFyY2giOiJxdWljayIsInF1ZXJ5IjoidmVoaWNsZSJ9

3.3 jar中类结构

每个类的定义,与SOA文档中信号划分是对应的。

(1)JAR中类定义(mi.car 包下的文件夹结构):

(2)SOA中信号划分(模块分工与定义规范):

3.4 信号接入指南

信号接入指南

信号接入方法

4.0 添加权限

在 AndroidManifest.xml 中添加如下权限:

<uses-permission android:name="android.car.permission.CONTROL_CAR_SEATS" />
<uses-permission android:name="android.car.permission.CAR_DRIVING_STATE" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_DOORS" />
<uses-permission android:name="android.car.permission.CAR_ENERGY_PORTS" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_ENERGY_PORTS" />
<uses-permission android:name="android.car.permission.CAR_ENERGY" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
<uses-permission android:name="android.car.permission.CAR_EXTERIOR_LIGHTS" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS" />
<uses-permission android:name="android.car.permission.READ_CAR_INTERIOR_LIGHTS" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_INTERIOR_LIGHTS" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_MIRRORS" />

4.1 绑定CarService

根据业务需求,在 Activity 或者 Service 的恰当时机进行绑定:

if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
    mCarApiClient = Car.createCar(this, mCarServiceConnection);
    mCarApiClient.connect();
}

4.2 查询业务关注的信号

(1)所有信号的定义,都可以在 SOA 文档中查询到:

SOA 服务接口定义表格 MS11(E2/E3 备份 | 弃用)

(2)vehicle.support.jar 也是根据 SOA 文档实现的,APP研发在 jar 中查找业务关心的信号,比如车辆电源模式信号:

信号名定义:

mi.car.config.Driving#POWER_MODE

信号值定义:

public static final class PowerStatus implements ValueDef.ValueEnum {
    public static final int OFF = 0;
    public static final int AWAKE = 1;
    public static final int ACC = 2;
    public static final int ON = 3;
    public static final int START = 4;
}

4.3 注册信号ID与回调

绑定 CarService 成功后,将业务关心的信号ID注册到 CarService,同时传入回调对象:

private final ServiceConnection mCarServiceConnection =
        new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                synchronized (mIcManagerReady) {
                    try {
                        // 业务需要关注的信号比较,每个信号都需要registerCallback
                        for (Integer id: IcPropertyIds.icObservedIds) {
                            mIcPropertyManager.registerCallback(mHardwareCallback, id, CarPropertyManager.SENSOR_RATE_ONCHANGE);
                            Log.i(TAG, "initIcManager propId: " + id);
                        }
                        mIcManagerReady.notifyAll();
                    } catch (CarNotConnectedException e) {
                        Log.e(TAG, "Car not connected in onServiceConnected");
                    }
                }
            }
 
            @Override
            public void onServiceDisconnected(ComponentName name) {
            }
        };

4.4 接收信号并处理

在回调对象中,接收到 CarPropertyValue,判断是否为业务关心的信号ID,并加以业务逻辑处理:

CarPropertyManager.CarPropertyEventCallback mHardwareCallback =
        new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(final CarPropertyValue val) {
                if (val == null) {
                    return;
                }
 
                switch (val.getPropertyId()) {
                    case IcPropertyIds.Power_Mode:
                        // XXX
                        break;
                    default:
                }
            }
        };

4.5 信号模拟

可以通过 adb 命令模拟信号,以车门状态为例:

adb shell dumpsys car_service inject-vhal-event 0x66403101 1 1
# 0x66403101 信号值
# 1  areaId
# 1  value

有些信号可能修改后值会马上复原,可以执行下面命令:

adb shell settings put --user 0 GLOBAL vehicle_mock_data 1