AndroidAndroid Framework Series—CarPower Power Management

Android Framework Series-CarPower Power Management

Smart cockpits usually include central control systems, instrument systems, IVI systems, rear entertainment, HUD, Internet of Vehicles, etc. These systems require power from the vehicle’s power supply. Due to the car’s own special power supply environment (compared to the convenient charging environment of mobile phones, if the car’s battery is out of power, it needs to be operated by professionals), its power state will be more complicated. It must not only satisfy the need for the cockpit system in the car to start up quickly enough, but also To ensure the testability of the car battery, in addition to power on (on) and power off (off), there will be some more power states (Suspend, STR, SLEEP, etc.)

Therefore, generally speaking, software systems require a specialized power management module.

CarPower Power Management

Android Automotive (car infotainment system based on Android platform) provides the CarPower module for managing power status. CarPower Service belongs to CarService and is started in the startOtherService phase of SystemSever.

CarPower Service makes relevant logical judgments based on the power status notification from Vehicle HAL (Hal layer service), applies the power policy (simply understood as informing certain services to enable or disable), and sends status notifications to its own listeners. Reply (Report) VehcileHAL processing results.
Generally speaking, the power status of Vehicle HAL comes from the MCU (can communication or Ethernet communication, the specific form is determined by Vehicle HAL and related suppliers). When the power status changes, the MCU usually pulls a certain pin low or high, and then notifies the event to VehicleHAL, which then notifies the CarPower Service through PropertyEvent. After the Android system handles the power status (there is a timeout requirement), VehiclHAL informs the MCU that the MCU is performing related operations on a certain pin.

CarPower power management boot process

The following takes booting the Android car system as an example. Explain the boot sequence of the CarPower module. The code is based on Android12.

  • CarPower service startup: Power on the Android system and start CarService in systemServer.
// 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();
// Started 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();
}
  • After CarService is started, a CarPower instance will be created.
<!-- 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 & amp; & amp; !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);
//The CarPower service instance is created here--------------------------------------------- ------------------
        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;
        }
//Add the power service to the Car local service 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);
//Add the power service to the Car service 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()]);
    }
}
  • After the CarPower service is started, it will register as a listener of PowerHalService. And actively send WAIT_FOR_VHALL (initial state) to inform the CarPower listener, and take the current screen brightness and send it to VHAL. And connect the CarPowerPolicyService of the Native layer to initialize the power management policy.
// 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()) {<!-- -->
//Emit initialization status------------------------------------------------
// 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);
}
// Monitor the screen status. In this function, the screen brightness will be sent to Vehicle HAL
mSystemInterface.startDisplayStateMonitoring(this);
// Connect to the Car PowerPolicy service and initialize the power policy
connectToPowerPolicyDaemon();
}
  • When CarPower starts, it will immediately send the WAIT_FOR_VHAL status to the listener and VehicleHAL.
// 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 canceled.
releaseTimerLocked();
mCurrentState = state;
}
mHandler.cancelProcessingComplete();
Slogf.i(TAG, "setCurrentState %s", state);
CarStatsLogHelper.logPowerState(state.mState);
switch (state.mState) {<!-- -->
case CpmsState.WAIT_FOR_VHAL:
//Handle WAIT_FOR_VHAL status---------------------------------
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();
//Send status to the listener of CarPower service
sendPowerManagerEvent(carPowerStateListenerState);
// Inspect CarPowerStateListenerState to decide which message to send via VHAL
switch (carPowerStateListenerState) {<!-- -->
case CarPowerStateListener.WAIT_FOR_VHAL:
//Send status to VehicleHAL through PowerHAlService
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();
}

  • Next, the MCU will send a power notification to VehicleHAL, and VehicleHAL notifies (AP_POWER_STATE_REQ= ON) to the CarPower service.
@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:
// This state is sent ------ 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 receives AP_POWER_STATE_REQ= ON and considers that the current power supply is ON. Apply the power policy (notify the functional module that it can be enabled), notify the observer that the power status is ON, and then reply to VehicleHAL (also called 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();
}
//Send to handler for processing in a separate thread. The final call is its own doHandlePowerStateChange function
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 canceled.
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:
// Handle power 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() & amp; & amp; isPreemptive) {<!-- -->
cancelPreemptivePowerPolicy();
} else {<!-- -->
// Apply power policy---------------------------------
applyDefaultPowerPolicyForState(VehicleApPowerStateReport.ON,
PolicyReader.POWER_POLICY_ID_ALL_ON);
}
//Notify observers that the power status is ON------------------------
sendPowerManagerEvent(CarPowerStateListener.ON);
//Reply to Vehicle HAL (VehicleApPowerStateReport.ON) through PowerHAlServicee
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");
}
}
  • At this point, the main boot process of CarPower is completed. In fact, it can be seen that it mainly receives Vehicle HAl Event (including replying to Vehicle HAL status), informs the listener of the power status, and applies power policies to enable related functions. And during the startup phase, the current screen brightness is taken and notified to VehicleHAL (and ultimately to the MCU). Of course, there are some other processes, such as the restoration of user services. If you are interested, you can read this part of the code.
  • CarPowerService power-on sequence diagram.