Android Car

一、Android Car介绍

Android Automotive是Android的一部分。 Android Automotive不是Android的分支或并行开发,它与手机,平板电脑等安卓设备上的Android具有相同的代码库,并且位于相同的存储库中。 它基于经过10多年开发的强大平台和功能集,可利用现有的安全模型,兼容性程序,开发人员工具 和基础架构,同时继续具有高度可定制性和可移植性,完全免费和开源的特点。Android Automotive扩展了Android 。在将Android打造为功能齐全的信息娱乐平台的过程中,添加了对汽车特定要求,功能和技术的支持。

Android Automotive 是在原先Android的系统架构上增加了一些与车相关的模块:

1)Car App :包括OEM和第三方开发的App

2)Car API :提供给汽车App特有的接口

3)Car Service :系统中与车相关的服务,主要基于CarProperty实现Vechile相关的策略

4)Vehicle Network Service :汽车的网络服务

5)Vehicle HAL :汽车的硬件抽象层描述,定义 OEM 可以实现的车辆属性的接口

1、CarAPI

Car API是Android系统中使用Android Automotive特性的系统接口,Car API与CarService中的服务,名称上存在对应关系,所以很好理解。例如:CarWatchdogManager对应CarWatchdogService,CarMediaManager对应CarMediaService。不过也有例外:CarInfoManager、CarSensorManager、CarHvacManager、CarCabinManager、CarVendorExtensionManager都对应CarPropertyService。但是在Android 11中这些Manager都已经过时,Google建议统一使用CarPropertyManager。

2、CarService

车载Android 系统的核心服务之一,所有应用都需要通过 CarService 来查询、控制整车的状态。例如:车辆的速度、档位、点火状态等等,CarService有许多子服务,负责具体功能。

Service端功能Client端

AppFocusService

应用程序焦点服务:确保一次只有一个应用程序类型的实例处于活动状态。

CarAppFocusManager

CarAudioService

汽车音频服务:负责与汽车音响系统交互的服务。

CarAudioManager

CarPowerManagerService

汽车电源管理服务:汽车电源管理服务。控制电源状态并与系统的其他部分交互以确保其自身状态。

CarPowerManager

CarPropertyService

汽车属性服务:此类实现 ICarProperty 的binder接口。有助于更容易地创建处理车辆属性的多个Manager。

CarPropertyManager

CarProjectionService

汽车投屏服务

CarProjectionManager

CarPackageManagerService

汽车包管理服务

CarPackageManager

CarDiagnosticService

汽车诊断服务

CarDiagnosticManager

CarProjecitonService

汽车投屏服务

CarProjecitonManager

CarMediaService

汽车媒体管理服务

CarMediaManager

CarConfigurationService

汽车配置服务

CarConfigurationManager

CarBluetoothService

汽车蓝牙服务

CarBluetoothManager

CarDrivingStateService

汽车驾驶状态服务:推断车辆当前驾驶状态的服务。它通过侦听 CarPropertyService 的相关属性来计算驾驶状态。

CarDrivingStateManager

CarStorageMonitoringService

汽车存储监控服务

CarStorageMonitoringManager

CarMediaService

汽车媒体服务:管理汽车应用程序的当前活动媒体源。这与 MediaSessionManager 的活动会话不同,因为同一时间内车内只能有一个活动源。

CarMediaManager

CarInputService

汽车输入服务:通过车辆HAL监控和处理输入事件。

CarInputManager

CarLocationService

汽车定位服务:此服务在车辆停放时存储 LocationManager 中最后一个已知位置,并在车辆通电时恢复该位置。

CarLocationManager

CarEvsService

汽车摄像头服务

CarEvsManager

CarTelemetryService

汽车电话服务

CarTelemetryManager

CarDevicePolicyService

汽车设备策略服务

CarDevicePolicyManager

CarActivityService

汽车活动服务

CarActivityManager

CarPerformanceService

汽车性能服务

CarPerformanceManager

CarWatchdogService

汽车看门狗服务:实现 CarWatchdogManager API的服务。 CarWatchdogService 作为汽车监控中介运行,它检查客户端的健康状况,并将结果报告给汽车监控服务器。

CarWatchdogManager

CarTestService

汽车测试服务:允许测试/模拟车辆HAL的服务。该服务直接使用车辆HAL API,因为车辆HAL模拟无论如何都需要直接访问该级别。

CarTestManager

CarUXRestrictionsService

汽车用户体验限制服务

CarUXRestrictionsManager

CarOccupantZoneService

汽车乘员区服务

CarOccupantZoneManager

CarBugreportManagerService

汽车错误报告管理器服务

CarBugreportManager

CarUserService

汽车用户服务

CarUserManager

CarUserNoticeService

向用户显示初始通知UI的服务:它仅在启用设置时启动它,并根据用户的请求通知UI自行关闭。

CarUserNoticeManager

ClusterHomeService

仪表Hoem服务

ClusterHomeManager

ClusterNavigationService

仪表导航服务

ClusterNavigationManager

OccupantAwarenessService

跨HAL边界侦听乘员感知检测系统的服务

OccupantAwarenessManager

VmsBrokerService

消息代理服务,用于在客户端之间路由车辆映射服务消息, 地图导航相关

VMS客户端实现,使用HAL特定消息编码将VmsPublisher/VmsSubscriber API调用代理到车辆HAL。

-

3、Vehicle HAL

用于处理车辆相关数据,底层通过RPC通信接收MCU数据和发送数据给MCU,作为CarPropertyService和CarPowerManagerService的底层实现电源控制与车辆属性控制功能。

二、Android汽车子系统相关类

1、CarService

