PMS
PowerManagerService是负责管理、协调设备电源管理的系统服务之一,它在Framework层建立起一个策略控制方案,向下决策HAL层以及kernel层来控制设备待机状态、控制显示屏、背光灯、距离或光线传感器等硬件设备的状态。向上提供给应用程序相应的操作接口,如听音乐保持系统唤醒、应用通知唤醒屏幕等场景。
该类继承自SystemService,具有生命周期方法,由SystemServer启动并注册到系统服务中,通过Binder和其他组件进行交互。
生命周期方法: (1)Constructor:通过反射调用,获取实例;(2)onStart()
方法:开启对应的SystemService;(3)onBootPhase()
方法:在SystemService服务启动过程中指定服务的启动阶段,每个阶段的工作。
1、PMS的启动
PMS和SystemService的其他子类一样由SystemServer通过反射的方式启动。首先,在SystemServer的main()
方法中调用自身的run()
方法,并在run()方法中启动三类服务:引导服务、核心服务和其他服务,引导服务就包括了PMS。
1 2 3 4 public static void main (String[] args) { new SystemServer().run(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 private void run () { try { startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } ...... }
在启动引导服务时,PMS随之启动,如下代码:
1 2 3 4 5 6 7 private void startBootstrapServices () { mPowerManagerService = mSystemServiceManager. startService(PowerManagerService.class); mActivityManagerService.initPowerManagement(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public <T extends SystemService> T startService (Class<T> serviceClass) { try { final T service; try { Constructor<T> constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); } catch (InstantiationException ex) { } startService(service); return service; } finally {} } public void startService (@NonNull final SystemService service) { mServices.add(service); try { service.onStart(); } catch (RuntimeException ex) {} }
从startService()
方法可以看到对于PMS,先执行了其构造方法,接着执行了onStart()
方法。构造方法如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public PowerManagerService (Context context) { super (context); mContext = context; mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, false ); mHandlerThread.start(); mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); synchronized (mLock) { mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks" ); mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display" ); mDisplaySuspendBlocker.acquire(); mHoldingDisplaySuspendBlocker = true ; mHalAutoSuspendModeEnabled = false ; mHalInteractiveModeEnabled = true ; mWakefulness = WAKEFULNESS_AWAKE; nativeInit(); nativeSetAutoSuspend(false ); nativeSetInteractive(true ); nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0 ); getPowerHintSceneIdConfig(); } }
构造方法执行完后执行onstart()
方法,代码如下:
1 2 3 4 5 6 7 8 9 10 11 @Override public void onStart () { publishBinderService(Context.POWER_SERVICE, new BinderService()); publishLocalService(PowerManagerInternal.class, new LocalService()); Watchdog.getInstance().addMonitor(this ); Watchdog.getInstance().addThread(mHandler); }
对服务进行远程注册,是通过Binder机制实现的,实际上,从代码中可以出,注册的并不是PMS本身,而是其内部类BinderService,BinderService继承自IPowerManager.Stub,IPowerManager.Stub继承自Binder并且实现了IPowerManager,因此可以知道,BinderService作为Binder的服务端,可以和客户端进行交互;注册的过程在ServiceManager中进行的,代码如下:
1 2 3 4 5 6 7 public static void addService (String name, IBinder service, boolean allowIsolated) { try { getIServiceManager().addService(name, service, allowIsolated); } catch (RemoteException e) { Log.e(TAG, "error in addService" , e); } }
经ServiceManager注册后,就可以根据Context.POWER_SERVICE在其他服务中获取对应的IBinder了,以PMS为例,当从其他应用中获取了PMS服务后,就可以调用PMS.BinderService中的方法。所以,PMS中的BinderService相当于服务端,其中的方法可以供其他应用进行调用,从而完成和PMS的交互。
通过Binder进行注册是为了供其他应用或系统服务和PMS进行交互。同样的,本地注册表示只能在System进程内部调用,和BinderService一样,本地注册也并非注册的是PMS,而是另一个内部类LocalService,LocalService继承自PowerManagerInternal(带有Internal的类一般都在System进程内使用);Binder注册是在SystemManager中进行注册的,本地注册则是在LocalServices中进行注册,其注册方法如下:
1 2 3 4 5 6 7 8 public static <T> void addService (Class<T> type, T service) { synchronized (sLocalServiceObjects) { if (sLocalServiceObjects.containsKey(type)) { throw new IllegalStateException("Overriding service registration" ); } sLocalServiceObjects.put(type, service); } }
本地注册完后,就可以在System进程内,通过PowerManagerInternal.class获取PMS.LocalService对象,从而完成交互了。
在远程注册和本地注册都完成以后,给PMS设置了watchDog监听,onStart()
方法调用完毕。此时,继续回到SytemServer中,startBootstrapServices()
方法中启动PMS部分执行完成了,然后根据SystemService的生命周期,会开始执行onBootPhase()
,这个方法的功能是为所有的已启动的服务指定启动阶段,从而可以在指定的启动阶段来做指定的工作。源代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public void startBootPhase (final int phase) { if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous" ); } mCurrentPhase = phase; try { final int serviceLen = mServices.size(); for (int i = 0 ; i < serviceLen; i++) { final SystemService service = mServices.get(i); try { service.onBootPhase(mCurrentPhase); } catch (Exception ex) { } } } }
在SystemServiceManager的startBootPhase()
中,调用SystemService的onBootPhase(int)
方法,此时每个SystemService都会执行其对应的onBootPhase()方法。通过在SystemServiceManager中传入不同的形参,回调所有SystemService的onBootPhase()方法,并根据形参的不同,在方法实现中完成不同的工作,在SystemService中定义了五个阶段:
SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY
:这是一个依赖项,只在DisplayManagerService中进行了对应处理;
SystemService.PHASE_LOCK_SETTINGS_READY
:经过这个引导阶段后,服务才可以接收到wakelock相关设置数据;
SystemService.PHASE_SYSTEM_SERVICES_READY
:经过这个引导阶段后,服务才可以安全地使用核心系统服务;
SystemService.PHASE_ACTIVITY_MANAGER_READY
:经过这个引导阶段后,服务可以发送广播
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START
:经过这个引导阶段后,服务可以启动第三方应用,第三方应用也可以通过Binder来调用服务。
SystemService.PHASE_BOOT_COMPLETED
:经过这个引导阶段后,说明服务启动完成,这时用户就可以和设备进行交互。
因此,只要在其他模块中调用了SystemServiceManager.startBootPhase()
方法,都会触发各自的onBootPhase()
。PMS的onBootPhase()
方法只对引导阶段的2个阶段做了处理,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Override public void onBootPhase (int phase) { synchronized (mLock) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { incrementBootCount(); } else if (phase == PHASE_BOOT_COMPLETED) { mBootCompleted = true ; PMSFactory.getInstance().createPowerManagerServiceUtils(mContext) .setBootCompleted(true ); mDirty |= DIRTY_BOOT_COMPLETED; userActivityNoUpdateLocked( now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0 , Process.SYSTEM_UID); updatePowerStateLocked(); ...... } } }
onBootPhase()
方法执行完,生命周期方法也执行完毕,引导服务也启动完成。
对于PMS,在SystemServer.startOtherServices()
中还进行了一步操作:
1 mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
即PMS依次执行完构造方法、onStart()
、onBootPhase()
(会调用多次),之后执行systemReady()
方法。
systemReady方法的作用:
1、获取各类本地服务和远程服务,如屏保(DreamManagerService)、窗口(PhoneWindowManager)、电池状态监听服务(BatteryService)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 synchronized (mLock) { mSystemReady = true ; mAppOps = appOps; mDreamManager = getLocalService(DreamManagerInternal.class); mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); mPolicy = getLocalService(WindowManagerPolicy.class); mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting(); mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting(); mScreenBrightnessForVrSettingDefault = pm.getDefaultScreenBrightnessForVrSetting(); SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); mBatteryStats = BatteryStatsService.getService(); mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats, mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts" ), mPolicy); mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, createSuspendBlockerLocked ("PowerManagerService.WirelessChargerDetector" ), mHandler); mSettingsObserver = new SettingsObserver(mHandler); mLightsManager = getLocalService(LightsManager.class); mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); mDisplayManagerInternal.initPowerManagement(mDisplayPowerCallbacks, mHandler, sensorManager);
2、注册用于和其他System交互的广播。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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);
3、调用updateSettingsLocked()
方法更新Setting中值的变化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 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; nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0 ); } } final String retailDemoValue = UserManager.isDeviceInDemoMode(mContext) ? "1" : "0" ; ...... mScreenBrightnessSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault, UserHandle.USER_CURRENT); final float oldScreenAutoBrightnessAdjustmentSetting = mScreenAutoBrightnessAdjustmentSetting; mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver, Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f , UserHandle.USER_CURRENT); if (oldScreenBrightnessSetting != getCurrentBrightnessSettingLocked()) { mTemporaryScreenBrightnessSettingOverride = -1 ; } if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) { mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN; } mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT); final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver, Settings.Global.LOW_POWER_MODE, 0 ) != 0 ; if (lowPowerModeEnabled != mLowPowerModeSetting || autoLowPowerModeConfigured != mAutoLowPowerModeConfigured) { mLowPowerModeSetting = lowPowerModeEnabled; mAutoLowPowerModeConfigured = autoLowPowerModeConfigured; updateLowPowerModeLocked(); } mDirty |= DIRTY_SETTINGS; }
4、调用readConfigurationLocked()
方法读取配置文件中的默认值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 private void readConfigurationLocked () { final Resources resources = mContext.getResources(); mDecoupleHalAutoSuspendModeFromDisplayConfig = resources.getBoolean( com.android.internal.R.bool. config_powerDecoupleAutoSuspendModeFromDisplay); mDecoupleHalInteractiveModeFromDisplayConfig = resources.getBoolean( com.android.internal.R.bool .config_powerDecoupleInteractiveModeFromDisplay); mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean( com.android.internal.R.bool.config_unplugTurnsOnScreen); mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean( com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug); 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); mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger( com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff); mDozeAfterScreenOffConfig = resources.getBoolean( com.android.internal.R.bool.config_dozeAfterScreenOff); mMinimumScreenOffTimeoutConfig = resources.getInteger( com.android.internal.R.integer.config_minimumScreenOffTimeout); 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); }
5、注册SettingsObserver监听
1 2 3 4 5 6 7 8 9 10 11 12 13 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), .......
至此,PMS启动过程分析完毕,相关时序图如下所示:
1.1、核心方法
updatePowerStateLocked()
updatePowerStateLocked()
方法是PMS中的核心方法,用以更新电源状态的改变,并进行重新计算。PMS中使用一个int值mDirty作为标志位判断电源状态是否发生改变,当发生亮灭屏、电池状态改变、暗屏、WakeLock锁申请/释放等都会调用该方法,在该方法中调用其他同级方法进行更新。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 private void updatePowerStateLocked () { if (!mSystemReady || mDirty == 0 ) { return ; } try { updateIsPoweredLocked(mDirty); updateStayOnLocked(mDirty); updateScreenBrightnessBoostLocked(mDirty); final long now = SystemClock.uptimeMillis(); int dirtyPhase2 = 0 ; for (;;) { int dirtyPhase1 = mDirty; dirtyPhase2 |= dirtyPhase1; mDirty = 0 ; updateWakeLockSummaryLocked(dirtyPhase1); updateUserActivitySummaryLocked(now, dirtyPhase1); if (!updateWakefulnessLocked(dirtyPhase1)) { break ; } } boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2); updateDreamLocked(dirtyPhase2, displayBecameReady); finishWakefulnessChangeIfNeededLocked(); updateSuspendBlockerLocked(); }finally { Trace.tranceEnd(Trace.TRACE_TAG_POWER); } }
下面对上述相关方法进行具体叙述:
updateIsPoweredLocked()
功能:(1)USB插拔亮屏入口点;(2)更新低电量模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 private void updateIsPoweredLocked (int dirty) {if ((dirty & DIRTY_BATTERY_STATE) != 0 ) {final boolean wasPowered = mIsPowered;final int oldPlugType = mPlugType;final boolean oldLevelLow = mBatteryLevelLow; mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager. BATTERY_PLUGGED_ANY); mPlugType = mBatteryManagerInternal.getPlugType(); mBatteryLevel = mBatteryManagerInternal.getBatteryLevel(); mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow(); if (wasPowered != mIsPowered || oldPlugType != mPlugType) { mDirty |= DIRTY_IS_POWERED; final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update( mIsPowered, mPlugType, mBatteryLevel); final long now = SystemClock.uptimeMillis(); if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType, dockedOnWirelessCharger)) { wakeUpNoUpdateLocked(now, "android.server.power:POWER" , Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID); } userActivityNoUpdateLocked( now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0 , Process.SYSTEM_UID); if (dockedOnWirelessCharger) { mNotifier.onWirelessChargingStarted(); } } if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) { if (oldLevelLow != mBatteryLevelLow && !mBatteryLevelLow) { mAutoLowPowerModeSnoozing = false ; } updateLowPowerModeLocked(); } } }
从上述代码中可知在满足mDirty&DIRTY_BATTERY_STATE != 0时才会执行该方法,满足此条件的情况有两处:
在调用systemReady()
方法中。
1 2 3 4 5 6 public void systemReady (IAppOpsService appOps) { .... mDirty |= DIRTY_BATTERY_STATE; updatePowerStateLocked(); .... }
在监听电量状态改变的广播中。
1 2 3 4 5 6 7 8 9 10 private final class BatteryReceiver extends BroadcastReceiver { @Override public void onReceive (Context context, Intent intent) { synchronized (mLock) { handleBatteryStateChangedLocked(); } } }
总结来说,该方法在电池状态发生变化时将被调用执行。
updateStayOnLocked()
该方法主要用于判断系统是否在Settings中设置了充电时保持屏幕亮屏后,根据是否充电来决定亮屏与否。方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private void updateStayOnLocked (int dirty) { if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0 ) { final boolean wasStayOn = mStayOn; if (mStayOnWhilePluggedInSetting != 0 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) { mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting); } else { mStayOn = false ; } if (mStayOn != wasStayOn) { mDirty |= DIRTY_STAY_ON; } } }
updateScreenBrightnessBoostLocked()
该方法在PhoneWindowManager中触发,和亮度增强有关。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private void updateScreenBrightnessBoostLocked (int dirty) { if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0 ) { if (mScreenBrightnessBoostInProgress) { final long now = SystemClock.uptimeMillis(); mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT); if (mLastScreenBrightnessBoostTime > mLastSleepTime) { final long boostTimeout = mLastScreenBrightnessBoostTime + SCREEN_BRIGHTNESS_BOOST_TIMEOUT; if (boostTimeout > now) { Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT); msg.setAsynchronous(true ); mHandler.sendMessageAtTime(msg, boostTimeout); return ; } } mScreenBrightnessBoostInProgress = false ; mNotifier.onScreenBrightnessBoostChanged(); userActivityNoUpdateLocked(now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0 , Process.SYSTEM_UID); } } }
updateWakeLockSummaryLocked()
该方法会对所有的WakeLock锁进行统计,过滤所有的wakelock锁状态,并更新mWakeLockSummary的值以汇总所有活动的唤醒锁的状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 private void updateWakeLockSummaryLocked (int dirty) { if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0 ) { mWakeLockSummary = 0 ; final int numWakeLocks = mWakeLocks.size(); for (int i = 0 ; i < numWakeLocks; i++) { final WakeLock wakeLock = mWakeLocks.get(i); switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) { case PowerManager.PARTIAL_WAKE_LOCK: if (!wakeLock.mDisabled) { mWakeLockSummary |= WAKE_LOCK_CPU; } break ; case PowerManager.FULL_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT; break ; case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT; break ; case PowerManager.SCREEN_DIM_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_SCREEN_DIM; break ; case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF; break ; case PowerManager.DOZE_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_DOZE; break ; case PowerManager.DRAW_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_DRAW; break ; } } if (mWakefulness != WAKEFULNESS_DOZING) { mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW); } if (mWakefulness == WAKEFULNESS_ASLEEP || (mWakeLockSummary & WAKE_LOCK_DOZE) != 0 ) { mWakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM| WAKE_LOCK_BUTTON_BRIGHT); if (mWakefulness == WAKEFULNESS_ASLEEP) { mWakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF; } } if ((mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0 ) { if (mWakefulness == WAKEFULNESS_AWAKE) { mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE; } else if (mWakefulness == WAKEFULNESS_DREAMING) { mWakeLockSummary |= WAKE_LOCK_CPU; } } if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0 ) { mWakeLockSummary |= WAKE_LOCK_CPU; } } }
updateUserActivitySummaryLocked()
该方法用来更新用户活动时间,当设备和用户有交互时,会根据当前时间和休眠时长、Dim时长、所处状态来计算下次休眠的时间,从而完成用户活动超时时的操作。关键代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 private void updateUserActivitySummaryLocked (long now, int dirty) { if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0 ) { mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT); long nextTimeout = 0 ; if (mWakefulness == WAKEFULNESS_AWAKE || mWakefulness == WAKEFULNESS_DREAMING || mWakefulness == WAKEFULNESS_DOZING) { final int sleepTimeout = getSleepTimeoutLocked(); final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout); final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager; mUserActivitySummary = 0 ; if (mLastUserActivityTime >= mLastWakeTime) { nextTimeout = mLastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < nextTimeout) { mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else { nextTimeout = mLastUserActivityTime + screenOffTimeout; if (now < nextTimeout) { mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; } } ..... if (mUserActivitySummary != 0 && nextTimeout >= 0 ) { Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT); msg.setAsynchronous(true ); mHandler.sendMessageAtTime(msg, nextTimeout); } } else { mUserActivitySummary = 0 ; } } }
updateWakefulnessLocked()
在updatePowerStateLocked()方法中,设置了一个死循环,并且上述分析的两个方法都在死循环中执行。
1 2 3 4 5 6 7 8 9 10 for (;;) { int dirtyPhase1 = mDirty; dirtyPhase2 |= dirtyPhase1; mDirty = 0 ; updateWakeLockSummaryLocked(dirtyPhase1); updateUserActivitySummaryLocked(now, dirtyPhase1); if (!updateWakefulnessLocked(dirtyPhase1)) { break ; } }
而updateWakefulnessLocked()
方法是退出循环的关键,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 private boolean updateWakefulnessLocked (int dirty) { boolean changed = false ; if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE | DIRTY_DOCK_STATE)) != 0 ) { if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) { Slog.d(TAG, "updateWakefulnessLocked: Bed time..." ); final long time = SystemClock.uptimeMillis(); if (shouldNapAtBedTimeLocked()) { changed = napNoUpdateLocked(time, Process.SYSTEM_UID); } else { changed = goToSleepNoUpdateLocked(time, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0 , Process.SYSTEM_UID); } } } return changed; }
该方法用于更新设备的wakefulness,同时,这个方法是亮屏到屏保/睡眠的决策点。wakefulness
是用来表示当前设备状态的一个值,系统定义的wakefulness值共有四种,分别表示不同的状态:
1 2 3 4 5 6 7 8 public static final int WAKEFULNESS_ASLEEP = 0 ;public static final int WAKEFULNESS_AWAKE = 1 ;public static final int WAKEFULNESS_DREAMING = 2 ;public static final int WAKEFULNESS_DOZING = 3 ;
isItBedTimeYetLocked()
方法,该方法判断当前设备是否将要进入睡眠状态,返回值为对isBeKeptAwakeLocke()
方法返回值取反,由mStayOn(是否屏幕常亮)、wakelockSummary、userActivitySummary、mProximityPositive
等决定,只要满足其中之一为ture,则说明无法进入睡眠,也就说,要满足进入睡眠,相关属性值都为false。isBeKeptAwakeLocke()
如下:
1 2 3 4 5 6 7 8 9 10 private boolean isBeingKeptAwakeLocked () {return mStayOn || mProximityPositive || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0 || mScreenBrightnessBoostInProgress; }
shoudNapAtBedTimeLocked()
方法用来判断设备是否进入屏保模式,相关代码如下:
1 2 3 4 5 6 private boolean shouldNapAtBedTimeLocked () {return mDreamsActivateOnSleepSetting || (mDreamsActivateOnDockSetting && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED); }
综上看来,之所以将updateWakeLockSummaryLocked()
、updateUserActivitySummaryLocked()
、updateWakefulnessLocked()
三个方法放入for(;;)
循环中,是因为它们共同决定了设备的状态,前两个方法是汇总状态,后一个方法是根据前两个方法汇总的值进行判断是否要改变当前的设备唤醒状态。
updateDisplayPowerStateLocked()
该方法用于更新设备显示状态,在这个方法中会计算出最终需要显示的亮度值和其他值,然后将这些值封装到DisplayPowerRequest对象中,向DisplayManagerService请求Display状态,完成屏幕亮度显示。
决定亮度的相关值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private int mScreenBrightnessOverrideFromWindowManager = -1 ;private int mTemporaryScreenBrightnessSettingOverride = -1 ;private int mScreenBrightnessSetting;private int mScreenBrightnessSettingMinimum;private int mScreenBrightnessSettingMaximum;private int mScreenBrightnessSettingDefault;private int mScreenBrightnessForVrSettingDefault;private float mScreenAutoBrightnessAdjustmentSetting;Settings.System.SCREEN_BRIGHTNESS
最终显示的亮度值和所处的状态有关,如在自动亮度调节打开时、VR模式时、或者从一个视频播放窗口中调节亮度时,都对应有不同的值。
在updateDisplayPowerStateLocked()
方法中,用到了一个DisplayPowerRequest
类的对象,这个类是DisplayManageInternal
类中的一个内部类,专门用于PowerManagerService
和DisplayPowerController
交互。PMS中会将当前亮度、屏幕状态等多个值封装在这个对象中,然后调用requestPowerState()
请求DisplayPowerController
,从而完成显示更新。
DisplayPowerRequest
中定义的属性如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public int policy;public boolean useProximitySensor;public int screenBrightness;public float screenAutoBrightnessAdjustment;public boolean brightnessSetByUser;public boolean useAutoBrightness;public boolean lowPowerMode;public float screenLowPowerBrightnessFactor;public boolean boostScreenBrightness;public boolean blockScreenOn;public int dozeScreenBrightness;public int dozeScreenState;
具体来说,updateDisplayPowerStateLocked()
方法会封装应该DisplayPowerRequest对象请求交给DisplayManagerService处理,关键代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private boolean updateDisplayPowerStateLocked (int dirty) { final boolean oldDisplayReady = mDisplayReady; mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); ...... mDisplayPowerRequest.screenBrightness = screenBrightness; ...... mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity); .... return mDisplayReady && !oldDisplayReady; }
getDesiredScreenPolicyLocked()
方法:
在请求 DisplayManagerService 时,会将所有的信息封装到 DisplayPowerRequest 对象中,其中需要注意 policy 值。policy 作为 DisplayPowerRequset 的属性,有四种值,分别为 off、doze、dim、bright、vr。在向 DisplayManagerService 请求时,会根据当前 PowerManagerService 中的唤醒状态和统计的 wakelock 来决定要请求的 Display 状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @VisibleForTesting int getDesiredScreenPolicyLocked () { if (mWakefulness == WAKEFULNESS_ASLEEP || sQuiescent) { return DisplayPowerRequest.POLICY_OFF; } if (mWakefulness == WAKEFULNESS_DOZING) { if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0 ) { return DisplayPowerRequest.POLICY_DOZE; } if (mDozeAfterScreenOffConfig) { return DisplayPowerRequest.POLICY_OFF; } } if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0 || !mBootCompleted || mScreenBrightnessBoostInProgress) { return DisplayPowerRequest.POLICY_BRIGHT; } return DisplayPowerRequest.POLICY_DIM; }
requestPowerState()方法:
1 2 3 4 5 6 7 8 @Override public boolean requestPowerState (DisplayPowerRequest request, boolean waitForNegativeProximity) { return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity); }
DisplayPowerController.requestPowerState()
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public boolean requestPowerState (DisplayPowerRequest request, boolean waitForNegativeProximity) { synchronized (mLock) { boolean changed = false ; if (waitForNegativeProximity && !mPendingWaitForNegativeProximityLocked) { mPendingWaitForNegativeProximityLocked = true ; changed = true ; } if (mPendingRequestLocked == null ) { mPendingRequestLocked = new DisplayPowerRequest(request); changed = true ; } else if (!mPendingRequestLocked.equals(request)) { mPendingRequestLocked.copyFrom(request); changed = true ; } if (changed) { mDisplayReadyLocked = false ; } if (changed && !mPendingRequestChangedLocked) { mPendingRequestChangedLocked = true ; sendUpdatePowerStateLocked(); } return mDisplayReadyLocked; } }
在该方法中,会判断请求时携带的DisplayPowerRequest对象是否和上一次请求的request对象相同,如果相同,则返回值mDisplayReadyLocked为true,如果不同则表示发生了改变,会异步请求新的Display状态,并返回false,表示Display状态正在更新中,直到更新完成mDisplayReadyLocked置为true。之后调用PMS.onStateChange()
方法通知PMS Display状态更新完成。
sendUpdatePowerStateLocked()
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private void sendUpdatePowerStateLocked () { if (!mPendingUpdatePowerStateLocked) { mPendingUpdatePowerStateLocked = true ; Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); mHandler.sendMessage(msg); } } public void handleMessage (Message msg) { switch (msg.what) { case MSG_UPDATE_POWER_STATE: updatePowerState(); break ;
updateDreamLocked()
该方法用来更新Dream(屏保)状态,比如是否继续屏保、Doze或者休眠。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private void updateDreamLocked (int dirty, boolean displayBecameReady) { if ((dirty & (DIRTY_WAKEFULNESS | DIRTY_USER_ACTIVITY | DIRTY_WAKE_LOCKS | DIRTY_BOOT_COMPLETED | DIRTY_SETTINGS | DIRTY_IS_POWERED | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) { if (mDisplayReady) { scheduleSandmanLocked(); } } }
scheduleSandmanLocked()
方法:
1 2 3 4 5 6 7 8 9 private void scheduleSandmanLocked () { if (!mSandmanScheduled) { mSandmanScheduled = true ; Message msg = mHandler.obtainMessage(MSG_SANDMAN); msg.setAsynchronous(true ); mHandler.sendMessage(msg); } }
1 2 3 case MSG_SANDMAN: handleSandman(); break ;
handleSandman()
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 private void handleSandman () { final boolean startDreaming; final int wakefulness; synchronized (mLock) { mSandmanScheduled = false ; wakefulness = mWakefulness; if (mSandmanSummoned && mDisplayReady) { startDreaming = canDreamLocked() || canDozeLocked(); mSandmanSummoned = false ; } else { startDreaming = false ; } } final boolean isDreaming; if (mDreamManager != null ) { if (startDreaming) { mDreamManager.stopDream(false ); mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING); } isDreaming = mDreamManager.isDreaming(); } else { isDreaming = false ; } synchronized (mLock) { if (startDreaming && isDreaming) { mBatteryLevelWhenDreamStarted = mBatteryLevel; if (wakefulness == WAKEFULNESS_DOZING) { Slog.i(TAG, "Dozing..." ); } else { Slog.i(TAG, "Dreaming..." ); } } if (mSandmanSummoned || mWakefulness != wakefulness) { return ; } if (wakefulness == WAKEFULNESS_DREAMING) { if (isDreaming && canDreamLocked()) { if (mDreamsBatteryLevelDrainCutoffConfig >= 0 && mBatteryLevel < mBatteryLevelWhenDreamStarted - mDreamsBatteryLevelDrainCutoffConfig && !isBeingKeptAwakeLocked()) { } else { return ; } } if (isItBedTimeYetLocked()) { goToSleepNoUpdateLocked(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0 , Process.SYSTEM_UID); updatePowerStateLocked(); } else { wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), "android.server.power:DREAM" , Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID); updatePowerStateLocked(); } } else if (wakefulness == WAKEFULNESS_DOZING) { if (isDreaming) { return ; } reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID); updatePowerStateLocked(); } } if (isDreaming) { mDreamManager.stopDream(false ); } }
finishWakefulnessChangeIfNeededLocked()
该方法主要做updateWakefulnessLocked()
方法的结束工作,当屏幕状态改变后,才会执行该方法。
**屏幕状态:**唤醒(awake)、休眠(asleep)、屏保(dream)、打盹(doze)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private void finishWakefulnessChangeIfNeededLocked () { if (mWakefulnessChanging && mDisplayReady) { if (mWakefulness == WAKEFULNESS_DOZING && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0 ) { return ; } if (mWakefulness == WAKEFULNESS_DOZING || mWakefulness == WAKEFULNESS_ASLEEP) { logSleepTimeoutRecapturedLocked(); } if (mWakefulness == WAKEFULNESS_AWAKE) { logScreenOn(); } mWakefulnessChanging = false ; mNotifier.onWakefulnessChangeFinished(); } }
updateSuspendBlockerLocked()
该方法用以更新SuspendBlocker锁的状态。通过Suspend锁向Hal层写入节点,Kernal层读取节点,从而唤醒或休眠CPU。