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; }