CarService是车载Android系统的核心服务之一,所有应用都需要通过CarService来查询、控制整车的状态。不仅仅是车辆控制,实际上CarService几乎就是整个车载Framework最核心的组件。提供了一系列的服务与HAL层的VehicleHAL通信,进而通过车载总线(例如CAN总线)与车身进行通讯,同时它们还为应用层的APP提供接口,从而让APP能够实现对车身的控制与状态的显示。

CarService代码位于:

packages/services/Car/car-lib/src/android/car/ICar.aidl

packages/services/Car/service/src/com/android/car/ICarImpl.java

packages/services/Car/service/src/com/android/car/CarServiceBase.java

packages/services/Car/service/src/com/android/car/CarServiceUtils.java

packages/services/Car/service/src/com/android/car/CarServiceImpl.java

packages/services/Car/service-builtin/src/com/android/car/CarService.java

frameworks/opt/car/services/builtInServices/src/com/android/internal/car/CarServiceHelperService .java

CarService的定义:

interface ICar {}
public interface CarServiceBase {}
public final class CarServiceUtils {}
public class ICarImpl extends ICar.Stub {}
public class CarService extends ServiceProxy {}
public class CarServiceImpl extends ProxiedService {}
public class CarServiceHelperService extends SystemService implements Dumpable, DevicePolicySafetyChecker, CarServiceHelperInterface {}

2、SystemInterface

此类包含对CarService 和 Android OS API。

SystemInterface代码位于:packages/services/Car/service/src/com/android/car/systeminterface/SystemInterface.java

SystemInterface的定义:

public class SystemInterface implements ActivityManagerInterface,
        DisplayInterface, IOInterface, StorageMonitoringInterface,
        SystemStateInterface, TimeInterface,
        WakeLockInterface {}

三、CarService配置

需要根据OEM需要对CarService进行配置,配置文件路径为packages/services/Car/services/res/values/config.xml,配置内容如下:

audioUseDynamicRouting:Configuration to enable usage of dynamic audio routing.

audioUseCarVolumeGroupMuting:Configuration to enable muting of individual volume groups.

audioUseHalDuckingSignals:Configuration to enable IAudioControl#onDevicesToDuckChange API to inform HAL when to duck.

audioVolumeAdjustmentContextsVersion:Configuration to select version of volume adjustment context priority list.

audioPersistMasterMuteState:Configuration to persist global mute state.

audioVolumeKeyEventTimeoutMs:Configuration to indicate the timeout in milliseconds while a car volume group will be considered active for volume control changes during volume key events.

displayOffMuteLockAllAudio:Whether to block other audio while media audio is muted with display off. When set to true, other sounds cannot be played either while display is off.

useDefaultBluetoothConnectionPolicy:Configuration to enable or disable the default Bluetooth Device Connection Policy.

useDefaultBluetoothPowerPolicy:Configuration to enable or disable the default Bluetooth Power Policy.

instrumentClusterRendererService:Service responsible for displaying information on the car instrument cluster.

config_clusterHomeActivity:The name of Activity who is in charge of ClusterHome.

rotaryService:Service responsible for handling the rotary controller input.

enableActivityBlockingForSafety:Whether to enable Activity blocking for safety.

activityBlockingActivity:Activity to be presented when un-safe activity is launched.

continuousBlankActivity:

activityAllowlist:Comma separated list of activities that need to be exempted from getting blocked in a UX restricted state.

systemActivityAllowlist:Comma separated list of activities that need to be exempted from getting blocked in a UX restricted state.

activityDenylist:Comma separated list of activities that will be blocked during restricted state.

defaultHomeActivity:Default home activity

vmsHalClientMetricsProperty:The vendor-defined HAL property used to collect VMS client metrics. Disabled by default.

vmsPublisherSystemClients:The com.android.car.vms.VmsClientManager will bind to this list of clients running as system user

vmsPublisherUserClients:The com.android.car.vms.VmsClientManager will bind to this list of clients running as current user

millisecondsBeforeRebindToVmsPublisher:Number of milliseconds to wait before trying re-bind to a crashed publisher.

acceptableHoursPerOnePercentFlashWear:Hours of uptime (excluding sleep) after which a 1% increase in the wear of the flash storage in the head-unit is considered as acceptable level of wear.

uptimeHoursIntervalBetweenUptimeDataWrite:How often (in hours of uptime excluding sleep) CarService will flush to disk information about the total running time of the head-unit.

activityHandlerForFlashWearChanges:The name of an activity to be launched by CarService whenever it detects a change in the level of wear of the flash storage.

ioStatsRefreshRateSeconds:How often (in seconds) CarService will update I/O metrics from the kernel.

ioStatsNumSamplesToStore:The number of I/O metrics samples to keep in memory at one time.

acceptableWrittenKBytesPerSample:The maximum number of KB (1024 bytes) that can be written to storage in one sample before CarService deems I/O activity excessive.

acceptableFsyncCallsPerSample:The maximum number of fsync() system calls that can be made in one sample before CarService deems I/O activity excessive.

maxExcessiveIoSamplesInWindow:The maximum number of samples (within an I/O stats sample window) that CarService should consider exhibiting excessive I/O activity before broadcasting an intent to signal the potential for flash wear.

recurringResourceOverusePeriodInDays:The number of days past until the current day considered by car watchdog to attribute recurring overuse to a package.

recurringResourceOveruseTimes:The number of overuses a package has to exceed for car watchdog to attribute recurring overuse.

uidIoUsageSummaryTopCount:The number of top UID I/O usage summaries to report on car watchdog I/O usage summary atom pull.

ioUsageSummaryMinSystemTotalWrittenBytes:The minimum number of total bytes written to disk by the system required to report the stats on car watchdog I/O usage summary atom pull. Currently 500 MiB.

intentReceiverForUnacceptableIoMetrics:The name of an intent to be notified by CarService whenever it detects too many samples with excessive I/O activity.

