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

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上电时序图。
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【观察】Dell APEX云平台:引领多云时代上云新范式

毫无疑问&#xff0c;过去十多年是云计算发展的黄金十年&#xff0c;云计算理念不断被市场所接受&#xff0c;但随着企业上云深入和认知度的不断增加&#xff0c;摆在很多企业面前的选择题也发生了新变化&#xff0c;即从过去企业上云或不上云的纠结&#xff0c;转变成今天如何…

【数据结构练习题】删除有序数组中的重复项

✨博客主页&#xff1a;小钱编程成长记 &#x1f388;博客专栏&#xff1a;数据结构练习题 &#x1f388;相关博文&#xff1a;消失的数字 — 三种解法超详解 删除有序数组中的重复项 1.&#x1f388;题目2. &#x1f388;解题思路3. &#x1f388;具体代码&#x1f387;总结 1…

【Spring】Spring MVC请求响应

文章目录 1. 请求1.1 传递单个参数1.2 传递多个参数1.3 传递对象1.4 后端参数重命名1.5 传递数组1.6 传递集合1.7 传递JSON对象1.8 获取URL中参数1.9 上传⽂件1.10 获得Cookie1.11 获得Session1.12 获得Header 2. 响应2.1 返回静态界面2.2 返回数据2.3 返回HTML代码片段2.4 返回…

前端Vue页面中如何展示本地图片

<el-table :data"tableData" stripe style"width: 100%"><el-table-column prop"imgUrl" label"图片"><template v-slot"scope"><img :src "http://localhost:8888/image/ scope.row.imgUrl&qu…

基于springboot实现网吧管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现网吧管理系统演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#x…

2023上半年系统集成项目管理工程师下午真题

文章目录 一&#xff1a;第5章 项目立项管理。第7章 项目范围管理&#xff0c;需求文件二&#xff1a;第9章 项目成本管理。第8章 项目进度管理&#xff0c;压缩工期三&#xff1a;第15章 信息&#xff08;文档&#xff09;和配置管理四&#xff1a;第18章 项目风险管理&#x…

【Java 进阶篇】Java Request 请求转发详解

在Java Web开发中&#xff0c;请求转发&#xff08;Request Forwarding&#xff09;是一种常见的技术&#xff0c;用于将请求从一个Servlet转发到另一个Servlet或JSP页面。这种技术在Web应用程序中起着非常重要的作用&#xff0c;可以用于实现模块化、重用代码以及构建更加灵活…

多输入多输出 | Matlab实现k-means-LSTM(k均值聚类结合长短期记忆神经网络)多输入多输出组合预测

多输入多输出 | Matlab实现k-means-LSTM&#xff08;k均值聚类结合长短期记忆神经网络&#xff09;多输入多输出组合预测 目录 多输入多输出 | Matlab实现k-means-LSTM&#xff08;k均值聚类结合长短期记忆神经网络&#xff09;多输入多输出组合预测预测效果基本描述程序设计参…

设计模式(19)命令模式

一、介绍&#xff1a; 1、定义&#xff1a;命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使你可以使用不同的请求对客户端进行参数化。命令模式还支持请求的排队、记录日志、撤销操作等功能。 2、组…

Ubuntu 23.10(Mantic Minotaur)正式发布,支持Linux 6.5和GNOME 45

导读Canonical 近日正式发布了 Ubuntu 23.10&#xff08;Mantic Minotaur&#xff09;操作系统&#xff0c;其中包含一些最新的 GNU/Linux 技术、改进的硬件支持以及许多其他变化。 Ubuntu 23.10 采用了最新的 Linux 6.5 内核系列&#xff0c;并为 Ubuntu 桌面和服务器增强了 z…

BI是什么?想要了解BI需要从哪些方面入手?

企业为了执行数字化战略&#xff0c;实行数字化转型&#xff0c;实现数据价值&#xff0c;除了需要相关数字化技术及理念、人才等&#xff0c;还需要借助数字化相关应用&#xff0c;例如商业世界中广受企业欢迎的ERP、OA、CRM等业务信息系统&#xff0c;以及上升势头非常迅猛的…

