PowerManagerService负责Android系统的电源管理,常见的功能有:点亮屏幕、熄灭屏幕、进入屏保等,PowerManagerService继承自SystemService,由SystemServer启动、注册到系统服务中,通过Binder和其他组件进行交互。
PowerManagerService 具有
构造方法:通过反射调用,获取实例; onstart()方法:开启对应的SystemService; onBootPhase()方法:在SystemService服务的启动过程中指定服务的启动阶段,每个阶段指定特定的工作;
PMS的启动:---通过SystemServer启动:
1.在SystemServer的main方法中调用
new SystemServer().run();
2.在run方法中启动相应的的Services
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
}
系统将服务分为了三类:
引导服务:
核心服务:
其他服务:
引导服务 |
作用 |
Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |
ActivityManagerService |
负责四大组件的启动、切换、调度。 |
PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
LightsService | 管理和显示背光LED |
DisplayManagerService |
用来管理所有显示设备 |
UserManagerService |
多用户模式管理 |
SensorService |
为系统提供各种感应器服务 |
PackageManagerService |
用来对apk进行安装、解析、删除、卸载等等操作 |
核心服务 |
|
BatteryService | 管理电池相关的服务 |
UsageStatsService | 收集用户使用每一个APP的频率、使用时常 |
WebViewUpdateService | WebView更新服务 |
其他服务 | |
CameraService | 摄像头相关服务 |
AlarmManagerService | 全局定时器管理服务 |
InputManagerService | 管理输入事件 |
WindowManagerService | 窗口管理服务 |
VrManagerService | VR模式管理服务 |
BluetoothService | 蓝牙管理服务 |
NotificationManagerService | 通知管理服务 |
DeviceStorageMonitorService | 存储相关管理服务 |
LocationManagerService | 定位管理服务 |
AudioService | 音频相关管理服务 |
3.startBootstrapServices方法中启动PowerManagerService
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
4.PMS依次执行构造方法、onStart()、onBootPhase()(会调用多次)方法后,会执行systemReady()方法,该方法主要完成电源的管理
获取各类本地服务和远程服务:
mDreamManager = getLocalService(DreamManagerInternal.class);
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
mPolicy = getLocalService(WindowManagerPolicy.class);
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
mAttentionDetector.systemReady(mContext);
//获取屏幕亮度相关
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
//传感器相关
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
// The notifier runs on the system server's main looper so as not to interfere
// with the animations and other critical functions of the power manager.
mBatteryStats = BatteryStatsService.getService();
//mNotifier用于PMS和其他系统服务间的交互,以及广播的发送
mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats,
mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
mPolicy);
mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
mInjector.createSuspendBlocker(
this, "PowerManagerService.WirelessChargerDetector"),
mHandler);
//系统设置的变化监听
mSettingsObserver = new SettingsObserver(mHandler);
mLightsManager = getLocalService(LightsManager.class);
mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
//mDisplayPowerCallbacks提供PMS和Display的接口,当DisplayPowerController发生改变,通过该接口回调PMS中的实现
//initPowerManagement()方法中实例化了DisplayPowerController, DPC是和显示有关,如亮灭屏、背光调节
// Initialize display power management.
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
注册观察setting变化的resolver
// SCREENSAVER_ENABLED 屏保功能开启
// SCREENSAVER_ACTIVATE_ON_SLEEP 在睡眠时屏保启动
// SCREENSAVER_ACTIVATE_ON_DOCK 连接底座并且屏保启动
// SCREEN_OFF_TIMEOUT 进入dream状态前未活动时间
// SLEEP_TIMEOUT 进入sleep状态前未活动时间
// STAY_ON_WHILE_PLUGGED_IN 有插入并且屏幕开启
// SCREEN_BRIGHTNESS 屏幕亮度
// SCREEN_BRIGHTNESS_MODE 屏幕亮度模式
// SCREEN_AUTO_BRIGHTNESS_ADJ 自动亮度
// LOW_POWER_MODE 低电量模式
// LOW_POWER_MODE_TRIGGER_LEVEL 低电量模式触发条件(电量低于多少,进入低电量模式)
final ContentResolver resolver = mContext.getContentResolver();
mConstants.start(resolver);
mBatterySaverController.systemReady();
mBatterySaverPolicy.systemReady();
// Register for settings changes.
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ENABLED),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SLEEP_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.THEATER_MODE_ON),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DOZE_ALWAYS_ON),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DOUBLE_TAP_TO_WAKE),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.DEVICE_DEMO_MODE),
false, mSettingsObserver, UserHandle.USER_SYSTEM);
注册广播:
// Register for broadcasts from other components of the system.
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DREAMING_STARTED);
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DOCK_EVENT);
mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
5.读取属性配置值
void readConfigurationLocked() {
final Resources resources = mContext.getResources();
/**
* auto_suspend模式是否和display分离
* 如果为false,则在亮屏前调用autosuspend_disable(),灭屏后调用
* autosuspend_enable();
* 如果为ture,则调用autosuspend_display()和autosuspend_enable()独立于display
* on/off.
*/
mDecoupleHalAutoSuspendModeFromDisplayConfig = resources.getBoolean(
com.android.internal.R.bool.config_powerDecoupleAutoSuspendModeFromDisplay);
/*
* interactive模式是否和display分离
* 如果为false,则在亮屏前调用setInteractive(…, true),灭屏后调用
* setInteractive(…,false);
* 如果为ture,则调用setInteractive(…)独立于display on/off.
*/
mDecoupleHalInteractiveModeFromDisplayConfig = resources.getBoolean(
com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay);
//插拔USB是否亮屏
mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
com.android.internal.R.bool.config_unplugTurnsOnScreen);
mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug);
//是否允许设备由于接近传感器而关闭屏幕时CPU挂起,进入suspend状态
mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
//是否支持屏保
mDreamsSupportedConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsSupported);
//屏保默认开启
mDreamsEnabledByDefaultConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsEnabledByDefault);
//充电和睡眠时屏保是否激活
mDreamsActivatedOnSleepByDefaultConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
//放电
mDreamsEnabledOnBatteryConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsEnabledOnBattery);
//充电时可以使用屏保的最低电量
mDreamsBatteryLevelMinimumWhenPoweredConfig = resources.getInteger(
com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenPowered);
//放电时可以使用屏保的最低电量
mDreamsBatteryLevelMinimumWhenNotPoweredConfig = resources.getInteger(
com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenNotPowered);
//电亮下降到该百分点,当用户活动超时后不进入屏保,默认5
mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
mDozeAfterScreenOff = resources.getBoolean(
com.android.internal.R.bool.config_dozeAfterScreenOffByDefault);
mMinimumScreenOffTimeoutConfig = resources.getInteger(
com.android.internal.R.integer.config_minimumScreenOffTimeout);
//用户活动超时进入且关闭屏幕前屏幕变暗的最大时间,默认7000ms,必须大于0
mMaximumScreenDimDurationConfig = resources.getInteger(
com.android.internal.R.integer.config_maximumScreenDimDuration);
mMaximumScreenDimRatioConfig = resources.getFraction(
com.android.internal.R.fraction.config_maximumScreenDimRatio, 1, 1);
//是否支持双击点亮屏幕
mSupportsDoubleTapWakeConfig = resources.getBoolean(
com.android.internal.R.bool.config_supportDoubleTapWake);
}
6.更新setting状态的变化
private void updateSettingsLocked() {
final ContentResolver resolver = mContext.getContentResolver();
mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
Settings.Secure.SCREENSAVER_ENABLED,
mDreamsEnabledByDefaultConfig ? 1 : 0,
UserHandle.USER_CURRENT) != 0);
mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
UserHandle.USER_CURRENT) != 0);
mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
UserHandle.USER_CURRENT) != 0);
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
UserHandle.USER_CURRENT);
mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,
Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,
UserHandle.USER_CURRENT);
mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
mTheaterModeEnabled = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 1;
mAlwaysOnEnabled = mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
if (mSupportsDoubleTapWakeConfig) {
boolean doubleTapWakeEnabled = Settings.Secure.getIntForUser(resolver,
Settings.Secure.DOUBLE_TAP_TO_WAKE, DEFAULT_DOUBLE_TAP_TO_WAKE,
UserHandle.USER_CURRENT) != 0;
if (doubleTapWakeEnabled != mDoubleTapWakeEnabled) {
mDoubleTapWakeEnabled = doubleTapWakeEnabled;
mNativeWrapper.nativeSetFeature(
POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0);
}
}
final String retailDemoValue = UserManager.isDeviceInDemoMode(mContext) ? "1" : "0";
if (!retailDemoValue.equals(SystemProperties.get(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED))) {
SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue);
}
mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
mDirty |= DIRTY_SETTINGS;
}