Android AutoMotive—CarPowerManagementService

1、电源状态概述

电源管理是Android AutoMotive OS中较手机Android系统差异化比较大的模块,这是因为车机面临的使用场景比手机更加复杂。既要考虑车辆短时间使用间隔的休眠,也要考虑长时间停放下的关机;休眠状态下可以快速响应唤醒,但是这种状态如果管理不好,又会存在持续耗电的情况,如果电瓶亏电,后果就很严重;同时我们还要考虑到车机系统的OTA升级,通常是在人离开车后,车辆空闲的状态去做的升级,称之为地库模式;还有哨兵模式,在车辆停放的时候摄像头会开启;以及远程控车,通过TBox唤醒车机系统,等等。
对于Android AutoMotive OS,电源状态的迁移如下:
在这里插入图片描述
(1) 车机系统处于STR(Suspend To RAM)深度睡眠状态,此时CUP已经掉电,但是RAM内存还保持着原有的数据;
(2) 用户操作车辆,唤醒车机系统,VHAL(Vehicle HAL,车辆硬件抽象层)开始启动车辆相关服务;
(3) 车机系统启动完成;
(4) 用户停止使用车辆,触发关机前的准备流程,等待上层APP做关机前的确认;
(5) 上层APP确认完毕可以关机,并通知到VHAL,等待VHAL关闭;
(6) VHAL关闭完成,AP掉电,车机再次进入STR休眠状态。

2、CarPowerManager

CarPowerManagementService运行在Carservice进程中,它对上层APP提供的客户端API是CarPowerManager,它主要提供了如下几个方法:

方法名注解
requestShutdownOnNextSuspend()请求在下次进入关机流程时直接关机,而非休眠挂起
scheduleNextWakeupTime(int seconds)设置下次唤醒的时间间隔
getPowerState()获取到电源状态
setListener(@NonNull @CallbackExecutor Executor executor, @NonNull CarPowerStateListener listener)设置电源变化监听
setListenerWithCompletion(@NonNull @CallbackExecutor Executor executor, @NonNull CarPowerStateListenerWithCompletion listener)设置电源变化监听,回调包含结果通知

CarPowerStateListenerWithCompletion监听器和CarPowerStateListener监听器不同的是,后者只有一个状态结果的通知;而前者的状态回调接口中,还包含了一个CompletableFuture对象,APP需要通过这个对象告诉CarPowerManagementService,APP层已经完成了关机前的动作,现在可以继续接下来的流程。
电源状态列表如下:

常量定义注解
STATE_SHUTDOWN_ENTER关机
STATE_WAIT_FOR_VHAL等待VHAL启动
STATE_ON开机
STATE_SHUTDOWN_PREPARE进入关机前的准备
STATE_SHUTDOWN_CANCELLED取消关机
STATE_SUSPEND_ENTER进入深度休眠,内存供电
STATE_HIBERNATION_ENTER更深度休眠,内存掉电
STATE_SUSPEND_EXIT退出休眠

需要注意的是,调用setListenerWithCompletion方法除了需要android.car.permission.CAR_POWER权限外,还需要以system UID的用户组运行。这是因为CarPowerStateListenerWithCompletion监听的回调方法,是可以阻塞关机流程的,这必定是要核心的系统级应用和服务才能有权使用。
在手机Android系统中,我们可能会监听BOOT_COMPLETED开机广播,去做程序数据的初始化,但是在AAOS中,如果车机只是休眠唤醒且没有用户切换的情况下,是没有开机广播的。所以除了开机广播外,我们更应该监听电源状态,STATE_ON、STATE_SHUTDOWN_PREPARE是最为常用的,AAOS中特有的地库模式,就是基于对STATE_SHUTDOWN_PREPARE的监听实现的。

3、CarPowerManagementService

CarPowerManagementService的处理流程如下:
在这里插入图片描述
VMCU是车辆微控制器,电源的状态上报就是从它发出来的,通过厂商定制的VHAL层到达CarPowermanagementService,接下来就会处理不同的状态,以SHUTDOWN_PREPARE流程为例,代码如下:

// packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
private void doHandlePowerStateChange() {
	switch (newState.mState) {
			case CpmsState.SHUTDOWN_PREPARE:
            handleShutdownPrepare(newState, prevState);
     }
}

然后调用到doShutdownPrepare()方法,这里会去给各个APP注册的监听器发送状态改变的回调:

private void doShutdownPrepare() {
	sendPowerManagerEvent(CarPowerManager.STATE_SHUTDOWN_PREPARE, timeoutMs);
    mHal.sendShutdownPrepare();
    waitForShutdownPrepareListenersToComplete(timeoutMs, intervalMs);
}

