愛做網(wǎng)站免費模板vip北京優(yōu)化網(wǎng)站公司
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)會比較復(fù)雜,既要滿足車內(nèi)的座艙系統(tǒng)啟動足夠快,又要保證汽車蓄電池的可考性,所以出了開機(jī)(on)、關(guān)機(jī)(off)外,會多出來一些電源狀態(tài)(Suspend、STR、SLEEP等等)
所以,一般來說軟件系統(tǒng)是需要一個專門的電源管理模塊的。
CarPower電源管理
Android Automotive(基于Android平臺的車載信息娛樂系統(tǒng))提供了CarPower模塊用于管理電源狀態(tài)。CarPower Service屬于CarService,在SystemSever的startOtherService階段啟動。
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)變化時,MCU一般會拉低或者拉高某個引腳,然后通知事件給VehicleHAL,VehicleHAL再通過PropertyEvent通知給CarPower Service。Android系統(tǒng)處理完電源狀態(tài)后(有超時要求),再由VehiclHAL告知MCU,MCU在對某個引腳進(jìn)行相關(guān)操作。
CarPower電源管理的開機(jī)流程
下面以Android車載系統(tǒng)開機(jī)為例。說明一下CarPower模塊的開機(jī)時序。代碼基于Android12.
- CarPower服務(wù)啟動:Android系統(tǒng)開機(jī)上電,在systemServer中啟動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();// 啟動了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啟動后會創(chuàng)建CarPower實例。
<!-- 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);}@VisibleForTestingICarImpl(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ù)實例-----------------------------------------------------------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ù)啟動后,會注冊成為PowerHalService的監(jiān)聽者。并主動發(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 implementsCarServiceBase, 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)));}@VisibleForTestingpublic 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 stateonApPowerStateChange(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),這個函數(shù)中會將屏幕亮度發(fā)給Vehicle HALmSystemInterface.startDisplayStateMonitoring(this);// 連接Car PowerPolicy服務(wù),初始化電源政策connectToPowerPolicyDaemon();
}
- CarPower啟動會立刻向監(jiān)聽者和VehicleHAL發(fā)出WAIT_FOR_VHAL這個狀態(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 VHALhandleFinish();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 VHALswitch (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會給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ā)送的是這個狀態(tài)------ AP_POWER_STATE_REQ=ONint 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,在單獨的線程中處理。最終調(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 VHALhandleFinish();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ī)處理流程完畢。實際上可以看出來,主要是接收Vehicle HAl Event(包括回復(fù)VehicleHAL狀態(tài)),告知監(jiān)聽者電源狀態(tài)、應(yīng)用電源政策使能相關(guān)機(jī)能。并且在啟動階段,取了一下當(dāng)前的屏幕亮度,告知VehicleHAL(最終是告知MCU)。當(dāng)然還有一些其他的處理,比如用戶服務(wù)的恢復(fù),有興趣的可以讀一下這部分代碼。
- CarPowerService上電時序圖。