【Android】Android Framework系列---CarPower电源管理

news2024/11/23 12:13:36

Android Framework系列—CarPower电源管理

智能座舱通常包括中控系统、仪表系统、IVI系统 、后排娱乐、HUD、车联网等。这些系统需要由汽车电源进行供电。由于汽车自身的特殊供电环境(相比手机方便的充电环境,汽车的蓄电池如果没有电是需要专业人士操作的),其电源状态会比较复杂,既要满足车内的座舱系统启动足够快,又要保证汽车蓄电池的可考性,所以出了开机(on)、关机(off)外,会多出来一些电源状态(Suspend、STR、SLEEP等等)

所以,一般来说软件系统是需要一个专门的电源管理模块的。

CarPower电源管理

Android Automotive(基于Android平台的车载信息娱乐系统)提供了CarPower模块用于管理电源状态。CarPower Service属于CarService,在SystemSever的startOtherService阶段启动。
在这里插入图片描述
CarPower Service根据来自于 Vehicle HAL(Hal层服务)的电源状态通知,进行相关的逻辑判断后,应用电源策略(简单理解成告知某些服务Enable 或者Disable)、发送状态通知给它自身的监听者、回复(Report)VehcileHAL处理结果。
Vehicle HAL的电源状态一般来讲是来自于MCU的(can通信 或者以太网通信,具体形式由Vehicle HAL和相关供应商决定)。电源状态变化时,MCU一般会拉低或者拉高某个引脚,然后通知事件给VehicleHAL,VehicleHAL再通过PropertyEvent通知给CarPower Service。Android系统处理完电源状态后(有超时要求),再由VehiclHAL告知MCU,MCU在对某个引脚进行相关操作。
在这里插入图片描述

CarPower电源管理的开机流程

下面以Android车载系统开机为例。说明一下CarPower模块的开机时序。代码基于Android12.

  • CarPower服务启动:Android系统开机上电,在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启动后会创建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);
    }

    @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);
		// 这里创建了CarPower服务实例-----------------------------------------------------------
        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;
        }
		//  将电源服务,添加到Car本地服务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);
		//  将电源服务,添加到Car服务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服务启动后,会注册成为PowerHalService的监听者。并主动发出WAIT_FOR_VHALL(初始状态)告知CarPower的监听者,并取一下当前的屏幕亮度发送给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()) {
		// 发出初始化状态-------------------------------------------
		// 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);
	}
	//  监控屏幕状态,这个函数中会将屏幕亮度发给Vehicle HAL
	mSystemInterface.startDisplayStateMonitoring(this);
	//  连接Car PowerPolicy服务,初始化电源政策
	connectToPowerPolicyDaemon();
}
  • CarPower启动会立刻向监听者和VehicleHAL发出WAIT_FOR_VHAL这个状态
// 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状态----------------------------
			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服务的监听者发送状态
	sendPowerManagerEvent(carPowerStateListenerState);
	// Inspect CarPowerStateListenerState to decide which message to send via VHAL
	switch (carPowerStateListenerState) {
		case CarPowerStateListener.WAIT_FOR_VHAL:
			// 通过PowerHAlService向VehicleHAL发送状态
			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发送电源通知,VehicleHAL通知(AP_POWER_STATE_REQ= ON) 给CarPower服务。
@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:
				// 发送的是这个状态------ 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,认为当前是电源ON的状态。应用电源策略(告知机能模块可以使能)、通知观察者电源状态为ON,然后向VehicleHAL进行回复(也叫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();
	}
	// 发给handler,在单独的线程中处理。最终调用的是自身的doHandlePowerStateChange函数
	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 {
		// 应用电源策略---------------------------------
		applyDefaultPowerPolicyForState(VehicleApPowerStateReport.ON,
				PolicyReader.POWER_POLICY_ID_ALL_ON);
	}
	// 通知观察者电源状态为ON------------------------
	sendPowerManagerEvent(CarPowerStateListener.ON);
	// 通过PowerHAlServicee,回复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主要的开机处理流程完毕。实际上可以看出来,主要是接收Vehicle HAl Event(包括回复VehicleHAL状态),告知监听者电源状态、应用电源政策使能相关机能。并且在启动阶段,取了一下当前的屏幕亮度,告知VehicleHAL(最终是告知MCU)。当然还有一些其他的处理,比如用户服务的恢复,有兴趣的可以读一下这部分代码。
  • CarPowerService上电时序图。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1148122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