Powershell脚本自动备份dhcp数据库

文章目录 为什么要备份DHCP数据库呢&#xff1f;在PowerShell中自动备份DHCP数据库1&#xff0c;创建备份目录2&#xff0c;判断备份路径是否存在3&#xff0c;备份DHCP数据库4&#xff0c;完整自动备份脚本5&#xff0c;安排定期备份 推荐阅读 为什么要备份DHCP数据库呢&#…

红队专题-从零开始VC++C/S远程控制软件RAT-MFC-屏幕监控

红队专题 招募六边形战士队员[24]屏幕监控-(1)屏幕查看与控制技术的讲解图像压缩算法图像数据转换其他 [25]---屏幕监控(2)查看屏幕的实现 招募六边形战士队员 一起学习 代码审计、安全开发、web攻防、逆向等。。。 私信联系 [24]屏幕监控-(1)屏幕查看与控制技术的讲解 屏幕…

CV计算机视觉每日开源代码Paper with code速览-2023.10.27

精华置顶 墙裂推荐&#xff01;小白如何1个月系统学习CV核心知识&#xff1a;链接 点击CV计算机视觉&#xff0c;关注更多CV干货 论文已打包&#xff0c;点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【基础网络架构&#xff1a;Transformer】&#xff08;Ne…

前端实现埋点监控

前端实现埋点&监控 实现埋点功能的意义主要体现在以下几个方面&#xff1a; 数据采集&#xff1a;埋点是数据采集领域&#xff08;尤其是用户行为数据采集领域&#xff09;的术语&#xff0c;它针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。通过埋…

附录B 其他第三方软件移植(FTP、OpenSSH、GDB)

目录 开发板 FTP 服务器移植与搭建vsftpd 源码下载vsftpd 移植vsftpd 服务器测试配置vsftpd添加新用户Filezilla 连接测试 开发板 OpenSSH 移植与使用OpenSSH 简介OpenSSH 移植OpenSSH 源码获取移植zlib 库移植openssl 库移植openssh 库 openssh 设置openssh 使用ssh 登录scp 命…

利用Excel支持JUnit参数化测试

在JUnit里面&#xff0c;可以使用CsvFileSource读取csv文件进行参数化测试&#xff0c;可是CSV文件不支持格式&#xff0c;编辑颇为麻烦&#xff0c;尤其是多次编辑&#xff0c;因此自然想到是否可以使用Excel文件&#xff0c;可以有各种格式&#xff0c;支持各类数据。 最新开…

常见面试题-MySQL专栏(一)

为什么 mysql 删了行记录&#xff0c;反而磁盘空间没有减少&#xff1f; 答&#xff1a; 在 mysql 中&#xff0c;当使用 delete 删除数据时&#xff0c;mysql 会将删除的数据标记为已删除&#xff0c;但是并不去磁盘上真正进行删除&#xff0c;而是在需要使用这片存储空间时&…

(速进)完美解决“用户在命令行上发出了 EULAS_AGREED=1,表示不接受许可协议。”以及“此产品安装程序不支持降级”

安装VMware时候&#xff0c;出现以下两种情况的原因是&#xff1a;未彻底卸载&#xff08;之前安装过VMware&#xff09;&#xff0c;例如&#xff1a;还有相关配置信息、注册表信息等。只要彻底清理就可以解决此问题。 网上很多帖子使用了powershell里的命令 例如&#xff1…

基于 matplotlib 实现的基本排序算法的动态可视化项目源码,通过 pyaudio 增加音效,冒泡、选择、插入、快速等排序

基本排序算法动态可视化 依托 matplotlib 实现的基本排序算法的动态可视化&#xff0c;并通过 pyaudio 增加音效。 安装 在使用之前请先检查本地是否存在以下库&#xff1a; matplotlibpyaudiofire requirements.txt 中包含了上述的库 使用 目前本项目仅提供了以下排序算…