eMmcLifetimeFilePath:The path to a file that contains lifetime estimation metrics for the eMMC storage on this system, in the lifetimeA lifetimeB format, as defined by the eMMC extended CSD register specification.

eMmcEolFilePath:The path to a file that contains end of life estimation metrics for the eMMC storage on this system, in the format defined by the eMMC extended CSD register specification.

fastPairModelId:The Model ID to advertise Bluetooth Fast Pair connections with.

fastPairAntiSpoofKey:The Anti Spoofing Public key associated with the advertised Fast Pair Model ID, base64 encoded.

fastPairAutomaticAcceptance:Enable to allow Fast Pair to automatically accept incoming pairing requests with matching Simple Secure Pairing codes without requiring further user input.

maxGarageModeRunningDurationInSecs:Maximum allowed time to run garage mode.

config_earlyStartupServices:The services that needs to be started earlier in the boot sequence and in particular order.

config_projectionConsentActivity:The consent activity that must be shown for every unknown mobile device before projection gets started.

config_projectionActivityDisplayId:Display Id where projection rendering activity needs to be shown, Specify -1 to use system defaults

config_projectionActivityLaunchBounds:Bounds of the projection activity on the screen. It should be in the pixels and screen coordinates in the following order: left, top, right, bottom.

config_projectionUiMode:UI mode for projection activity.

config_projectionAccessPointTethering:Configure whether access point created for wireless projection should be in tethered mode.

config_stableLocalOnlyHotspotConfig:If projection Access Point is configured to not provide Internet access (not tethered, see config_projectionAccessPointTethering) then this flag will be used to control whether Wi-Fi configuration will persist reboots.

serviceMediaConnection:The package name of a service to be launched by CarService to bind to an active media service on the current user.

config_car_bugreport_application:The package name of the default bugreport application that can use CarBugreportServiceManager.

config_occupant_zones:Lists all occupant (= driver + passenger) zones available in the car.

config_occupant_display_mapping:Specifies configuration of displays in system telling its usage / type and assigned occupant.

config_sourcePreferredComponents:Specifies whether CarLaunchParamControl prefers source.

config_userNoticeUiService:Specifies notice UI that will be launched when user starts a car or do user switching.

config_mediaSourceChangedAutoplay:Configuration to enable media center to autoplay when the media source is changed.

config_mediaBootAutoplay:Configuration to enable media center to autoplay on boot

config_mediaSourceIndependentPlayback:Setting this flag to true allows for browsing a different source than the one that is currently playing audio.

config_allowed_optional_car_features:Specifies optional features that can be enabled by this image.

enablePassengerSupport:Configuration to enable passenger support.

config_customCountryDetector:Class name of the custom country detector to be used.

enableLongPressBluetoothVoiceRecognition:Controls the use of bluetooth voice recognition when long pressing the voice assist button.

config_switchGuestUserBeforeGoingSleep:Switch guest user into new guest user before going to sleep.

enableProfileUserAssignmentForMultiDisplay:Enable profile user assignment per each CarOccupantZone for per display android user assignments.

config_defaultMediaSource:The ComponentName of the media source that will be selected as the default

config_callButtonEndsOngoingCall:A configuration flag to enable ending an ongoing call using the physical Call button.

config_maxSuspendWaitDuration:Number of milliseconds to wait before the system goes into Suspend-to-RAM.

config_preShutdownPrepareTimeout:Number of milliseconds to wait until all listeners complete when PRE_SHUTDOWN_PREPARE is notified

config_shutdownEnterTimeout:Number of milliseconds to wait until all listeners complete when SHUTDOWN_ENTER is notified

config_postShutdownEnterTimeout:Number of milliseconds to wait until all listeners complete when POST_SHUTDOWN_ENTER is notified

config_evsRearviewCameraId:A name of a camera device that provides the rearview through EVS service

config_evsCameraActivity:The camera Activity name for EVS, if defined, the Activity will be launched by CarEvsService.

config_wifiAdjustmentForSuspend:A configuration flag to adjust Wifi for suspend.

config_enableCarLocationServiceGnssControlsForPowerManagement:A configuration flag to adjust enabling and disabling the GNSS Location Provider for Power Management purposes such as Supsend to RAM.

config_preventTemplatedAppsFromShowingDialog:A configuration flag to prevent the templated apps from showing dialogs.

config_template_activity_class_name:The class name of the templated activities.

config_enableExternalCarTimeToExternalTimeSuggestion:A flag to configure whether the ExternalCarTime VHAL property should be used to send ExternalTimeSuggestions to the Android TimeManager service.

config_userPreCreationStage:Configuration to set when pre-created users should be managed by CarService.

config_userPreCreationDelay:How many milli-seconds CarService should wait before managing pre-created users after system start.

config_oemCarService:This is the component name for the OEM customization service.

config_oemCarService_connection_timeout_ms:Related to OEM customization service.

config_oemCarService_serviceReady_timeout_ms:Related to OEM customization service.

config_oemCarService_regularCall_timeout_ms:Related to OEM customization service.

config_oemCarService_crashCall_timeout_ms:Related to OEM customization service.

config_oemCarService_thread_pool_size:Related to OEM customization service.

四、CarService流程介绍

CarService的启动流程大致如下:

  • SystemServer启动CarServiceHelperService服务

  • 在调用startService后,CarServiceHelperService的onStart方法通过bindService的方式启动CarService(一个系统级别的APK,位于system/priv-app)

  • 启动CarService后首先调用onCreate,创建ICarImpl对象并初始化,在此时创建了一系列car相关的核心服务,并遍历init初始化

  • 然后调用onBind将该ICarImpl对象返回给CarServiceHelperService,CarServiceHelperService在内部的一个Binder对象ICarServiceHelperImpl传递给CarService,建立双向跨进程

如下为流程图:

1、系统启动后在SystemServer进程中启动CarServiceHelperService

