Android CarService 源码分析

第一部分 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 处理流程及实例

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容