Android Automotive是通过Android的通用框架,语言和API来实现的一个全栈,开源,高度可定制的平台。
Automotive
Android Automative是在原先Android的系统架构上增加了一些与车相关的(图中虚线框中绿色背景的)模块。
· annotation:包含了两个注解。 · app · menu:车辆应用菜单相关API。 · cluster:仪表盘相关API。 · render:渲染相关API。 · content · pm:应用包相关API。 · diagnostic:包含与汽车诊断相关的API。 · hardware:车辆硬件相关API。 · cabin:座舱相关API。 · hvac:通风空调相关API。 · property:属性相关API(实现定制的property)。 · radio:收音机相关API。 · input:输入相关API。 · media:多媒体相关API。 · navigation:导航相关API。 · settings:设置相关API。 · vms:汽车监测相关API
这些api集合中,我们可以通过CarpropertyManager去实现定制的property功能,简要类图:
需要注意的是ICarProperty是同步接口,ICarPropertyEventListener是异步接口。
onEvent传上来的是参数是CarPropertyEvent的list,CarPropertyEvent中包含event type与CarPropertyValue; eventType包含PROPERTY_EVENT_PROPERTY_CHANGE与PROPERTY_EVENT_ERROR,分别对应listener中的onPropertyChanged和PROPERTY_EVENT_ERROR, CarPropertyValue则包含具体的propId、propValue等具体属性信息。
代码目录: packages/services/Car/service
SystemServer启动过程中,在ActivityManagerService systemReady时,启动CarServiceHelperService。 代码:
android/frameworks/base/services/java/com/android/server/SystemServer.java
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
t.traceBegin("StartCarServiceHelperService");
final SystemService cshs = mSystemServiceManager
.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
if (cshs instanceof Dumpable) {
mDumper.addDumpable((Dumpable) cshs);
}
if (cshs instanceof DevicePolicySafetyChecker) {
dpms.setDevicePolicySafetyChecker((DevicePolicySafetyChecker) cshs);
}
t.traceEnd();
}
private static final String CAR_SERVICE_HELPER_SERVICE_CLASS =
"com.android.internal.car.CarServiceHelperService";
CarServiceHelperService在onStart时拉起CarServcie,加载Native库car-framework-service-jni。
android/frameworks/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java
public void onStart() {
EventLog.writeEvent(EventLogTags.CAR_HELPER_START);
IntentFilter filter = new IntentFilter(Intent.ACTION_REBOOT);
filter.addAction(Intent.ACTION_SHUTDOWN);
mContext.registerReceiverForAllUsers(mShutdownEventReceiver, filter, null, null);
mCarWatchdogDaemonHelper.addOnConnectionChangeListener(mConnectionListener);
mCarWatchdogDaemonHelper.connect();
Intent intent = new Intent();
intent.setPackage("com.android.car");
intent.setAction(CAR_SERVICE_INTERFACE);
if (!mContext.bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
mHandler, UserHandle.SYSTEM)) {
Slogf.wtf(TAG, "cannot start car service");
}
loadNativeLibrary();
}
void loadNativeLibrary() {
System.loadLibrary("car-framework-service-jni");
}
android/packages/services/Car/car-lib/src/com/android/car/internal/common/CommonConstants.java
public static final String CAR_SERVICE_INTERFACE = "android.car.ICar";
android/packages/services/Car/service/AndroidManifest.xml
CarService在onCreate时先判断Vehicle HAL起来了,然后再初始化ICarImpl。 代码:
android/packages/services/Car/service/src/com/android/car/CarService.java
public void onCreate() {
LimitedTimingsTraceLog initTiming = new LimitedTimingsTraceLog(CAR_SERVICE_INIT_TIMING_TAG,
Trace.TRACE_TAG_SYSTEM_SERVER, CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS);
initTiming.traceBegin("CarService.onCreate");
initTiming.traceBegin("getVehicle");
mVehicle = getVehicle();
initTiming.traceEnd();
EventLog.writeEvent(EventLogTags.CAR_SERVICE_CREATE, mVehicle == null ? 0 : 1);
if (mVehicle == null) {
throw new IllegalStateException("Vehicle HAL service is not available.");
}
try {
mVehicleInterfaceName = mVehicle.interfaceDescriptor();
} catch (RemoteException e) {
throw new IllegalStateException("Unable to get Vehicle HAL interface descriptor", e);
}
Slog.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName);
EventLog.writeEvent(EventLogTags.CAR_SERVICE_CONNECTED, mVehicleInterfaceName);
mICarImpl = new ICarImpl(this,
mVehicle,
SystemInterface.Builder.defaultSystemInterface(this).build(),
mVehicleInterfaceName);
mICarImpl.init();
linkToDeath(mVehicle, mVehicleDeathRecipient);
ServiceManager.addService("car_service", mICarImpl);
SystemProperties.set("boot.car_service_created", "1");
super.onCreate();
initTiming.traceEnd(); // "CarService.onCreate"
}
private static IVehicle getVehicle() {
final String instanceName = SystemProperties.get("ro.vehicle.hal", "default");
try {
return android.hardware.automotive.vehicle.V2_0.IVehicle.getService(instanceName);
} catch (RemoteException e) {
Slog.e(CarLog.TAG_SERVICE, "Failed to get IVehicle/" + instanceName + " service", e);
} catch (NoSuchElementException e) {
Slog.e(CarLog.TAG_SERVICE, "IVehicle/" + instanceName + " service not registered yet");
}
return null;
}
android/packages/services/Car/car-lib/src/android/car/ICar.aidl
android/packages/services/Car/service/src/com/android/car/ICarImpl.java
ICarImpl构造函数中,构造了下面几个实现了CarServiceBase接口的Car Services组件,以及VehicleHal和CarStatsService;然后通过init函数进行初始化。
CarFeatureController
CarPropertyService
CarDrivingStateService
CarUxRestrictionsManagerService
CarUserService
CarOccupantZoneService
SystemActivityMonitoringService
CarPowerManagementService
CarUserNoticeService
CarPackageManagerService
PerUserCarServiceHelper
CarBluetoothService
CarInputService
CarProjectionService
GarageModeService
AppFocusService
CarAudioService
CarNightService
FixedActivityService
ClusterNavigationService
InstrumentClusterService
VmsBrokerService
CarDiagnosticService
CarStorageMonitoringService
CarLocationService
CarMediaService
CarBugreportManagerService
CarExperimentalFeatureServiceController
CarWatchdogService
CarDevicePolicyService
ClusterHomeService
CarEvsService
CarTelemetryService
CarActivityService
VehicleHal构造函数中,构造了下面几个继承自HalServiceBase基类的Hal Services组件以及HalClient;然后通过init函数进行初始化。
PowerHalService
PropertyHalService
InputHalService
VmsHalService
UserHalService
DiagnosticHalService
ClusterHalService
EvsHalService
TimeHalService
android/packages/services/Car/service/src/com/android/car/hal/VehicleHal.java
下面是vehicle 2.0参考实现的目录结构。
android/hardware/interfaces/automotive/vehicle/2.0/
|-- default // 默认实现
|-- common
|-- include
|-- vhal_v2_0 // .h
|-- src // .cpp
|-- impl
|-- vhal_v2_0 // impl代码
|-- proto // proto协议
|-- tests
|-- tests
|-- Android.bp // 编译文件
|-- VehicleService.cpp // main函数
|-- [email protected] // init rc
|-- [email protected] // matrix xml
|-- utils
|-- vts
|-- Android.bp // 编译文件
|-- IVehicle.hal // interface
|-- IVehicleCallback.hal // callback
|-- types.hal // types
Hidl代码有个明显的namespace规则,如下。
namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
namespace V2_0 {
// ...
} // namespace V2_0
} // namespace vehicle
} // namespace automotive
} // namespace hardware
} // namespace android
VehicleHAL由init rc启动。 代码:
android/hardware/interfaces/automotive/vehicle/2.0/default/[email protected]
service vendor.vehicle-hal-2.0 /vendor/bin/hw/[email protected]
class early_hal
user vehicle_network
group system inet
下面是VehicleHAL的main函数。 代码:
android/hardware/interfaces/automotive/vehicle/2.0/default/VehicleService.cpp
int main(int /* argc */, char* /* argv */ []) {
auto store = std::make_unique();
auto connector = std::make_unique();
auto userHal = connector->getEmulatedUserHal();
auto hal = std::make_unique(store.get(), connector.get(), userHal);
auto emulator = std::make_unique(hal.get());
auto service = std::make_unique(hal.get());
connector->setValuePool(hal->getValuePool());
configureRpcThreadpool(4, true /* callerWillJoin */);
ALOGI("Registering as service...");
status_t status = service->registerAsService();
if (status != OK) {
ALOGE("Unable to register vehicle service (%d)", status);
return 1;
}
ALOGI("Ready");
joinRpcThreadpool();
return 1;
}
以上为车机开发技术中的CarFrameWork学习;启动流程及原理介绍,更多的车载技术可以前往《车机开发技术手册》查看更多车载技术。
CarService向上与App通过CarLib(aidl)交互,向下与VehicleHAL通过hidl交互,其中包括了一个很重要的概念:Property。 Property可以是静态的,也可以是变化后向上通报的,还可以是以一定的频率实时上报的。 下面以HVAC为例,说明HVAC的控制过程。
最终,将Property或转换后的信号发到【Car ECU】。vehicle 2.0模拟实现是将Property存储到VehiclePropertyStore