在SystemServer的startOtherServices()中会启动CarServiceHelperService服务:

//frameworks/base/services/java/com/android/server/SystemServer.java    
public final class SystemServer implements Dumpable {
    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
private static final String CAR_SERVICE_HELPER_SERVICE_CLASS =
            "com.android.internal.car.CarServiceHelperService";
            ......
            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
                traceBeginAndSlog("StartCarServiceHelperService");
                mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS); 调用SystemServiceManager启动CarServiceHelperService服务
                traceEnd();
            }
    }
}

因为前面我们传入的参数为com.android.internal.car.CarServiceHelperService,所以SystemServiceManager的startService方法首先会通过反射创建CarServiceHelperService对象实例,然后将其存储在类型ArrayList的mServices中,紧接着会调用CarServiceHelperService的onStart方法,CarServiceHelperService的onStart方法如下所示:

//frameworks/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java 
public class CarServiceHelperService extends SystemService
        implements Dumpable, DevicePolicySafetyChecker {
    
    @Override
    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);
        //通过bindService绑定车机服务CarService
        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");
    }
}

CarServiceHelperService的onStart方法首先创建一个Action为android.car.ICar,包名为com.android.car的Intent,然后通过bindService的方式启动该Intent对应的服务,而这个服务正是车机模块才有的CarService服务。

2、CarService启动

系统关于CarService服务的声明如下所示:

//packages/services/Car/service/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<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">
    <!--...代码省略...-->       
    <application android:label="@string/app_title"
         android:directBootAware="true"
         android:allowBackup="false"
         android:persistent="true">


        <service android:name=".CarService"
             android:singleUser="true"
             android:exported="true">
            <intent-filter>
                <action android:name="android.car.ICar"/>
            </intent-filter>
        </service>
        <!--...代码省略...-->       
   </application>
</manifest>     

结合这个配置文件我们可以知道CarServiceHelperService最终所启动的,就是CarService这个服务,CarService的代码如下所示:

//packages/services/Car/service-builtin/src/com/android/car/CarService.java
/** Proxy service for CarServciceImpl */
public class CarService extends ServiceProxy {
    public CarService() {
        super(UpdatablePackageDependency.CAR_SERVICE_IMPL_CLASS);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // keep it alive.
        return START_STICKY;
    }
}

CarService里面啥也没有,实际的处理都在CarServciceImpl里面:

//packages/services/Car/service/src/com/android/car/CarServiceImpl.java
/** Implementation of CarService */
public class CarServiceImpl extends ProxiedService {
    public static final String CAR_SERVICE_INIT_TIMING_TAG = "CAR.InitTiming";
    public static final int CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS = 5;
    private ICarImpl mICarImpl;
    private VehicleStub mVehicle;
    private String mVehicleInterfaceName;
    private final VehicleDeathRecipient mVehicleDeathRecipient = new VehicleDeathRecipient();


    @Override
    public void onCreate() {
        LimitedTimingsTraceLog initTiming = new LimitedTimingsTraceLog(CAR_SERVICE_INIT_TIMING_TAG,
                TraceHelper.TRACE_TAG_CAR_SERVICE, CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS);
        initTiming.traceBegin("CarService.onCreate");


        initTiming.traceBegin("getVehicle");
        mVehicle = VehicleStub.newVehicleStub();
        initTiming.traceEnd(); // "getVehicle"
        EventLogHelper.writeCarServiceCreate(/* hasVhal= */ mVehicle.isValid());
        mVehicleInterfaceName = mVehicle.getInterfaceDescriptor();
        Slogf.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName);
        EventLogHelper.writeCarServiceConnected(mVehicleInterfaceName);


        mICarImpl = new ICarImpl(this, 
                getBuiltinPackageContext(),
                mVehicle,
                SystemInterface.Builder.defaultSystemInterface(this).build(),
                mVehicleInterfaceName); // 创建ICarImpl 对象
        mICarImpl.init(); //调用mICarImpl的初始化方法
        mVehicle.linkToDeath(mVehicleDeathRecipient);
        //将ICarImpl存储到系统服务管理者ServiceManager中
        ServiceManagerHelper.addService("car_service", mICarImpl);
        SystemPropertiesHelper.set("boot.car_service_created", "1");
        super.onCreate();
        initTiming.traceEnd(); // "CarService.onCreate"
    }


    // onDestroy is best-effort and might not get called on shutdown/reboot. As such it is not
    // suitable for permanently saving state or other need-to-happen operation. If you have a
    // cleanup task that you want to make sure happens on shutdown/reboot, see OnShutdownReboot.
    @Override
    public void onDestroy() {
        EventLogHelper.writeCarServiceDestroy(/* hasVhal= */ mVehicle.isValid());
        Slogf.i(CarLog.TAG_SERVICE, "Service onDestroy");
        mICarImpl.release();
        mVehicle.unlinkToDeath(mVehicleDeathRecipient);
        mVehicle = null;
        super.onDestroy();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // keep it alive.
        return START_STICKY;
    }


    @Override
    public IBinder onBind(Intent intent) {
        return mICarImpl;
    }


    @Override
    @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        // historically, the way to get a dumpsys from CarService has been to use
        // "dumpsys activity service com.android.car/.CarService" - leaving this
        // as a forward to car_service makes the previously well-known command still work
        mICarImpl.dump(fd, writer, args);
    }


    private static class VehicleDeathRecipient implements IVehicleDeathRecipient {


        @Override
        public void serviceDied(long cookie) {
            EventLogHelper.writeCarServiceVhalDied(cookie);
            Slogf.wtf(CarLog.TAG_SERVICE, "***Vehicle HAL died. Car service will restart***");
            Process.killProcess(Process.myPid());
        }


        @Override
        public void binderDied() {
            EventLogHelper.writeCarServiceVhalDied(/*cookie=*/ 0);
            Slogf.wtf(CarLog.TAG_SERVICE, "***Vehicle HAL died. Car service will restart***");
            Process.killProcess(Process.myPid());
        }
    }
}