这个第一个输出为啥是2 不是4 啊?

#include <iostream> using namespace std;class Point{ public:int x;int y;Point(int x1, int y1) : x(x1), y(y1) //成员初始化列表{ }int getDistance() {return x * x y * y;} };void changePoint1(Point point) //使用对象作为函数参数 {point.x 1;point.y -…

上海高考英语科目命题趋势和备考建议,附1990-2023真题解析

英语和语文一样&#xff0c;都是侧重语言的阅读理解、交流和运用&#xff0c;但是英语作为外国语和语文又不太一样&#xff0c;相对来说考的更简单一些。不过要拿高分也不容易。 为了帮助高三的学子们提升英语备考的效率&#xff0c;争取多提分&#xff0c;六分职场特撰写这篇…

信息系统项目管理师教程 第四版【第5章-信息系统工程-思维导图】

信息系统项目管理师教程 第四版【第5章-信息系统工程-思维导图】 课本里章节里所有蓝色字体的思维导图

ZYNQ连载05-Vitis更新xsa硬件配置

ZYNQ连载05-Vitis更新xsa硬件配置 1. 简述 在开发过程中&#xff0c;Vivado中硬件配置在开发过程中有所变动&#xff0c;Vitis需要根据Vivado生成的xsa文件&#xff0c;更新相应的BSP配置 2. 操作步骤

基于SSM的个性化美食推荐系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

【斗罗二】王东升级三环,戴华斌挑衅,雨浩单手接鼎订下赌约

【侵权联系删除】【文/郑尔巴金】 深度爆料&#xff0c;《绝世唐门》第20集&#xff0c;一场瞩目的战斗即将爆发。王冬&#xff0c;这位一年级的强攻系班长&#xff0c;将与戴华斌进行一场激烈的较量。王冬拥有三大武魂&#xff0c;其中最为人们所熟知的是那光明女神蝶&#x…

美食论坛大全订阅交流系统 uniapp+vue 微信小程序设计与实现

美食大全订阅小程序在系统的智能手机上可以运行&#xff0c;主要实现了首页、个人中心、用户管理、菜系管理、口味管理、美食分类管理、美食信息管理、美食论坛、系统管理等主要功能模块的操作和管理。 后端&#xff1a;java(springbootssm)/python/php/nodejs/ 开发运行&…

Mac 安装使用NPM及常用命令

环境&#xff1a; Mac 工具&#xff1a; NPM 可通过官网查询一些模块相关 NPM Doc 通过官网文档了解更多的关于NPM的使用 安装 NPM是Node.js的包管理工具&#xff0c;可用于解决 Node.js在代码部署上的问题。 新版本的Node.js已经集成了NPM&#xff0c; 因此可通过下载 Nod…

Linux网络编程二(TCP三次握手、四次挥手、TCP滑动窗口、MSS、TCP状态转换、多进程/多线程服务器实现)

TCP三次握手 TCP三次握手(TCP three-way handshake)是TCP协议建立可靠连接的过程&#xff0c;确保客户端和服务器之间可以进行可靠的通信。下面是TCP三次握手的详细过程&#xff1a; 假设客户端为A&#xff0c;服务器为B 1、第一次握手&#xff08;SYN1&#xff0c;seq500&…

【存储】lotusdb的原理及实现

