拆分盤網(wǎng)站建設(shè)百度流量推廣項(xiàng)目
汽車架構(gòu):車載HAL是汽車與車輛網(wǎng)絡(luò)服務(wù)之間的接口定義(同時保護(hù)傳入的數(shù)據(jù)):
車載HAL與Android Automotive架構(gòu):
- Car App:包括OEM和第三方開發(fā)的App
- Car API:內(nèi)有包含CarSensorManager在內(nèi)的API。位于/platform/packages/services/Car/car-lib
- CarService:系統(tǒng)中與車相關(guān)的服務(wù),位于/platform/packages/services/Car/
- Vehicle HAL:汽車的硬件抽象層描述。位于hardware/interfaces/automotive/vehicle/2.0/default/(接口屬性:hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/)
Framework CarService
Android O/P為Automotive場景提供了一系列的服務(wù),這些服務(wù)統(tǒng)被稱為CarService。它們與HAL層的VehicleHAL通信,進(jìn)而通過車載總線(例如CAN總線)與車身進(jìn)行通訊,同時它們還為應(yīng)用層的APP提供接口,從而讓APP能夠?qū)崿F(xiàn)對車身的控制與狀態(tài)的顯示
- Car***Manager:packages/services/Car/car-lib/src/android/car/hardware
- Car***Service:packages/services/Car/service/src/com/android/car/
CarService啟動流程
和汽車相關(guān)的服務(wù)的啟動主要依靠一個系統(tǒng)服務(wù)CarServiceHelperService開機(jī)時在SystemServer中啟動:
CarServiceHelperService啟動
private static final String CAR_SERVICE_HELPER_SERVICE_CLASS ="com.android.internal.car.CarServiceHelperService";private void startOtherServices(@NonNull TimingsTraceAndSlog t) {......?if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {t.traceBegin("StartCarServiceHelperService");mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);t.traceEnd();}......}
CarServiceHelperService被定義在frameworks/opt/car/下,它和其他系統(tǒng)服務(wù)一樣,屬于SystemService的子類,通過SystemServiceManager.startService啟動:
SystemServiceManager.startService
public SystemService startService(String className) {final Class<SystemService> serviceClass = loadClassFromLoader(className,this.getClass().getClassLoader());return startService(serviceClass);}private static Class<SystemService> loadClassFromLoader(String className,ClassLoader classLoader) {try {return (Class<SystemService>) Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {...}}
loadClassFromLoader通過類加載器直接獲取CarServiceHelperService的class對象,拿到class對象進(jìn)而再調(diào)用startService重載方法:
public <T extends SystemService> T startService(Class<T> serviceClass) {try {final String name = serviceClass.getName();
?
?// Create the service.if (!SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name+ ": service must extend " + SystemService.class.getName());}final T service;try {Constructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);} catch (InstantiationException ex) {...} catch (IllegalAccessException ex) {...} catch (NoSuchMethodException ex) {...} catch (InvocationTargetException ex) {...}startService(service);return service;} finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}}
?
接著通過反射構(gòu)造CarServiceHelperService的實(shí)例對象,然后再調(diào)用startService重載方法:
public void startService(@NonNull final SystemService service) {// Register it.mServices.add(service);// Start it.long time = SystemClock.elapsedRealtime();try {service.onStart();} catch (RuntimeException ex) {throw new RuntimeException("Failed to start service " + service.getClass().getName()+ ": onStart threw an exception", ex);}warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");}
這里先將CarServiceHelperService保存到mServices這個list中,然后調(diào)用CarServiceHelperService的onStart方法正式啟動此服務(wù)。
CarServiceHelperService.onStart
@Overridepublic void onStart() {EventLog.writeEvent(EventLogTags.CAR_HELPER_START, mHalEnabled ? 1 : 0);
?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(ICarConstants.CAR_SERVICE_INTERFACE);if (!mContext.bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,UserHandle.SYSTEM)) {Slog.wtf(TAG, "cannot start car service");}loadNativeLibrary();}
這里首先注冊了開關(guān)機(jī)廣播,CarWatchdogDaemonHelper用于監(jiān)控此服務(wù),接著會綁定一個包名為"com.android.car",Action為"android.car.ICar"的服務(wù),這就是系統(tǒng)中和汽車相關(guān)的核心服務(wù)CarService,相關(guān)源代碼在packages/services/Car/service目錄下,然后我們先去看看CarService,等下再回頭來看綁定此服務(wù)之后的mCarServiceConnection回調(diào)部分。
如下是CarService的AndroidManifest部分截圖,可以看到CarService的sharedUserId是系統(tǒng)級別的,這是一個系統(tǒng)級服務(wù),類似SystemUI,它編譯出來同樣是一個APK文件。 來具體看CarService,它的onStartCommand沒什么東西,主要來看onBind:
CarService.onBind
@Overridepublic IBinder onBind(Intent intent) {return mICarImpl;}
ICarImpl是一個Binder服務(wù)端,其頂級接口為ICar,在onCreate中初始化:
CarService.onCreate
@Overridepublic void onCreate() {//通知用戶有關(guān) CAN 總線故障 mCanBusErrorNotifier = new CanBusErrorNotifier(this /* context */);//獲取Vehicle hal的client端mVehicle = getVehicle();if (mVehicle == null) {throw new IllegalStateException("Vehicle HAL service is not available.");}try {mVehicleInterfaceName = mVehicle.interfaceDescriptor();} catch (RemoteException e) {...}//實(shí)例化ICarImplmICarImpl = new ICarImpl(this,mVehicle,SystemInterface.Builder.defaultSystemInterface(this).build(),mCanBusErrorNotifier,mVehicleInterfaceName);//初始化mICarImpl.init();//Vehicle hal對端死亡回調(diào)linkToDeath(mVehicle, mVehicleDeathRecipient);//將mICarImpl注冊到ServiceManagerServiceManager.addService("car_service", mICarImpl);//修改boot.car_service_created屬性為1SystemProperties.set("boot.car_service_created", "1");super.onCreate();}
此方法中主要會對ICarImpl實(shí)例化,之后init進(jìn)行初始化,最后將其注冊到ServiceManager。
ICarImpl構(gòu)造方法
ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,CanBusErrorNotifier errorNotifier, String vehicleInterfaceName,@Nullable CarUserService carUserService,@Nullable CarWatchdogService carWatchdogService) {......mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext, mCarUserService);mCarBluetoothService = new CarBluetoothService(serviceContext, mPerUserCarServiceHelper);mCarInputService = new CarInputService(serviceContext, mHal.getInputHal(), mCarUserService);mCarProjectionService = new CarProjectionService(serviceContext, null /* handler */, mCarInputService, mCarBluetoothService);mGarageModeService = new GarageModeService(mContext);mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);mCarAudioService = new CarAudioService(serviceContext);mCarNightService = new CarNightService(serviceContext, mCarPropertyService);mFixedActivityService = new FixedActivityService(serviceContext);mInstrumentClusterService = new InstrumentClusterService(serviceContext,mAppFocusService, mCarInputService);mSystemStateControllerService = new SystemStateControllerService(serviceContext, mCarAudioService, this);mCarStatsService = new CarStatsService(serviceContext);mCarStatsService.init();if (mFeatureController.isFeatureEnabled(Car.VEHICLE_MAP_SERVICE)) {mVmsBrokerService = new VmsBrokerService(mContext, mCarStatsService);} else {mVmsBrokerService = null;}if (mFeatureController.isFeatureEnabled(Car.DIAGNOSTIC_SERVICE)) {mCarDiagnosticService = new CarDiagnosticService(serviceContext,mHal.getDiagnosticHal());} else {mCarDiagnosticService = null;}if (mFeatureController.isFeatureEnabled(Car.STORAGE_MONITORING_SERVICE)) {mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext,systemInterface);} else {mCarStorageMonitoringService = null;}mCarConfigurationService =new CarConfigurationService(serviceContext, new JsonReaderImpl());mCarLocationService = new CarLocationService(serviceContext);mCarTrustedDeviceService = new CarTrustedDeviceService(serviceContext);mCarMediaService = new CarMediaService(serviceContext, mCarUserService);mCarBugreportManagerService = new CarBugreportManagerService(serviceContext);......CarLocalServices.addService(CarPowerManagementService.class, mCarPowerManagementService);CarLocalServices.addService(CarPropertyService.class, mCarPropertyService);CarLocalServices.addService(CarUserService.class, mCarUserService);CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService);CarLocalServices.addService(CarUserNoticeService.class, mCarUserNoticeService);CarLocalServices.addService(SystemInterface.class, mSystemInterface);CarLocalServices.addService(CarDrivingStateService.class, mCarDrivingStateService);CarLocalServices.addService(PerUserCarServiceHelper.class, mPerUserCarServiceHelper);CarLocalServices.addService(FixedActivityService.class, mFixedActivityService);CarLocalServices.addService(VmsBrokerService.class, mVmsBrokerService);.....List<CarServiceBase> allServices = new ArrayList<>();allServices.add(mFeatureController);allServices.add(mCarUserService);allServices.add(mSystemActivityMonitoringService);allServices.add(mCarPowerManagementService);allServices.add(mCarPropertyService);allServices.add(mCarDrivingStateService);...mAllServices = allServices.toArray(new CarServiceBase[allServices.size()]);
}
這里省略了和Vehicle hal有關(guān)的初始化和分析,后續(xù)文章再看。
ICarImpl構(gòu)造方法中創(chuàng)建了一系列CarService模塊下的服務(wù),這些服務(wù)有部分被添加到了CarLocalServices內(nèi)部,其提供了getService靜態(tài)方法用于直接獲取這些服務(wù),所有服務(wù)都被保存在ICarImpl內(nèi)部的CarServiceBase類型數(shù)組mAllServices中(所有服務(wù)都是CarServiceBase的子類)。
ICarImpl構(gòu)造方法完了之后會接著調(diào)用其init方法:
ICarImpl.init
@MainThreadvoid init() {mBootTiming = new TimingsTraceLog(VHAL_TIMING_TAG, Trace.TRACE_TAG_HAL);traceBegin("VehicleHal.init");//hal初始化//...省略traceEnd();traceBegin("CarService.initAllServices");for (CarServiceBase service : mAllServices) {service.init();}traceEnd();}
此方法很簡單,遍歷mAllServices,分別執(zhí)行所有服務(wù)的init,各自初始化,有興趣的可以自己去研究各個服務(wù)。
到此ICarImpl初始化完畢,最后會作為binder返回給綁定此服務(wù)的mCarServiceConnection:
private final ServiceConnection mCarServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {if (DBG) {Slog.d(TAG, "onServiceConnected:" + iBinder);}handleCarServiceConnection(iBinder);}
?@Overridepublic void onServiceDisconnected(ComponentName componentName) {handleCarServiceCrash();}};
CarServiceHelperService.handleCarServiceConnection
void handleCarServiceConnection(IBinder iBinder) {...synchronized (mLock) {if (mCarService == iBinder) {return; // already connected.}mCarService = iBinder;...sendSetCarServiceHelperBinderCall();......}}
這個方法我們主要關(guān)注上面部分,返回的ICarImpl被保存在了CarServiceHelperService的mCarService,后續(xù)可通過mCarService跨進(jìn)程通信。
CarServiceHelperService.sendSetCarServiceHelperBinderCallprivate void sendSetCarServiceHelperBinderCall() {Parcel data = Parcel.obtain();data.writeInterfaceToken(ICarConstants.CAR_SERVICE_INTERFACE);data.writeStrongBinder(mHelper.asBinder());// void setCarServiceHelper(in IBinder helper)sendBinderCallToCarService(data, ICarConstants.ICAR_CALL_SET_CAR_SERVICE_HELPER);}
這里將會進(jìn)行跨進(jìn)程通信,首先構(gòu)造傳輸數(shù)據(jù),ICarConstants是定義在ExternalConstants的靜態(tài)內(nèi)部類:
static final class ICarConstants {....static final String CAR_SERVICE_INTERFACE = "android.car.ICar";static final int ICAR_CALL_SET_CAR_SERVICE_HELPER = 0;....}
CAR_SERVICE_INTERFACE用來標(biāo)識遠(yuǎn)程服務(wù)接口,其具體傳輸數(shù)據(jù)是一個Binder對象,我們來看看mHelper是什么?
?private final ICarServiceHelperImpl mHelper = new ICarServiceHelperImpl();
mHelper是定義在CarServiceHelperService的內(nèi)部類,是一個Binder對象:
private class ICarServiceHelperImpl extends ICarServiceHelper.Stub {...........
}
CarServiceHelperService.sendBinderCallToCarService 再回到前面看sendBinderCallToCarService方法:
private void sendBinderCallToCarService(Parcel data, int callNumber) {// Cannot depend on ICar which is defined in CarService, so handle binder call directly// instead.IBinder carService;synchronized (mLock) {carService = mCarService;}if (carService == null) {Slog.w(TAG, "Not calling txn " + callNumber + " because service is not bound yet",new Exception());return;}int code = IBinder.FIRST_CALL_TRANSACTION + callNumber;try {carService.transact(code, data, null, Binder.FLAG_ONEWAY);} catch (RemoteException e) {handleCarServiceCrash();} catch (RuntimeException e) {throw e;} finally {data.recycle();}}
這個方法很明顯就是跨進(jìn)程傳輸?shù)木唧w實(shí)現(xiàn)了,對端是mCarService即ICarImpl,調(diào)用binder的transact進(jìn)行跨進(jìn)程通信,其code代表需要調(diào)用的對端方法,data為攜帶的傳輸數(shù)據(jù),ICAR_CALL_SET_CAR_SERVICE_HELPER等于0,這里調(diào)用的是對端的0號方法。
于是我們來看看ICar.aidl中定義的0號方法:
interface ICar {.....oneway void setCarServiceHelper(in IBinder helper) = 0;......}
ICarImpl.setCarServiceHelper
接著來看setCarServiceHelper具體實(shí)現(xiàn):
@Overridepublic void setCarServiceHelper(IBinder helper) {//權(quán)限檢查assertCallingFromSystemProcess();ICarServiceHelper carServiceHelper = ICarServiceHelper.Stub.asInterface(helper);synchronized (mLock) {mICarServiceHelper = carServiceHelper;}mSystemInterface.setCarServiceHelper(carServiceHelper);mCarOccupantZoneService.setCarServiceHelper(carServiceHelper);}
這里將ICarServiceHelper的代理端保存在ICarImpl內(nèi)部mICarServiceHelper,同時也傳給了SystemInterface和CarOccupantZoneService,我們暫時不需要知道這三個類拿到ICarServiceHelper的代理端的具體用處,只需要知道他們有能力跨進(jìn)程訪問CarServiceHelperService就行了。
全文解析了車機(jī)開發(fā)中CarFramework框架的CarService啟動流程;車機(jī)開發(fā)的知識點(diǎn)非常的多;總結(jié)如上圖資料文檔參考《車載技術(shù)手冊》,里面內(nèi)容包含以上進(jìn)階技術(shù)。
CarService啟動流程總結(jié)
- 首先CarService是一個系統(tǒng)級別的服務(wù)APK,類似SystemUI,其在開機(jī)時由SystemServer通過CarServiceHelperService啟動。
- CarServiceHelperService通過綁定服務(wù)的方式啟動CarService,啟動之后創(chuàng)建了一個Binder對象ICarImpl,并通過onBind返回給system_server進(jìn)程。
- ICarImpl構(gòu)造方法中創(chuàng)建了一系列和汽車相關(guān)的核心服務(wù),并依次啟動這些服務(wù)即調(diào)用各自init方法。
- ICarImpl返回給CarServiceHelperService之后,CarServiceHelperService也將其內(nèi)部的一個Binder對象(ICarServiceHelperImpl)傳遞到了CarService進(jìn)程,自此CarService和system_server兩個進(jìn)程建立了雙向Binder通信。