CarService的onCreate方法会创建一个关键对象ICarImpl的实例,并将该实例赋值给mICarImpl属性变量,然后会调用该对象的init方法,之后还会将mICarImpl存储到ServiceManager中。另外结合CarService的onBind方法我们可以知道,CarServiceHelperService通过bindService方式开启CarService,CarService会返回mICarImpl对象,通过该Binder对象使二者建立双向跨进程通信。

//packages/services/Car/service/src/com/android/car/ICarImpl.java
public class ICarImpl extends ICar.Stub {
    private final VehicleHal mHal;
    private final CarServiceBase[] mAllServices;


    public ICarImpl(Context serviceContext, Context builtinContext, VehicleStub vehicle,
            SystemInterface systemInterface, String vehicleInterfaceName) {
        this(serviceContext, builtinContext, vehicle, systemInterface, vehicleInterfaceName,
                /* carUserService= */ null, /* carWatchdogService= */ null,
                /* carPerformanceService= */ null, /* garageModeService= */ null,
                /* powerPolicyDaemon= */ null, /*carTelemetryService= */ null);
    }


    ICarImpl(Context serviceContext, @Nullable Context builtinContext, VehicleStub vehicle,
            SystemInterface systemInterface, String vehicleInterfaceName,
            @Nullable CarUserService carUserService,
            @Nullable CarWatchdogService carWatchdogService,
            @Nullable CarPerformanceService carPerformanceService,
            @Nullable GarageModeService garageModeService,
            @Nullable ICarPowerPolicySystemNotification powerPolicyDaemon,
            @Nullable CarTelemetryService carTelemetryService) {
        LimitedTimingsTraceLog t = new LimitedTimingsTraceLog(
                CAR_SERVICE_INIT_TIMING_TAG, TraceHelper.TRACE_TAG_CAR_SERVICE,
                CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS);
        t.traceBegin("ICarImpl.constructor");


        mContext = serviceContext;
        if (builtinContext == null) {
            mCarServiceBuiltinPackageContext = serviceContext;
        } else {
            mCarServiceBuiltinPackageContext = builtinContext;
        }
        mSystemInterface = systemInterface;
         //创建VehicleHal
        CarLocalServices.addService(SystemInterface.class, mSystemInterface);
        mHal = constructWithTrace(t, VehicleHal.class,
                () -> new VehicleHal(serviceContext, vehicle));


        t.traceBegin("VHAL.earlyInit");
        // Do this before any other service components to allow feature check. It should work
        // even without init. For that, vhal get is retried as it can be too early.
        HalPropValue disabledOptionalFeatureValue = mHal.getIfAvailableOrFailForEarlyStage(
                VehicleProperty.DISABLED_OPTIONAL_FEATURES, INITIAL_VHAL_GET_RETRY);
        t.traceEnd();


        String[] disabledFeaturesFromVhal = null;
        if (disabledOptionalFeatureValue != null) {
            String disabledFeatures = disabledOptionalFeatureValue.getStringValue();
            if (disabledFeatures != null && !disabledFeatures.isEmpty()) {
                disabledFeaturesFromVhal = disabledFeatures.split(",");
            }
        }
        if (disabledFeaturesFromVhal == null) {
            disabledFeaturesFromVhal = new String[0];
        }
        Resources res = mContext.getResources();
        String[] defaultEnabledFeatures = res.getStringArray(
                R.array.config_allowed_optional_car_features);
        final String[] disabledFromVhal = disabledFeaturesFromVhal;
        mFeatureController = constructWithTrace(t, CarFeatureController.class,
                () -> new CarFeatureController(serviceContext, defaultEnabledFeatures,
                        disabledFromVhal, mSystemInterface.getSystemCarDir()));
        mVehicleInterfaceName = vehicleInterfaceName;


//创建各种子服务对象
        mCarPropertyService = constructWithTrace(
                t, CarPropertyService.class,
                () -> new CarPropertyService(serviceContext, mHal.getPropertyHal()));
        mCarDrivingStateService = constructWithTrace(
                t, CarDrivingStateService.class,
                () -> new CarDrivingStateService(serviceContext, mCarPropertyService));
        mCarOccupantZoneService = constructWithTrace(t, CarOccupantZoneService.class,
                () -> new CarOccupantZoneService(serviceContext));
        mCarUXRestrictionsService = constructWithTrace(t, CarUxRestrictionsManagerService.class,
                () -> new CarUxRestrictionsManagerService(serviceContext, mCarDrivingStateService,
                        mCarPropertyService, mCarOccupantZoneService));
        if (carUserService != null) {
            mCarUserService = carUserService;
            CarLocalServices.addService(CarUserService.class, carUserService);
        } else {
            UserManager userManager = serviceContext.getSystemService(UserManager.class);
            int maxRunningUsers = UserManagerHelper.getMaxRunningUsers(serviceContext);
            mCarUserService = constructWithTrace(t, CarUserService.class,
                    () -> new CarUserService(serviceContext, mHal.getUserHal(), userManager,
                            maxRunningUsers, mCarUXRestrictionsService));
        }
        if (mFeatureController.isFeatureEnabled(Car.EXPERIMENTAL_CAR_USER_SERVICE)) {
            mExperimentalCarUserService = constructWithTrace(t, ExperimentalCarUserService.class,
                    () -> new ExperimentalCarUserService(serviceContext, mCarUserService,
                            serviceContext.getSystemService(UserManager.class)));
        } else {
            mExperimentalCarUserService = null;
        }
        mSystemActivityMonitoringService = constructWithTrace(
                t, SystemActivityMonitoringService.class,
                () -> new SystemActivityMonitoringService(serviceContext));
        mCarPowerManagementService = constructWithTrace(
                t, CarPowerManagementService.class,
                () -> new CarPowerManagementService(mContext, mHal.getPowerHal(),
                        systemInterface, mCarUserService, powerPolicyDaemon));
        if (mFeatureController.isFeatureEnabled(CarFeatures.FEATURE_CAR_USER_NOTICE_SERVICE)) {
            mCarUserNoticeService = constructWithTrace(
                    t, CarUserNoticeService.class, () -> new CarUserNoticeService(serviceContext));
        } else {
            mCarUserNoticeService = null;
        }
        if (mFeatureController.isFeatureEnabled(Car.OCCUPANT_AWARENESS_SERVICE)) {
            mOccupantAwarenessService = constructWithTrace(t, OccupantAwarenessService.class,
                    () -> new OccupantAwarenessService(serviceContext));
        } else {
            mOccupantAwarenessService = null;
        }
        mCarActivityService = constructWithTrace(t, CarActivityService.class,
                () -> new CarActivityService(serviceContext));
        mCarPackageManagerService = constructWithTrace(t, CarPackageManagerService.class,
                () -> new CarPackageManagerService(serviceContext, mCarUXRestrictionsService,
                        mCarActivityService, mCarOccupantZoneService));
        mPerUserCarServiceHelper = constructWithTrace(
                t, PerUserCarServiceHelper.class,
                () -> new PerUserCarServiceHelper(serviceContext, mCarUserService));
        mCarBluetoothService = constructWithTrace(t, CarBluetoothService.class,
                () -> new CarBluetoothService(serviceContext, mPerUserCarServiceHelper));
        mCarInputService = constructWithTrace(t, CarInputService.class,
                () -> new CarInputService(serviceContext, mHal.getInputHal(), mCarUserService,
                        mCarOccupantZoneService, mCarBluetoothService));
        mCarProjectionService = constructWithTrace(t, CarProjectionService.class,
                () -> new CarProjectionService(serviceContext, null /* handler */, mCarInputService,
                        mCarBluetoothService));
        if (garageModeService == null) {
            mGarageModeService = constructWithTrace(t, GarageModeService.class,
                    () -> new GarageModeService(mContext));
        } else {
            mGarageModeService = garageModeService;
        }
        mAppFocusService = constructWithTrace(t, AppFocusService.class,
                () -> new AppFocusService(serviceContext, mSystemActivityMonitoringService));
        mCarAudioService = constructWithTrace(t, CarAudioService.class,
                () -> new CarAudioService(serviceContext));
        mCarNightService = constructWithTrace(t, CarNightService.class,
                () -> new CarNightService(serviceContext, mCarPropertyService));
        mFixedActivityService = constructWithTrace(t, FixedActivityService.class,
                () -> new FixedActivityService(serviceContext, mCarActivityService));
        mClusterNavigationService = constructWithTrace(
                t, ClusterNavigationService.class,
                () -> new ClusterNavigationService(serviceContext, mAppFocusService));
        if (mFeatureController.isFeatureEnabled(Car.CAR_INSTRUMENT_CLUSTER_SERVICE)) {
            mInstrumentClusterService = constructWithTrace(t, InstrumentClusterService.class,
                    () -> new InstrumentClusterService(serviceContext,
                            mClusterNavigationService, mCarInputService));
        } else {
            mInstrumentClusterService = null;
        }
        mCarStatsService = constructWithTrace(t, CarStatsService.class, () -> {
            // This service should be initialized here.
            CarStatsService service = new CarStatsService(serviceContext);
            service.init();
            return service;
        });
        if (mFeatureController.isFeatureEnabled(Car.VEHICLE_MAP_SERVICE)) {
            mVmsBrokerService = constructWithTrace(t, VmsBrokerService.class,
                    () -> new VmsBrokerService(mContext, mCarStatsService));
        } else {
            mVmsBrokerService = null;
        }
        if (mFeatureController.isFeatureEnabled(Car.DIAGNOSTIC_SERVICE)) {
            mCarDiagnosticService = constructWithTrace(t, CarDiagnosticService.class,
                    () -> new CarDiagnosticService(serviceContext,
                            mHal.getDiagnosticHal()));
        } else {
            mCarDiagnosticService = null;
        }
        if (mFeatureController.isFeatureEnabled(Car.STORAGE_MONITORING_SERVICE)) {
            mCarStorageMonitoringService = constructWithTrace(
                    t, CarStorageMonitoringService.class,
                    () -> new CarStorageMonitoringService(serviceContext,
                            systemInterface));
        } else {
            mCarStorageMonitoringService = null;
        }
        mCarLocationService = constructWithTrace(t, CarLocationService.class,
                () -> new CarLocationService(serviceContext));
        mCarMediaService = constructWithTrace(t, CarMediaService.class,
                () -> new CarMediaService(serviceContext, mCarUserService));
        mCarBugreportManagerService = constructWithTrace(t, CarBugreportManagerService.class,
                () -> new CarBugreportManagerService(serviceContext));
        if (!BuildHelper.isUserBuild()) {
            mCarExperimentalFeatureServiceController = constructWithTrace(
                    t, CarExperimentalFeatureServiceController.class,
                    () -> new CarExperimentalFeatureServiceController(serviceContext));
        } else {
            mCarExperimentalFeatureServiceController = null;
        }
        if (carWatchdogService == null) {
            mCarWatchdogService = constructWithTrace(t, CarWatchdogService.class,
                    () -> new CarWatchdogService(serviceContext, mCarServiceBuiltinPackageContext));
        } else {
            mCarWatchdogService = carWatchdogService;
        }
        if (carPerformanceService == null) {
            mCarPerformanceService = constructWithTrace(t, CarPerformanceService.class,
                    () -> new CarPerformanceService(serviceContext));
        } else {
            mCarPerformanceService = carPerformanceService;
        }
        mCarDevicePolicyService = constructWithTrace(
                t, CarDevicePolicyService.class, () -> new CarDevicePolicyService(mContext,
                        mCarServiceBuiltinPackageContext, mCarUserService));
        if (mFeatureController.isFeatureEnabled(Car.CLUSTER_HOME_SERVICE)) {
            if (!mFeatureController.isFeatureEnabled(Car.CAR_INSTRUMENT_CLUSTER_SERVICE)) {
                mClusterHomeService = constructWithTrace(
                        t, ClusterHomeService.class,
                        () -> new ClusterHomeService(serviceContext, mHal.getClusterHal(),
                                mClusterNavigationService, mCarOccupantZoneService,
                                mFixedActivityService));
            } else {
                Slogf.w(TAG, "Can't init ClusterHomeService, since Old cluster service is running");
                mClusterHomeService = null;
            }
        } else {
            mClusterHomeService = null;
        }


        if (mFeatureController.isFeatureEnabled(Car.CAR_EVS_SERVICE)) {
            mCarEvsService = constructWithTrace(t, CarEvsService.class,
                    () -> new CarEvsService(serviceContext, mCarServiceBuiltinPackageContext,
                            mHal.getEvsHal(), mCarPropertyService));
        } else {
            mCarEvsService = null;
        }


        if (mFeatureController.isFeatureEnabled(Car.CAR_TELEMETRY_SERVICE)) {
            if (carTelemetryService == null) {
                mCarTelemetryService = constructWithTrace(t, CarTelemetryService.class,
                        () -> new CarTelemetryService(serviceContext, mCarPropertyService));
            } else {
                mCarTelemetryService = carTelemetryService;
            }
        } else {
            mCarTelemetryService = null;
        }


//将服务对象放置一个list中。这样在init方法中就可以以循环的形式直接调用服务对象的init,而不需要一个个调用。
        // Be careful with order. Service depending on other service should be inited later.
        List<CarServiceBase> allServices = new ArrayList<>();
        allServices.add(mFeatureController);
        allServices.add(mCarPropertyService); // mCarUXRestrictionsService depends on it
        allServices.add(mCarOccupantZoneService); // mCarUXRestrictionsService depends on it
        allServices.add(mCarUXRestrictionsService); // mCarUserService depends on it
        allServices.add(mCarUserService);
        addServiceIfNonNull(allServices, mExperimentalCarUserService);
        allServices.add(mSystemActivityMonitoringService);
        allServices.add(mCarPowerManagementService);
        allServices.add(mCarDrivingStateService);
        addServiceIfNonNull(allServices, mOccupantAwarenessService);
        allServices.add(mCarPackageManagerService);
        allServices.add(mCarInputService);
        allServices.add(mGarageModeService);
        addServiceIfNonNull(allServices, mCarUserNoticeService);
        allServices.add(mAppFocusService);
        allServices.add(mCarAudioService);
        allServices.add(mCarNightService);
        allServices.add(mFixedActivityService);
        allServices.add(mClusterNavigationService);
        addServiceIfNonNull(allServices, mInstrumentClusterService);
        allServices.add(mPerUserCarServiceHelper);
        allServices.add(mCarBluetoothService);
        allServices.add(mCarProjectionService);
        addServiceIfNonNull(allServices, mCarDiagnosticService);
        addServiceIfNonNull(allServices, mCarStorageMonitoringService);
        addServiceIfNonNull(allServices, mVmsBrokerService);
        allServices.add(mCarMediaService);
        allServices.add(mCarLocationService);
        allServices.add(mCarBugreportManagerService);
        allServices.add(mCarWatchdogService);
        allServices.add(mCarPerformanceService);
        allServices.add(mCarDevicePolicyService);
        addServiceIfNonNull(allServices, mClusterHomeService);
        addServiceIfNonNull(allServices, mCarEvsService);
        addServiceIfNonNull(allServices, mCarTelemetryService);
        allServices.add(mCarActivityService);


        // Always put mCarExperimentalFeatureServiceController in last.
        addServiceIfNonNull(allServices, mCarExperimentalFeatureServiceController);
        mAllServices = allServices.toArray(new CarServiceBase[allServices.size()]);


        mICarSystemServerClientImpl = new ICarSystemServerClientImpl();


        t.traceEnd(); // "ICarImpl.constructor"
    }