最近看了lotusdb的源码。lotusdb是一个golang实现的嵌入式的持久化kv存储。 从整体设计上看&#xff0c;lotusdb采用了类似LSM树的架构&#xff0c;并采用了针对SSD的优化&#xff0c;将key和value分开存储。在此基础上&#xff0c;lotusdb将LSM树中存储key的SST使用B树或者ha…

进阶JAVA篇-了解 File 文件的常用API

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 1.0 File 文件的说明 2.0 如何创建 File 类的对象 2.1 需要注意的事项 3.0 File 类的常用 API 3.1 如何创建文件或文件夹 3.2 如何查询文件和文件夹的信息 3.3 如何删除文件和…

鸿蒙系统、澎湃系统和安卓系统的区别一看就懂

前言 最近看了小米澎湃OS的发布会&#xff0c;这是继华为鸿蒙OS脱离Android OS后&#xff0c;国内发布的另一个重量级的操作系统。 依稀记得&#xff0c;当初鸿蒙OS问世的时候&#xff0c;很多人都质疑它是Android OS的套壳&#xff0c;对鸿蒙系统提出了诸多质疑和否定。 现趁着…

ActiveMQ

ActiveMQ 安装 下载网址&#xff1a;ActiveMQ 一定要和自己安装的jdk版本匹配&#xff0c;不然会报错 下载到本地之后解压缩 有可能端口号被占用 解除端口号占用&#xff0c;参考&#xff1a;Windows_端口被占用 打开cmd 查询所有的端口号 netstat -nao查询指定端口号 n…

基于STM32的示波器信号发生器设计

**单片机设计介绍&#xff0c;基于STM32的示波器信号发生器设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序文档 六、 文章目录 一 概要 基于STM32的示波器信号发生器是一种高性能的电子仪器&#xff0c;用于测试和分析电路中的电信号。在该系统中&a…

ZKP7.1 Polynomial Commitments Based on Error-correcting Codes (Background)

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 7: Polynomial Commitments Based on Error-correcting Codes (Yupeng Zhang) Recall: common paradigm for efficient SNARK A polynomial commitment scheme A polynomial interactive oracle proof (IOP) SNARK for gene…

AD9371 官方例程HDL详解之JESD204B RX侧格式配置及各层主要功能

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 采样率和各个时钟之间的关系 &#xff1a; AD9371 官方例程HDL详解之JESD204B TX侧时钟生成 &#xff08;三&#xff09; 参考资料&#xff1a; UltraScale Architecture G…

Jenkins git 克隆代码超时问题解决

目录 一、问题描述二、解决方案方式一&#xff1a;手动配置超时时间方式二&#xff1a;浅克隆&#xff08;推荐&#xff09; 一、问题描述 在使用 Jenkins 首次进行服务部署的时候&#xff0c;如果我们项目的 .git 文件夹太大&#xff0c;可能会导致 git clone 失败。 在 Jen…

当『后设学习』碰上『工程学思维』

只要我成为一个废物&#xff0c;就没人能够利用我&#xff01; 雷猴啊&#xff0c;我是一只临期程序猿。打过几年工&#xff0c;写过几行代码。但今天我不想聊代码&#xff0c;我们聊聊学习这件事。 技术年年更新&#xff0c;尤其是前端框架&#xff0c;很多时候觉得学习速度都…

leetcode-栈与队列

C中stack 是容器么&#xff1f; 栈&#xff0c;队列往往不被归类为容器&#xff0c;而被归类为container adapter(容器适配器)。因为由底层的容器实现&#xff0c;同时使用适配器模式的设计模式&#xff0c;封装了一层。 我们使用的stack是属于哪个版本的STL&#xff1f;SGI ST…

【Java 进阶篇】解决Java Web应用中请求参数中文乱码问题

在Java Web应用开发中&#xff0c;处理请求参数时经常会遇到中文乱码的问题。当浏览器向服务器发送包含中文字符的请求参数时&#xff0c;如果不正确处理&#xff0c;可能会导致乱码问题&#xff0c;使得参数无法正确解析和显示。本文将详细探讨Java Web应用中请求参数中文乱码…