Android Framework系列—CarPower電源管理
智能座艙通常包括中控系統(tǒng)、儀表系統(tǒng)、IVI系統(tǒng) 、后排娛樂、HUD、車聯(lián)網(wǎng)等。這些系統(tǒng)需要由汽車電源進(jìn)行供電。由于汽車自身的特殊供電環(huán)境(相比手機(jī)方便的充電環(huán)境,汽車的蓄電池如果沒有電是需要專業(yè)人士操作的),其電源狀態(tài)會(huì)比較復(fù)雜,既要滿足車內(nèi)的座艙系統(tǒng)啟動(dòng)足夠快,又要保證汽車蓄電池的可考性,所以出了開機(jī)(on)、關(guān)機(jī)(off)外,會(huì)多出來一些電源狀態(tài)(Suspend、STR、SLEEP等等)
所以,一般來說軟件系統(tǒng)是需要一個(gè)專門的電源管理模塊的。
CarPower電源管理
Android Automotive(基于Android平臺(tái)的車載信息娛樂系統(tǒng))提供了CarPower模塊用于管理電源狀態(tài)。CarPower Service屬于CarService,在SystemSever的startOtherService階段啟動(dòng)。
CarPower Service根據(jù)來自于 Vehicle HAL(Hal層服務(wù))的電源狀態(tài)通知,進(jìn)行相關(guān)的邏輯判斷后,應(yīng)用電源策略(簡單理解成告知某些服務(wù)Enable 或者Disable)、發(fā)送狀態(tài)通知給它自身的監(jiān)聽者、回復(fù)(Report)VehcileHAL處理結(jié)果。
Vehicle HAL的電源狀態(tài)一般來講是來自于MCU的(can通信 或者以太網(wǎng)通信,具體形式由Vehicle HAL和相關(guān)供應(yīng)商決定)。電源狀態(tài)變化時(shí),MCU一般會(huì)拉低或者拉高某個(gè)引腳,然后通知事件給VehicleHAL,VehicleHAL再通過PropertyEvent通知給CarPower Service。Android系統(tǒng)處理完電源狀態(tài)后(有超時(shí)要求),再由VehiclHAL告知MCU,MCU在對(duì)某個(gè)引腳進(jìn)行相關(guān)操作。文章來源:http://www.zghlxwxcb.cn/news/detail-734324.html
CarPower電源管理的開機(jī)流程
下面以Android車載系統(tǒng)開機(jī)為例。說明一下CarPower模塊的開機(jī)時(shí)序。代碼基于Android12.文章來源地址http://www.zghlxwxcb.cn/news/detail-734324.html
- CarPower服務(wù)啟動(dòng):Android系統(tǒng)開機(jī)上電,在systemServer中啟動(dòng)CarService。
// frameworks/base/services/java/com/android/server/SystemServer.java
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
t.traceBegin("StartCarServiceHelperService");
final SystemService cshs = mSystemServiceManager
.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
if (cshs instanceof Dumpable) {
mDumper.addDumpable((Dumpable) cshs);
}
if (cshs instanceof DevicePolicySafetyChecker) {
dpms.setDevicePolicySafetyChecker((DevicePolicySafetyChecker) cshs);
}
t.traceEnd();
}
}
// frameworks/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java
public void onStart() {
EventLog.writeEvent(EventLogTags.CAR_HELPER_START, mHalEnabled ? 1 : 0);
IntentFilter filter = new IntentFilter(Intent.ACTION_REBOOT);
filter.addAction(Intent.ACTION_SHUTDOWN);
mContext.registerReceiverForAllUsers(mShutdownEventReceiver, filter, null, null);
mCarWatchdogDaemonHelper.addOnConnectionChangeListener(mConnectionListener);
mCarWatchdogDaemonHelper.connect();
// 啟動(dòng)了CarService------------------------------------------
Intent intent = new Intent();
intent.setPackage("com.android.car");
intent.setAction(ICarConstants.CAR_SERVICE_INTERFACE);
if (!mContext.bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
UserHandle.SYSTEM)) {
Slog.wtf(TAG, "cannot start car service");
}
loadNativeLibrary();
}
- CarService啟動(dòng)后會(huì)創(chuàng)建CarPower實(shí)例。
<!-- packages/services/Car/service/AndroidManifest.xml -->
<application android:label="@string/app_title"
android:directBootAware="true"
android:allowBackup="false"
android:persistent="true">
<service android:name=".CarService"
android:singleUser="true">
<intent-filter>
<action android:name="android.car.ICar" />
</intent-filter>
</service>
// packages/services/Car/service/src/com/android/car/ICarImpl.java
public class ICarImpl extends ICar.Stub {
public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) {
this(serviceContext, vehicle, systemInterface, errorNotifier, vehicleInterfaceName,
/* carUserService= */ null, /* carWatchdogService= */ null);
}
@VisibleForTesting
ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
CanBusErrorNotifier errorNotifier, String vehicleInterfaceName,
@Nullable CarUserService carUserService,
@Nullable CarWatchdogService carWatchdogService) {
mContext = serviceContext;
mSystemInterface = systemInterface;
mHal = new VehicleHal(serviceContext, vehicle);
// 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.
VehiclePropValue disabledOptionalFeatureValue = mHal.getIfAvailableOrFailForEarlyStage(
VehicleProperty.DISABLED_OPTIONAL_FEATURES, INITIAL_VHAL_GET_RETRY);
String[] disabledFeaturesFromVhal = null;
if (disabledOptionalFeatureValue != null) {
String disabledFeatures = disabledOptionalFeatureValue.value.stringValue;
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);
mFeatureController = new CarFeatureController(serviceContext, defaultEnabledFeatures,
disabledFeaturesFromVhal , mSystemInterface.getSystemCarDir());
CarLocalServices.addService(CarFeatureController.class, mFeatureController);
mVehicleInterfaceName = vehicleInterfaceName;
mUserManagerHelper = new CarUserManagerHelper(serviceContext);
if (carUserService != null) {
mCarUserService = carUserService;
} else {
UserManager userManager =
(UserManager) serviceContext.getSystemService(Context.USER_SERVICE);
int maxRunningUsers = res.getInteger(
com.android.internal.R.integer.config_multiuserMaxRunningUsers);
mCarUserService = new CarUserService(serviceContext, mHal.getUserHal(),
mUserManagerHelper, userManager, ActivityManager.getService(), maxRunningUsers);
}
mCarOccupantZoneService = new CarOccupantZoneService(serviceContext);
mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
// 這里創(chuàng)建了CarPower服務(wù)實(shí)例-----------------------------------------------------------
mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(),
systemInterface, mCarUserService);
if (mFeatureController.isFeatureEnabled(CarFeatures.FEATURE_CAR_USER_NOTICE_SERVICE)) {
mCarUserNoticeService = new CarUserNoticeService(serviceContext);
} else {
mCarUserNoticeService = null;
}
mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal());
mCarDrivingStateService = new CarDrivingStateService(serviceContext, mCarPropertyService);
mCarUXRestrictionsService = new CarUxRestrictionsManagerService(serviceContext,
mCarDrivingStateService, mCarPropertyService);
if (mFeatureController.isFeatureEnabled(Car.OCCUPANT_AWARENESS_SERVICE)) {
mOccupantAwarenessService = new OccupantAwarenessService(serviceContext);
} else {
mOccupantAwarenessService = null;
}
mCarPackageManagerService = new CarPackageManagerService(serviceContext,
mCarUXRestrictionsService,
mSystemActivityMonitoringService,
mCarUserService);
mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext, mCarUserService);
mCarBluetoothService = new CarBluetoothService(serviceContext, mPerUserCarServiceHelper);
mCarInputService = new CarInputService(serviceContext, mHal.getInputHal(), mCarUserService);
mCarProjectionService = new CarProjectionService(
serviceContext, null /* handler */, mCarInputService, mCarBluetoothService);
mGarageModeService = new GarageModeService(mContext);
mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);
mCarAudioService = new CarAudioService(serviceContext);
mCarNightService = new CarNightService(serviceContext, mCarPropertyService);
mFixedActivityService = new FixedActivityService(serviceContext);
mInstrumentClusterService = new InstrumentClusterService(serviceContext,
mAppFocusService, mCarInputService);
mSystemStateControllerService = new SystemStateControllerService(
serviceContext, mCarAudioService, this);
mCarStatsService = new CarStatsService(serviceContext);
mCarStatsService.init();
if (mFeatureController.isFeatureEnabled(Car.VEHICLE_MAP_SERVICE)) {
mVmsBrokerService = new VmsBrokerService(mContext, mCarStatsService);
} else {
mVmsBrokerService = null;
}
if (mFeatureController.isFeatureEnabled(Car.DIAGNOSTIC_SERVICE)) {
mCarDiagnosticService = new CarDiagnosticService(serviceContext,
mHal.getDiagnosticHal());
} else {
mCarDiagnosticService = null;
}
if (mFeatureController.isFeatureEnabled(Car.STORAGE_MONITORING_SERVICE)) {
mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext,
systemInterface);
} else {
mCarStorageMonitoringService = null;
}
mCarConfigurationService =
new CarConfigurationService(serviceContext, new JsonReaderImpl());
mCarLocationService = new CarLocationService(serviceContext);
mCarTrustedDeviceService = new CarTrustedDeviceService(serviceContext);
mCarMediaService = new CarMediaService(serviceContext, mCarUserService);
mCarBugreportManagerService = new CarBugreportManagerService(serviceContext);
if (!Build.IS_USER) {
mCarExperimentalFeatureServiceController = new CarExperimentalFeatureServiceController(
serviceContext);
} else {
mCarExperimentalFeatureServiceController = null;
}
if (carWatchdogService == null) {
mCarWatchdogService = new CarWatchdogService(serviceContext);
} else {
mCarWatchdogService = carWatchdogService;
}
// 將電源服務(wù),添加到Car本地服務(wù)List中-----------------------------
CarLocalServices.addService(CarPowerManagementService.class, mCarPowerManagementService);
CarLocalServices.addService(CarPropertyService.class, mCarPropertyService);
CarLocalServices.addService(CarUserService.class, mCarUserService);
CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService);
CarLocalServices.addService(CarUserNoticeService.class, mCarUserNoticeService);
CarLocalServices.addService(SystemInterface.class, mSystemInterface);
CarLocalServices.addService(CarDrivingStateService.class, mCarDrivingStateService);
CarLocalServices.addService(PerUserCarServiceHelper.class, mPerUserCarServiceHelper);
CarLocalServices.addService(FixedActivityService.class, mFixedActivityService);
CarLocalServices.addService(VmsBrokerService.class, mVmsBrokerService);
CarLocalServices.addService(CarOccupantZoneService.class, mCarOccupantZoneService);
CarLocalServices.addService(AppFocusService.class, mAppFocusService);
// Be careful with order. Service depending on other service should be inited later.
List<CarServiceBase> allServices = new ArrayList<>();
allServices.add(mFeatureController);
allServices.add(mCarUserService);
allServices.add(mSystemActivityMonitoringService);
// 將電源服務(wù),添加到Car服務(wù)List中-----------------------------
allServices.add(mCarPowerManagementService);
allServices.add(mCarPropertyService);
allServices.add(mCarDrivingStateService);
allServices.add(mCarOccupantZoneService);
allServices.add(mCarUXRestrictionsService);
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(mInstrumentClusterService);
allServices.add(mSystemStateControllerService);
allServices.add(mPerUserCarServiceHelper);
allServices.add(mCarBluetoothService);
allServices.add(mCarProjectionService);
addServiceIfNonNull(allServices, mCarDiagnosticService);
addServiceIfNonNull(allServices, mCarStorageMonitoringService);
allServices.add(mCarConfigurationService);
addServiceIfNonNull(allServices, mVmsBrokerService);
allServices.add(mCarTrustedDeviceService);
allServices.add(mCarMediaService);
allServices.add(mCarLocationService);
allServices.add(mCarBugreportManagerService);
allServices.add(mCarWatchdogService);
// Always put mCarExperimentalFeatureServiceController in last.
addServiceIfNonNull(allServices, mCarExperimentalFeatureServiceController);
mAllServices = allServices.toArray(new CarServiceBase[allServices.size()]);
}
}
- CarPower服務(wù)啟動(dòng)后,會(huì)注冊(cè)成為PowerHalService的監(jiān)聽者。并主動(dòng)發(fā)出WAIT_FOR_VHALL(初始狀態(tài))告知CarPower的監(jiān)聽者,并取一下當(dāng)前的屏幕亮度發(fā)送給VHAL。并連接Native層的CarPowerPolicyService來初始化電源管理政策。
// packages/services/Car/service/src/com/android/car/CarPowerManagementService.java
/**
* Power Management service class for cars. Controls the power states and interacts with other
* parts of the system to ensure its own state.
*/
public class CarPowerManagementService extends ICarPower.Stub implements
CarServiceBase, PowerHalService.PowerEventListener {
public CarPowerManagementService(Context context, PowerHalService powerHal,
SystemInterface systemInterface, CarUserService carUserService) {
this(context, context.getResources(), powerHal, systemInterface, UserManager.get(context),
carUserService, new InitialUserSetter(context,
(u) -> carUserService.setInitialUser(u),
context.getString(R.string.default_guest_name)),
IVoiceInteractionManagerService.Stub.asInterface(
ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)));
}
@VisibleForTesting
public CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal,
SystemInterface systemInterface, UserManager userManager, CarUserService carUserService,
InitialUserSetter initialUserSetter,
IVoiceInteractionManagerService voiceInteractionService) {
mContext = context;
mHal = powerHal;
mSystemInterface = systemInterface;
mUserManager = userManager;
mDisableUserSwitchDuringResume = resources
.getBoolean(R.bool.config_disableUserSwitchDuringResume);
mShutdownPrepareTimeMs = resources.getInteger(
R.integer.maxGarageModeRunningDurationInSecs) * 1000;
mSwitchGuestUserBeforeSleep = resources.getBoolean(
R.bool.config_switchGuestUserBeforeGoingSleep);
if (mShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) {
Slog.w(TAG,
"maxGarageModeRunningDurationInSecs smaller than minimum required, resource:"
+ mShutdownPrepareTimeMs + "(ms) while should exceed:"
+ MIN_MAX_GARAGE_MODE_DURATION_MS + "(ms), Ignore resource.");
mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS;
}
mUserService = carUserService;
mInitialUserSetter = initialUserSetter;
mVoiceInteractionManagerService = voiceInteractionService;
mWifiManager = context.getSystemService(WifiManager.class);
mWifiStateFile = new AtomicFile(
new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME));
}
}
@Override
public void init() {
mPolicyReader.init();
mPowerComponentHandler.init();
mHal.setListener(this);
if (mHal.isPowerStateSupported()) {
// 發(fā)出初始化狀態(tài)-------------------------------------------
// Initialize CPMS in WAIT_FOR_VHAL state
onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerStateListener.WAIT_FOR_VHAL);
} else {
Slogf.w(TAG, "Vehicle hal does not support power state yet.");
onApPowerStateChange(CpmsState.ON, CarPowerStateListener.ON);
}
// 監(jiān)控屏幕狀態(tài),這個(gè)函數(shù)中會(huì)將屏幕亮度發(fā)給Vehicle HAL
mSystemInterface.startDisplayStateMonitoring(this);
// 連接Car PowerPolicy服務(wù),初始化電源政策
connectToPowerPolicyDaemon();
}
- CarPower啟動(dòng)會(huì)立刻向監(jiān)聽者和VehicleHAL發(fā)出WAIT_FOR_VHAL這個(gè)狀態(tài)
// packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
private void doHandlePowerStateChange() {
CpmsState state;
synchronized (mLock) {
state = mPendingPowerStates.peekFirst();
mPendingPowerStates.clear();
if (state == null) {
Slogf.e(TAG, "Null power state was requested");
return;
}
Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", state.name());
if (!needPowerStateChangeLocked(state)) {
return;
}
// now real power change happens. Whatever was queued before should be all cancelled.
releaseTimerLocked();
mCurrentState = state;
}
mHandler.cancelProcessingComplete();
Slogf.i(TAG, "setCurrentState %s", state);
CarStatsLogHelper.logPowerState(state.mState);
switch (state.mState) {
case CpmsState.WAIT_FOR_VHAL:
// 處理WAIT_FOR_VHAL狀態(tài)----------------------------
handleWaitForVhal(state);
break;
case CpmsState.ON:
handleOn();
break;
case CpmsState.SHUTDOWN_PREPARE:
handleShutdownPrepare(state);
break;
case CpmsState.SIMULATE_SLEEP:
simulateShutdownPrepare();
break;
case CpmsState.WAIT_FOR_FINISH:
handleWaitForFinish(state);
break;
case CpmsState.SUSPEND:
// Received FINISH from VHAL
handleFinish();
break;
default:
// Illegal state
// TODO: Throw exception?
break;
}
}
private void handleWaitForVhal(CpmsState state) {
int carPowerStateListenerState = state.mCarPowerStateListenerState;
// TODO(b/177478420): Restore Wifi, Audio, Location, and Bluetooth, if they are artificially
// modified for S2R.
mSilentModeHandler.querySilentModeHwState();
// 給CarPower服務(wù)的監(jiān)聽者發(fā)送狀態(tài)
sendPowerManagerEvent(carPowerStateListenerState);
// Inspect CarPowerStateListenerState to decide which message to send via VHAL
switch (carPowerStateListenerState) {
case CarPowerStateListener.WAIT_FOR_VHAL:
// 通過PowerHAlService向VehicleHAL發(fā)送狀態(tài)
mHal.sendWaitForVhal();
break;
case CarPowerStateListener.SHUTDOWN_CANCELLED:
mShutdownOnNextSuspend = false; // This cancels the "NextSuspend"
mHal.sendShutdownCancel();
break;
case CarPowerStateListener.SUSPEND_EXIT:
mHal.sendSleepExit();
break;
}
if (mWifiAdjustmentForSuspend) restoreWifi();
}
- 接下來,MCU會(huì)給VehicleHAL發(fā)送電源通知,VehicleHAL通知(AP_POWER_STATE_REQ= ON) 給CarPower服務(wù)。
@Override
public void onHalEvents(List<VehiclePropValue> values) {
PowerEventListener listener;
synchronized (mLock) {
if (mListener == null) {
if (mQueuedEvents == null) {
mQueuedEvents = new LinkedList<>();
}
mQueuedEvents.addAll(values);
return;
}
listener = mListener;
}
dispatchEvents(values, listener);
}
private void dispatchEvents(List<VehiclePropValue> values, PowerEventListener listener) {
for (VehiclePropValue v : values) {
switch (v.prop) {
case AP_POWER_STATE_REPORT:
// Ignore this property event. It was generated inside of CarService.
break;
case AP_POWER_STATE_REQ:
// 發(fā)送的是這個(gè)狀態(tài)------ AP_POWER_STATE_REQ=ON
int state = v.value.int32Values.get(VehicleApPowerStateReqIndex.STATE);
int param = v.value.int32Values.get(VehicleApPowerStateReqIndex.ADDITIONAL);
Slog.i(CarLog.TAG_POWER, "Received AP_POWER_STATE_REQ="
+ powerStateReqName(state) + " param=" + param);
listener.onApPowerStateChange(new PowerState(state, param));
break;
case DISPLAY_BRIGHTNESS:
{
int maxBrightness;
synchronized (mLock) {
maxBrightness = mMaxDisplayBrightness;
}
int brightness = v.value.int32Values.get(0) * MAX_BRIGHTNESS / maxBrightness;
if (brightness < 0) {
Slog.e(CarLog.TAG_POWER, "invalid brightness: " + brightness
+ ", set to 0");
brightness = 0;
} else if (brightness > MAX_BRIGHTNESS) {
Slog.e(CarLog.TAG_POWER, "invalid brightness: " + brightness + ", set to "
+ MAX_BRIGHTNESS);
brightness = MAX_BRIGHTNESS;
}
Slog.i(CarLog.TAG_POWER, "Received DISPLAY_BRIGHTNESS=" + brightness);
listener.onDisplayBrightnessChange(brightness);
}
break;
}
}
}
- CarPowerService接收到 AP_POWER_STATE_REQ= ON,認(rèn)為當(dāng)前是電源ON的狀態(tài)。應(yīng)用電源策略(告知機(jī)能模塊可以使能)、通知觀察者電源狀態(tài)為ON,然后向VehicleHAL進(jìn)行回復(fù)(也叫report)
packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
@Override
public void onApPowerStateChange(PowerState state) {
synchronized (mLock) {
mPendingPowerStates.addFirst(new CpmsState(state));
mLock.notify();
}
// 發(fā)給handler,在單獨(dú)的線程中處理。最終調(diào)用的是自身的doHandlePowerStateChange函數(shù)
mHandler.handlePowerStateChange();
}
private void doHandlePowerStateChange() {
CpmsState state;
synchronized (mLock) {
state = mPendingPowerStates.peekFirst();
mPendingPowerStates.clear();
if (state == null) {
Slogf.e(TAG, "Null power state was requested");
return;
}
Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", state.name());
if (!needPowerStateChangeLocked(state)) {
return;
}
// now real power change happens. Whatever was queued before should be all cancelled.
releaseTimerLocked();
mCurrentState = state;
}
mHandler.cancelProcessingComplete();
Slogf.i(TAG, "setCurrentState %s", state);
CarStatsLogHelper.logPowerState(state.mState);
switch (state.mState) {
case CpmsState.WAIT_FOR_VHAL:
handleWaitForVhal(state);
break;
case CpmsState.ON:
// 處理電源ON----------------------------------------------------------------
handleOn();
break;
case CpmsState.SHUTDOWN_PREPARE:
handleShutdownPrepare(state);
break;
case CpmsState.SIMULATE_SLEEP:
simulateShutdownPrepare();
break;
case CpmsState.WAIT_FOR_FINISH:
handleWaitForFinish(state);
break;
case CpmsState.SUSPEND:
// Received FINISH from VHAL
handleFinish();
break;
default:
// Illegal state
// TODO: Throw exception?
break;
}
}
@VisibleForTesting
void handleOn() {
if (factoryResetIfNeeded()) return;
// If current user is a Guest User, we want to inform CarUserNoticeService not to show
// notice for current user, and show user notice only for the target user.
if (!mSwitchGuestUserBeforeSleep) {
updateCarUserNoticeServiceIfNecessary();
}
boolean isPreemptive;
synchronized (mLock) {
isPreemptive = mPolicyReader.isPreemptivePowerPolicy(mCurrentPowerPolicyId);
}
if (!mSilentModeHandler.isSilentMode() && isPreemptive) {
cancelPreemptivePowerPolicy();
} else {
// 應(yīng)用電源策略---------------------------------
applyDefaultPowerPolicyForState(VehicleApPowerStateReport.ON,
PolicyReader.POWER_POLICY_ID_ALL_ON);
}
// 通知觀察者電源狀態(tài)為ON------------------------
sendPowerManagerEvent(CarPowerStateListener.ON);
// 通過PowerHAlServicee,回復(fù)Vehicle HAL(VehicleApPowerStateReport.ON)
mHal.sendOn();
synchronized (mLock) {
if (mIsBooting) {
Slogf.d(TAG, "handleOn(): called on boot");
mIsBooting = false;
return;
}
}
try {
mUserService.onResume();
} catch (Exception e) {
Slogf.e(TAG, e, "Could not switch user on resume");
}
}
- 到這里,CarPower主要的開機(jī)處理流程完畢。實(shí)際上可以看出來,主要是接收Vehicle HAl Event(包括回復(fù)VehicleHAL狀態(tài)),告知監(jiān)聽者電源狀態(tài)、應(yīng)用電源政策使能相關(guān)機(jī)能。并且在啟動(dòng)階段,取了一下當(dāng)前的屏幕亮度,告知VehicleHAL(最終是告知MCU)。當(dāng)然還有一些其他的處理,比如用戶服務(wù)的恢復(fù),有興趣的可以讀一下這部分代碼。
- CarPowerService上電時(shí)序圖。
到了這里,關(guān)于【Android】Android Framework系列---CarPower電源管理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!