    private void addServiceIfNonNull(List<CarServiceBase> services, CarServiceBase service) {
        if (service != null) {
            services.add(service);
        }
    }


    void init() {
        LimitedTimingsTraceLog t = new LimitedTimingsTraceLog(CAR_SERVICE_INIT_TIMING_TAG,
                TraceHelper.TRACE_TAG_CAR_SERVICE, CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS);


        t.traceBegin("ICarImpl.init");
        t.traceBegin("VHAL.init");
        mHal.init(); //调用VehicleHal 初始化方法
        t.traceEnd();


        t.traceBegin("CarService.initAllServices");
        for (CarServiceBase service : mAllServices) {
            t.traceBegin(service.getClass().getSimpleName());
            service.init(); //初始所有子服务
            t.traceEnd();
        }
        t.traceEnd(); // "CarService.initAllServices"
        t.traceEnd(); // "ICarImpl.init"
    }


    void release() {
        // release done in opposite order from init
        for (int i = mAllServices.length - 1; i >= 0; i--) {
            mAllServices[i].release(); //释放所有子服务
        }
        mHal.release(); //释放VehicleHal 
    }
}

在ICarImpl的构造函数中会创建VehicleHal 和各种Car子服务,并把这些服务添加到List中,然后在init方法中调用这些服务的初始化方法,完成服务的初始化。

