如下为CarPower上电的流程图:
下面我们从代码角度分析:
通过VHAL向MCU发送AP_POWER_STATE_REPORT:WAIT_FOR_VHAL消息
在CPMS的init方法中会调用onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerManager.STATE_WAIT_FOR_VHAL); 设置ApPowerState为STATE_WAIT_FOR_VHAL:
//packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
public class CarPowerManagementService extends ICarPower.Stub implements
CarServiceBase, PowerHalService.PowerEventListener {
private final PowerHandler mHandler = new PowerHandler(mHandlerThread.getLooper(), this);
private void onApPowerStateChange(int apState,
@CarPowerManager.CarPowerState int carPowerStateListenerState) {
CpmsState newState = new CpmsState(apState, carPowerStateListenerState, //将apState和carPowerStateListenerState记录到CpmsState对象中
/* canPostpone= */ false);
synchronized (mLock) {
if (newState.mState == CpmsState.WAIT_FOR_FINISH) {
// We are ready to shut down. Suppress this transition if
// there is a request to cancel the shutdown (WAIT_FOR_VHAL).
for (int idx = 0; idx < mPendingPowerStates.size(); idx++) {
if (mPendingPowerStates.get(idx).mState == CpmsState.WAIT_FOR_VHAL) {
// Completely ignore this WAIT_FOR_FINISH
return;
}
}
}
mPendingPowerStates.addFirst(newState); //将新的CpmsState加到待处理电源状态List中
mLock.notify();
}
mHandler.handlePowerStateChange(); //调用PowerHandler的handlePowerStateChange方法
}
}
在onApPowerStateChange中调用PowerHandler 的handlePowerStateChange方法:
//packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
public class CarPowerManagementService extends ICarPower.Stub implements
CarServiceBase, PowerHalService.PowerEventListener {
private static final class PowerHandler extends Handler {
private void handlePowerStateChange() {
Message msg = obtainMessage(MSG_POWER_STATE_CHANGE);
sendMessage(msg); //发送MSG_POWER_STATE_CHANGE消息
}
public void handleMessage(Message msg) {
CarPowerManagementService service = mService.get();
if (service == null) {
Slogf.i(TAG, "handleMessage null service");
return;
}
switch (msg.what) {
case MSG_POWER_STATE_CHANGE:
service.doHandlePowerStateChange(); //调用CPMS的doHandlePowerStateChange方法
break;
case MSG_DISPLAY_BRIGHTNESS_CHANGE:
service.doHandleDisplayBrightnessChange(msg.arg1);
break;
case MSG_MAIN_DISPLAY_STATE_CHANGE:
service.doHandleMainDisplayStateChange((Boolean) msg.obj);
break;
case MSG_PROCESSING_COMPLETE:
service.doHandleProcessingComplete();
break;
}
}
}
}
在handlePowerStateChange中发送MSG_POWER_STATE_CHANGE消息,handleMessage收到消息后调用CPMS的doHandlePowerStateChange方法:
//packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
public class CarPowerManagementService extends ICarPower.Stub implements
CarServiceBase, PowerHalService.PowerEventListener {
private void doHandlePowerStateChange() {
CpmsState state;
synchronized (mLock) {
state = mPendingPowerStates.pollFirst();
if (state == null) {
Slogf.w(TAG, "No more power state to process");
return;
}
Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", state.name());
if (!needPowerStateChangeLocked(state)) {
// We may need to process the pending power state request.
if (!mPendingPowerStates.isEmpty()) {
Slogf.i(TAG, "There is a pending power state change request. requesting the "
+ "processing...");
mHandler.handlePowerStateChange();
}
return;
}
// now real power change happens. Whatever was queued before should be all cancelled.
mPendingPowerStates.clear();
cancelWaitingForCompletion();
mCurrentState = state;
}
mHandler.cancelProcessingComplete();
Slogf.i(TAG, "setCurrentState %s", state);
CarStatsLogHelper.logPowerState(state.mState);
EventLogHelper.writeCarPowerManagerStateChange(state.mState);
switch (state.mState) {
case CpmsState.WAIT_FOR_VHAL:
handleWaitForVhal(state); //调用handleWaitForVhal方法
break;
case CpmsState.ON:
handleOn();
break;
case CpmsState.SHUTDOWN_PREPARE:
handleShutdownPrepare(state);
break;
case CpmsState.SIMULATE_SLEEP:
case CpmsState.SIMULATE_HIBERNATION:
simulateShutdownPrepare(state);
break;
case CpmsState.WAIT_FOR_FINISH:
handleWaitForFinish(state);
break;
case CpmsState.SUSPEND:
// Received FINISH from VHAL
handleFinish();
break;
default:
// Illegal state
// TODO(b/202414427): Add handling of illegal state
break;
}
}
}
在CPMS的doHandlePowerStateChange方法中判断CpmsState为WAIT_FOR_VHAL,调用handleWaitForVhal方法:
//packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
public class CarPowerManagementService extends ICarPower.Stub implements
CarServiceBase, PowerHalService.PowerEventListener {
private void handleWaitForVhal(CpmsState state) {
@CarPowerManager.CarPowerState int carPowerStateListenerState =
state.mCarPowerStateListenerState;
// TODO(b/177478420): Restore Wifi, Audio, Location, and Bluetooth, if they are artificially
// modified for S2R.
mSilentModeHandler.querySilentModeHwState();
sendPowerManagerEvent(carPowerStateListenerState, INVALID_TIMEOUT);
// Inspect CarPowerStateListenerState to decide which message to send via VHAL
switch (carPowerStateListenerState) {
case CarPowerManager.STATE_WAIT_FOR_VHAL:
mHal.sendWaitForVhal();
break;
case CarPowerManager.STATE_SHUTDOWN_CANCELLED:
synchronized (mLock) {
mShutdownOnNextSuspend = false; // This cancels the "NextSuspend"
}
mHal.sendShutdownCancel();
break;
case CarPowerManager.STATE_SUSPEND_EXIT:
mHal.sendSleepExit();
break;
case CarPowerManager.STATE_HIBERNATION_EXIT:
mHal.sendHibernationExit();
break;
}
if (mWifiAdjustmentForSuspend) restoreWifi();
}
}
CarPowerManagementService 的handleWaitForVhal方法调用PowerHalService 的sendWaitForVhal方法:
//packages/services/Car/service/src/com/android/car/hal/PowerHalService.java
public class PowerHalService extends HalServiceBase {
public void sendWaitForVhal() {
Slogf.i(CarLog.TAG_POWER, "send wait for vhal");
setPowerState(VehicleApPowerStateReport.WAIT_FOR_VHAL, 0); //设置PowerState为WAIT_FOR_VHAL
}
private void setPowerState(int state, int additionalParam) {
if (isPowerStateSupported()) {
int[] values = { state, additionalParam };
try {
mHal.set(VehicleProperty.AP_POWER_STATE_REPORT, 0).to(values); //调用VHAL的set方法向VHAL发送AP_POWER_STATE_REPORT(WAIT_FOR_VHAL)
Slogf.i(CarLog.TAG_POWER, "setPowerState=" + powerStateReportName(state)
+ " param=" + additionalParam);
} catch (ServiceSpecificException e) {
Slogf.e(CarLog.TAG_POWER, "cannot set to AP_POWER_STATE_REPORT", e);
}
}
}
}