美文网首页Car
Android CarService 源码分析

Android CarService 源码分析

作者: HarrisGong | 来源:发表于2019-08-29 11:43 被阅读0次

    第一部分 Android Automative的整体架构

    image.png

    从这幅图中我们可以看出,Android Automative是在原先Android的系统架构上增加了一些与车相关的(图中虚线框中绿色背景的)模块。

    包括:

    Car App:包括OEM和第三方开发的App
    Car API:提供给汽车App特有的接口
    Car Service:系统中与车相关的服务
    Vehicle Network Service:汽车的网络服务
    Vehicle HAL:汽车的硬件抽象层描述

    下面我们采取从上到下的顺序对主要模块做一些介绍。

    Car App

    packages/services/Car/car_product/build/car.mk 这个文件中列出了汽车系统中专有的模块:

    BOARD_PLAT_PUBLIC_SEPOLICY_DIR += packages/services/Car/car_product/sepolicy/public   
    BOARD_PLAT_PRIVATE_SEPOLICY_DIR += packages/services/Car/car_product/sepolicy/private
    
    # Automotive specific packages
    PRODUCT_PACKAGES += \
        CarService \
        CarTrustAgentService \
        CarDialerApp \
        CarRadioApp \
        OverviewApp \
        CarLauncher \
        CarLensPickerApp \
        LocalMediaPlayer \
        CarMediaApp \
        CarMessengerApp \
        CarHvacApp \
        CarMapsPlaceholder \
        CarLatinIME \                                                                                                                                                                                           
        CarSettings \ 
        CarUsbHandler \
        android.car \
        car-frameworks-service \
        com.android.car.procfsinspector \
        libcar-framework-service-jni \
      
    # System Server components 
    PRODUCT_SYSTEM_SERVER_JARS += car-frameworks-service
    
    # should add to BOOT_JARS only once
    ifeq (,$(INCLUDED_ANDROID_CAR_TO_PRODUCT_BOOT_JARS))                                                                                                                                                        
    PRODUCT_BOOT_JARS += \
        android.car
    INCLUDED_ANDROID_CAR_TO_PRODUCT_BOOT_JARS := yes
    endif
    

    这些app源码都位于packages/apps/Car/目录下,OEM厂商可以添加更多的App

    Car API

    packages/services/Car/car-lib/
    开发汽车专有的App自然需要专有的API。这些API对于其他平台(例如手机和平板)通常是没有意义的。所以这些API没有包含在Android Framework SDK中,而是生成在android.car.jar中,源码编译时需要通过在Android.mk中添加LOCAL_JAVA_LIBRARIES += android.car 加入编译,Android Studio需要添加 android.car.jar加入编译,通过INCLUDED_ANDROID_CAR_TO_PRODUCT_BOOT_JARS 加入运行时。
    下面这张大图列出了所有的Car API:

    car_api.png

    从这个图中我们可以看到Car API主要包括:

    android.car:包含了与车相关的基本API。例如:车辆后视镜,门,座位,窗口等。
    annotation:包含了两个注解。
    app
    menu:车辆应用菜单相关API。
    cluster:仪表盘相关API。
    render:渲染相关API。
    content
    pm:应用包相关API。
    diagnostic:包含与汽车诊断相关的API。
    hardware:车辆硬件相关API。
    cabin:座舱相关API。
    hvac:通风空调相关API。(hvac是Heating, ventilation and air conditioning的缩写)
    property:属性相关API。
    radio:收音机相关API。
    input:输入相关API。
    media:多媒体相关API。
    navigation:导航相关API。
    settings:设置相关API。
    vms:汽车监测相关API,见下文。

    CarService

    源码:http://androidxref.com/9.0.0_r3/xref/packages/services/Car/
    Android Automative中的Car Service集中在一个App中。可以想象,这个App需要非常高的权限,所以这是一个系统App。其Manifest开头如下:
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
    package="com.android.car"
    coreApp="true"
    android:sharedUserId="android.uid.system">
    android:sharedUserId属性"android.uid.system"使得这个应用具有系统权限
    Car Service并非一个服务,而是一系列的服务这些服务都在ICarImpl.java构造函数中列了出来。

    public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
                CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) {                                                                                                                               
            mContext = serviceContext;
            mSystemInterface = systemInterface;
            mHal = new VehicleHal(vehicle);
            mVehicleInterfaceName = vehicleInterfaceName;
            mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
            mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(),
                    systemInterface);
            mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal());
            mCarDrivingStateService = new CarDrivingStateService(serviceContext, mCarPropertyService);
            mCarUXRestrictionsService = new CarUxRestrictionsManagerService(serviceContext,
                    mCarDrivingStateService, mCarPropertyService);
            mCarPackageManagerService = new CarPackageManagerService(serviceContext,
                    mCarUXRestrictionsService,
                    mSystemActivityMonitoringService);
            mCarInputService = new CarInputService(serviceContext, mHal.getInputHal());
            mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService);
            mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService);
            mCarLocationService = new CarLocationService(mContext, mCarPowerManagementService,
                    mCarPropertyService);
            mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);
            mCarAudioService = new CarAudioService(serviceContext);
            mCarNightService = new CarNightService(serviceContext, mCarPropertyService);
            mInstrumentClusterService = new InstrumentClusterService(serviceContext,
                    mAppFocusService, mCarInputService);
            mSystemStateControllerService = new SystemStateControllerService(serviceContext,
                    mCarPowerManagementService, mCarAudioService, this);
            mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext);
            mCarBluetoothService = new CarBluetoothService(serviceContext, mCarPropertyService,
                    mPerUserCarServiceHelper, mCarUXRestrictionsService);
            mVmsSubscriberService = new VmsSubscriberService(serviceContext, mHal.getVmsHal());
            mVmsPublisherService = new VmsPublisherService(serviceContext, mHal.getVmsHal());
            mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal());
            mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext,
                    systemInterface);
            mCarConfigurationService =
                    new CarConfigurationService(serviceContext, new JsonReaderImpl());
            mUserManagerHelper = new CarUserManagerHelper(serviceContext);
    

    CarTool

    packages/services/Car/tools

    EVS

    packages/services/Car/evs/

    ODB2

    packages/services/Car/obd2-lib/

    Vehicle Network Service

    HAL

    第二部分 CarService启动流程

    SystemServer启动CarService

    SystemServer里会启动CarServiceHelperService,如下:

                if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {                
                traceBeginAndSlog("StartCarServiceHelperService");
                    mSystemServiceManager.startService(CarServiceHelperService.class);
                    traceEnd();
                }
    

    而CarServiceHelperService.onStart()会bind到CarService,如下:

            Intent intent = new Intent();
            intent.setPackage("com.android.car");
            intent.setAction(CAR_SERVICE_INTERFACE);
            if (!getContext().bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
                    UserHandle.SYSTEM)) { 
                Slog.wtf(TAG, "cannot start car service");
            }
    

    注意:这里用的是bindService方式,mCarServiceConnection是ServiceConnection类对象,它能监听目标Service的状态,当目标Service所在进程异常退出时,会导致其onServiceDisconnected()方法被调用

    CarService启动其他service

    CarService.onCreate()里会创建ICarImpl的实例,并调用ICarImpl.init()方法;

            Log.i(CarLog.TAG_SERVICE, "Service onCreate"); 
            mCanBusErrorNotifier = new CanBusErrorNotifier(this /* context */);
            mVehicle = getVehicle();
     
            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);
            } 
     
            Log.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName);
     
            mICarImpl = new ICarImpl(this, mVehicle, SystemInterface.getDefault(this),
                    mCanBusErrorNotifier);
            mICarImpl.init();
            SystemProperties.set("boot.car_service_created", "1");
     
            linkToDeath(mVehicle, mVehicleDeathRecipient);
     
            super.onCreate();
    

    而ICarImpl.init()里会启动一大堆Service,其中就包括InstrumentClusterService,如下

            // Be careful with order. Service depending on other service should be inited later. 
            List<CarServiceBase> allServices = new ArrayList<>(Arrays.asList(
                    mSystemActivityMonitoringService,
                    mCarPowerManagementService,
                    mCarSensorService,
                    mCarPackageManagerService,
                    mCarInputService,
                    mGarageModeService,
                    mCarInfoService,
                    mAppFocusService,
                    mCarAudioService,
                    mCarCabinService,
                    mCarHvacService,
                    mCarRadioService,
                    mCarNightService,
                    mInstrumentClusterService,
                    mCarProjectionService,
                    mSystemStateControllerService,
                    mCarVendorExtensionService,
                    mCarBluetoothService,
                    mCarDiagnosticService,
                    mPerUserCarServiceHelper
            ));
    

    注意服务启动顺序,依赖于其他服务的service靠后初始化。

    Car App

    通过Car.createCar 获得car,再通过car.getCarManager获得service
    例如,CarAudioManager carAudioManager = car.getCarManager(Car.AUDIO_SERVICE);
    app通过各种CarXXManager获取服务然后注册Listener或者调用接口。

    system.img

    android.car编译并加入PRODUCT_BOOT_JARS,存储路径/system/framework/android.car.jar
    CarService编译后路径为 /system/priv-app/CarService
    其他app编译后路径,例如/system/priv-app/CarLauncher,/system/priv-app/CarMediaApp

    参考:

    https://yq.aliyun.com/articles/610105?utm_content=m_1000006763
    https://www.jianshu.com/p/dacc21e2b32e
    https://www.jianshu.com/p/2c3659800fbc makefile PRODUCT_BOOT_JARS 处理流程及实例

    相关文章

      网友评论

        本文标题:Android CarService 源码分析

        本文链接:https://www.haomeiwen.com/subject/fppmectx.html