3、取得CarService子服务

CarService启动和初始化完成后,可以通过CarService的getCarService获取子服务了,实际调用的是ICarImpl的getCarService,它继承与ICar.aidl接口,实现了ICar.aidl接口的方法:

//packages/services/Car/car-lib/src/android/car/ICar.aidl
interface ICar {
    /**
     * Helper binder is for ICarServiceHelper. It is for the communication from CarService ->
     * CarServiceHelperService.
     * Receiver binder would set ICarSystemServerClient binder for CarServiceHelperService.
     */
    oneway void setSystemServerConnections(in ICarServiceHelper helper,
        in ICarResultReceiver receiver) = 0;


    // Rest of the calls are used for Apps to CarService communication
    @nullable IBinder getCarService(in String serviceName) = 11;
    int getCarConnectionType() = 12;
    boolean isFeatureEnabled(in String featureName) = 13;
    int enableFeature(in String featureName) = 14;
    int disableFeature(in String featureName) = 15;
    List<String> getAllEnabledFeatures() = 16;
    List<String> getAllPendingDisabledFeatures() = 17;
    List<String> getAllPendingEnabledFeatures() = 18;
    /**
     * Get class name for experimental feature. Class should have constructor taking (Car, IBinder)
     * and should inherit CarManagerBase.
     */
    @nullable String getCarManagerClassForFeature(in String featureName) = 19;
}