最后会执行到waitForCompletionAsync 方法:

// Waits for listeners to complete.
    // If {@code intervalMs} is non-positive value, it is ignored and the method waits up to
    // {@code timeoutMs}.
    private void waitForCompletionAsync(Runnable taskAtCompletion, Runnable taskAtInterval,
            long timeoutMs, long intervalMs) {
            
        //这里使用信号量去进程间通信,获取远程APP prepare的状态。
		boolean isNotified = mListenerCompletionSem.tryAcquire(waitTimeMs, TimeUnit.MILLISECONDS); 
		
		//超过最大等待时间,则进入下一步流程
		if (isLastWait) {
                 Slogf.w(TAG, "Waiting for listener completion is timeout(%d)",waitTimeMs);
                 taskAtCompletion.run(); 
                  return;
         }
         
		//判断所有的监听等待对象是否已经完成准备,等待队列为空之后,也会进入下一步流程
		isComplete = mListenersWeAreWaitingFor.isEmpty(); 
		if (isComplete) {
                  Slogf.i(TAG, "All listeners completed");
                  taskAtCompletion.run();
                  mIsListenerWaitingCancelled.set(false);
                  return;
        }
}

所以CarPowermanagementService的执行逻辑总体概括,就是把状态信号回调给各个监听器,同时开启对各个监听器回执状态的检测。

4、Garage Mode 车库模式

车库模式是AAOS中特有的一种空闲模式,它的触发时机是在用户停止使用车辆之后,即收到SHUTDOWN_PREPARE状态信号。车库模式的作用,是利用这段空闲时间,做一些开机时候不能做的事情,最典型的就是系统升级。
Garage Mode对应的服务GarageModeService也是运行在Carservice进程里面,属于CarService的一部分,它内部有一个GarageModeController,会去注册监听CarPowerManagementService的状态:

// packages/services/Car/service/src/com/android/car/garagemode/GarageModeController.java
public class GarageModeController extends ICarPowerStateListener.Stub {
	mCarPowerService.registerInternalListener(GarageModeController.this);
	@Override
	public void onStateChanged(int state, long expirationTimeMs) {
		case CarPowerManager.STATE_SHUTDOWN_PREPARE:
                initiateGarageMode(
                        () -> mCarPowerService.completeHandlingPowerStateChange(state,
                                GarageModeController.this));
           break;
	}
}

调用registerInternalListener去注册,就会让CarPowerService去把这个监听器加入到上面提到的等待队列中去。
在收到STATE_SHUTDOWN_PREPARE状态后,就会开启车库模式。

// packages/services/Car/service/src/com/android/car/garagemode/GarageModeController.java
void enterGarageMode(Runnable completor) {
	broadcastSignalToJobScheduler(true);
startMonitoringThread();
}

这里最重要的就是做了两个事情:一是发送开启车库模式的广播,从方法名可以看到,在广播接收方会去执行JobScheduler任务,也就是OTA升级任务;二是开启对线程的观察,其实也就是观察JobSchedulerJobInfo任务队列是否已经全部执行结束。
跟随广播的发送,我们来到广播的接受方,代码位于frameworks/base/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java
CarIdlenessTracker已经不在Carservice的一部分,属于AOSP的framework下,它是由IdleController创建。当设备运行在车载环境时,就会创建CarIdlenessTracker,而在手机上则会创建DeviceIdlenessTracker。这样,CarService就会和原有的Android JobScheduler机制完美结合了起来。
看CarIdlenessTracker:

// frameworks/base/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java
public final class CarIdlenessTracker extends BroadcastReceiver implements IdlenessTracker {
	@Override
	public void onReceive(Context context, Intent intent) {
		if (action.equals(ACTION_GARAGE_MODE_ON)) {
            logIfDebug("GarageMode is on...");
            mGarageModeOn = true;
            updateIdlenessState();
        }
	}

	private void updateIdlenessState() {
        final boolean newState = (mForced || mGarageModeOn);
        mIdle = newState;
            mIdleListener.reportNewIdleState(mIdle);
        
	}

}

这里就会通知IdleController现在的处于空闲状态,可以去执行相关的JobInfo调度。