ICarImpl的getCarService方法如下:

//packages/services/Car/service/src/com/android/car/ICarImpl.java
public class ICarImpl extends ICar.Stub {
    @Override
    @Nullable
    public IBinder getCarService(String serviceName) {
        if (!mFeatureController.isFeatureEnabled(serviceName)) {
            Slogf.w(CarLog.TAG_SERVICE, "getCarService for disabled service:" + serviceName);
            return null;
        }
        switch (serviceName) {
            case Car.AUDIO_SERVICE:
                return mCarAudioService;
            case Car.APP_FOCUS_SERVICE:
                return mAppFocusService;
            case Car.PACKAGE_SERVICE:
                return mCarPackageManagerService;
            case Car.DIAGNOSTIC_SERVICE:
                CarServiceUtils.assertAnyDiagnosticPermission(mContext);
                return mCarDiagnosticService;
            case Car.POWER_SERVICE:
                return mCarPowerManagementService;
            case Car.CABIN_SERVICE:
            case Car.HVAC_SERVICE:
            case Car.INFO_SERVICE:
            case Car.PROPERTY_SERVICE:
            case Car.SENSOR_SERVICE:
            case Car.VENDOR_EXTENSION_SERVICE:
                return mCarPropertyService;
            case Car.CAR_NAVIGATION_SERVICE:
                CarServiceUtils.assertNavigationManagerPermission(mContext);
                return mClusterNavigationService;
            case Car.CAR_INSTRUMENT_CLUSTER_SERVICE:
                CarServiceUtils.assertClusterManagerPermission(mContext);
                return mInstrumentClusterService.getManagerService();
            case Car.PROJECTION_SERVICE:
                return mCarProjectionService;
            case Car.VEHICLE_MAP_SERVICE:
                CarServiceUtils.assertAnyVmsPermission(mContext);
                return mVmsBrokerService;
            case Car.VMS_SUBSCRIBER_SERVICE:
                CarServiceUtils.assertVmsSubscriberPermission(mContext);
                return mVmsBrokerService;
            case Car.TEST_SERVICE: {
                CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
                synchronized (mLock) {
                    if (mCarTestService == null) {
                        mCarTestService = new CarTestService(mContext, this);
                    }
                    return mCarTestService;
                }
            }
            case Car.STORAGE_MONITORING_SERVICE:
                CarServiceUtils.assertPermission(mContext, Car.PERMISSION_STORAGE_MONITORING);
                return mCarStorageMonitoringService;
            case Car.CAR_DRIVING_STATE_SERVICE:
                CarServiceUtils.assertDrivingStatePermission(mContext);
                return mCarDrivingStateService;
            case Car.CAR_UX_RESTRICTION_SERVICE:
                return mCarUXRestrictionsService;
            case Car.OCCUPANT_AWARENESS_SERVICE:
                return mOccupantAwarenessService;
            case Car.CAR_MEDIA_SERVICE:
                return mCarMediaService;
            case Car.CAR_OCCUPANT_ZONE_SERVICE:
                return mCarOccupantZoneService;
            case Car.CAR_BUGREPORT_SERVICE:
                return mCarBugreportManagerService;
            case Car.CAR_USER_SERVICE:
                return mCarUserService;
            case Car.EXPERIMENTAL_CAR_USER_SERVICE:
                return mExperimentalCarUserService;
            case Car.CAR_WATCHDOG_SERVICE:
                return mCarWatchdogService;
            case Car.CAR_PERFORMANCE_SERVICE:
                return mCarPerformanceService;
            case Car.CAR_INPUT_SERVICE:
                return mCarInputService;
            case Car.CAR_DEVICE_POLICY_SERVICE:
                return mCarDevicePolicyService;
            case Car.CLUSTER_HOME_SERVICE:
                return mClusterHomeService;
            case Car.CAR_EVS_SERVICE:
                return mCarEvsService;
            case Car.CAR_TELEMETRY_SERVICE:
                return mCarTelemetryService;
            case Car.CAR_ACTIVITY_SERVICE:
                return mCarActivityService;
            default:
                IBinder service = null;
                if (mCarExperimentalFeatureServiceController != null) {
                    service = mCarExperimentalFeatureServiceController.getCarService(serviceName);
                }
                if (service == null) {
                    Slogf.w(CarLog.TAG_SERVICE, "getCarService for unknown service:"
                            + serviceName);
                }
                return service;
        }
    } 
}
  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值