<think>我们正在讨论Android Automotive OS中的CarService。根据用户的问题,我们需要详细解释CarService的核心组成、启动流程、SystemServer与SystemServiceManager的作用、CarServiceHelperService的角色、AndroidManifest配置要求以及如何通过CarAPI调用汽车服务。 首先,我们需要明确CarService是Android Automotive OS中一个重要的系统服务,它作为车机服务的核心,负责管理车辆相关的硬件抽象层(HAL)和向上层应用提供统一的接口。 根据引用[1]和[2]的信息: - CarService运行在独立的进程中,作为原有Android服务的补充。 - CarServiceHelperService在启动过程中通过bindService的方式启动CarService。 下面,我们将按照用户的要求逐一解答。 ### 1. CarService的核心组成 CarService由多个内部服务组成,每个内部服务负责一个特定的车辆子系统。常见的包括: - CarPowerManagementService:管理车辆电源状态 - CarProjectionService:负责投影相关功能 - CarHvacService:控制空调系统 - CarSensorService:处理车辆传感器数据 - CarPropertyService:管理车辆属性 这些服务通过车辆硬件抽象层(Vehicle HAL)与底层硬件交互,并通过Car API向应用提供接口。 ### 2. 启动流程详解 CarService的启动流程涉及多个步骤,主要分为以下阶段: #### 阶段1:SystemServer启动 Android系统启动时,SystemServer进程启动,它会初始化各种系统服务。其中,SystemServiceManager负责系统服务的生命周期管理。 #### 阶段2:启动CarServiceHelperService 在SystemServer中,会启动CarServiceHelperService(这是一个系统服务)。CarServiceHelperService的启动过程如下: 1. 在`onStart`方法中,创建一个Intent,其Action为`android.car.ICar`,包名为`com.android.car`(即CarService所在的包)。 2. 通过`bindService`方式绑定到该Intent对应的服务(即CarService)。 #### 阶段3:CarService的启动 当CarService被绑定后,其`onBind`方法会被调用,然后CarService开始初始化。CarService的初始化包括: - 初始化各个内部服务(如CarPowerManagementService等) - 注册到ServiceManager,以便其他进程可以通过Binder调用 - 初始化Vehicle HAL ### 3. SystemServer与SystemServiceManager在CarService中的作用 - **SystemServer**:是Android系统的核心进程,负责启动和管理所有系统服务。CarServiceHelperService就是在SystemServer中启动的。 - **SystemServiceManager**:负责系统服务的注册、创建和生命周期管理。在SystemServer中,通过SystemServiceManager来启动CarServiceHelperService(它是一个SystemService)。 ### 4. CarServiceHelperService角色 CarServiceHelperService是一个在SystemServer进程中运行的系统服务,它的主要作用是在系统启动阶段触发CarService的启动。它通过绑定服务(bindService)的方式启动CarService进程并建立连接。这样,CarService就可以运行在独立的进程中(通常为com.android.car进程)。 ### 5. AndroidManifest配置要求 CarService作为一个独立的服务,需要在AndroidManifest.xml中声明。通常,CarService的声明如下(在CarService模块的AndroidManifest.xml中): ```xml <service android:name=".CarService" android:process="com.android.car" android:label="@string/service_name"> <intent-filter> <action android:name="android.car.ICar" /> </intent-filter> </service> ``` 同时,CarServiceHelperService也需要在系统服务的AndroidManifest中声明(因为它是系统服务): ```xml <service android:name=".CarServiceHelperService" android:exported="true" android:label="@string/car_service_helper_service"> <!-- 需要系统权限 --> </service> ``` ### 6. 如何通过CarAPI调用汽车服务 应用要使用汽车服务,需要先获取Car对象,然后通过Car对象获取具体的服务。步骤如下: 1. 在AndroidManifest.xml中声明需要的汽车权限,例如: ```xml <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_SYSTEM"/> ``` 2. 在代码中连接CarService: ```java // 创建CarConnectionCallback回调 CarConnectionCallback callback = new CarConnectionCallback() { @Override public void onConnected(Car car) { // 获取具体的服务,例如CarHvacManager CarHvacManager hvacManager = (CarHvacManager) car.getCarManager(Car.HVAC_SERVICE); // 使用服务 } }; // 建立连接 Car car = Car.createCar(context, callback); car.connect(); ``` 3. 通过获取到的Manager调用相应的方法,例如设置空调温度: ```java hvacManager.setFloatProperty(CarHvacManager.ID_ZONE_TEMP_SETPOINT, zone, temp); ``` 注意:使用Car API需要应用具有相应的权限,并且需要在支持Android Automotive OS的车载设备上运行。 ### 总结 CarService是Android Automotive OS中负责车辆服务的核心组件,它通过独立的进程运行,管理多个车辆子系统服务。启动流程由SystemServer中的CarServiceHelperService触发,通过绑定服务的方式启动。应用通过Car API获取Car实例,然后通过Car实例获取具体的服务管理器来调用车辆功能。 §§相关问题§§ 1. CarService与Vehicle HAL之间是如何交互的? 2. 开发一个需要访问车辆属性的应用需要哪些步骤? 3. CarService在Android Automotive OS中的安全机制是怎样的? 4. 如何调试CarService相关的进程?</think>### Android Automotive OS中CarService详解 #### 一、CarService核心组成 CarService是Android Automotive OS的核心系统服务,由多个关键模块组成: 1. **服务管理层**:通过`CarServiceBase`实现服务生命周期管理 2. **车辆子系统服务**: - `CarPowerManagementService`:电源状态管理 - `CarProjectionService`:屏幕投影控制 - `CarHvacService`:空调系统控制 - `CarSensorService`:车辆传感器数据采集 - `CarPropertyService`:车辆属性管理 3. **HAL适配层**:通过`VehicleHal`类实现与车辆硬件抽象层(VHAL)的通信 4. **权限管理**:`CarPermissionService`处理车辆相关权限控制 5. **事件分发**:`CarInputService`处理车辆专用输入事件 这些组件通过Binder IPC机制向上层提供标准化接口[^2]。 #### 二、启动流程详解 ```mermaid graph TD A[SystemServer] --> B[启动SystemServiceManager] B --> C[启动CarServiceHelperService] C -->|onStart| D[创建绑定Intent] D --> E[bindService连接CarService] E --> F[CarService进程启动] F --> G[初始化Vehicle HAL] G --> H[注册子系统服务] H --> I[向ServiceManager注册] ``` 关键步骤: 1. **SystemServer初始化**:在`startBootstrapServices()`阶段启动`SystemServiceManager` 2. **CarServiceHelperService启动**: ```java public void onStart() { Intent intent = new Intent("android.car.ICar"); intent.setPackage("com.android.car"); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } ``` 3. **CarService绑定**:通过`ICar.Stub`建立Binder连接 4. **服务初始化**:在`CarService.onCreate()`中初始化所有子系统服务 5. **HAL连接**:通过`VehicleHal.getInstance()`建立与车辆硬件的通信[^1] #### 三、SystemServer与SystemServiceManager作用 1. **SystemServer**: - Android系统核心进程 - 负责启动所有系统级服务 - 通过`startService()`触发CarServiceHelperService启动 2. **SystemServiceManager**: - 管理系统服务生命周期 - 处理服务依赖关系 - 提供`startService()`方法启动CarServiceHelperService #### 四、CarServiceHelperService角色 1. **桥梁作用**:连接SystemServer与CarService 2. **启动触发器**:通过bindService()激活CarService进程 3. **进程隔离**:确保CarService运行在独立进程(`com.android.car`) 4. **状态监控**:监听CarService连接状态并重连 #### 五、AndroidManifest配置要求 CarService需在独立进程中声明: ```xml <service android:name=".CarService" android:process="com.android.car" android:label="@string/service_name"> <intent-filter> <action android:name="android.car.ICar" /> </intent-filter> </service> ``` 关键配置项: 1. 强制独立进程:`android:process="com.android.car"` 2. 绑定Action:`android.car.ICar` 3. 权限声明:`<uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_SYSTEM"/>` 4. 功能声明:`<uses-feature android:name="android.hardware.type.automotive"/>` #### 六、CarAPI调用流程 1. **获取Car实例**: ```java Car car = Car.createCar(context); car.connect(); ``` 2. **获取服务管理器**: ```java CarHvacManager hvacManager = (CarHvacManager) car.getCarManager(Car.HVAC_SERVICE); ``` 3. **调用车辆功能**: ```java // 设置空调温度 hvacManager.setFloatProperty( CarHvacManager.ID_ZONE_TEMP_SETPOINT, CarHvacManager.VEHICLE_ZONE_ROW_1_LEFT, 22.0f ); ``` 4. **权限检查**: ```xml <uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE"/> ``` 5. **异常处理**: ```java try { // 调用Car API } catch (CarNotConnectedException e) { // 处理连接断开 } ``` ### 关键设计要点 1. **进程隔离**:CarService独立进程防止车辆功能崩溃影响系统核心 2. **HAL标准化**:通过`android.hardware.automotive[email protected]`规范硬件接口 3. **权限分级**:`普通权限|签名权限|厂商权限`三级控制体系 4. **事件分发**:使用`CarPropertyEvent`对象封装车辆数据变更
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值