Android P PowerManagerService分析(一)

1、概述

     PowerManagerService是负责管理、协调设备电源管理的系统服务之一,设备常见功能如亮灭屏、亮度调节、低电量模式、保持CPU唤醒等,都会通过PMS的协调和处理。其继承自SystemService,因此具有SystemService子类的共性:具有生命周期方法,由SystemServer启动、注册到系统服务中,通过Binder和其他组件进行交互等。
其生命周期方法如下:
     构造方法:通过反射调用,获取实例;
     onstart()方法:开启对应的SystemService;
     onBootPhase()方法:在SystemService服务的启动过程中指定服务的启动阶段,每个阶段指定特定的工作;
由于是系统服务,不仅需要掌握其启动流程,还要了解和其他服务之间的交互,下面就PMS的流程和功能进行具体的分析。
在这里插入图片描述

2、PMS的启动

     和SystemService的其他子类一样,PMS由SystemServer通过反射的方式启动,首先,在SystemServer的main()方法中,调用了自身的run()方法,并在run()方法中启动三类服务:引导服务、核心服务和其他服务,引导服务中启动的是一些依赖性比较强的服务,其中就包括了PMS,具体如下:

在SystemServer的main()中:

//The main entry point from zygote.
public static void main(String[] args) {
    new SystemServer().run();
}

在SystemServer的run()中:

private void run() {
    //......
    try {
        startBootstrapServices();//启动引导服务
        startCoreServices();//启动核心服务
        startOtherServices();//启动其他服务
    } catch (Throwable ex) {
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
    ......
}

     所谓引导服务是指一些具有高度相互依赖性的服务,在启动引导服务时,启动了PMS,以下代码是PMS的启动以及和其他服务的依赖关系:

private void startBootstrapServices() {
 	//通过SystemManagerService启动PMS服务
    mPowerManagerService = mSystemServiceManager.
                startService(PowerManagerService.class);
    //AMS中初始化PowerManager
    mActivityManagerService.initPowerManagement();
}

     逐步分析,首先看PMS的启动,调用了SystemServiceManager的startService()方法进行了启动,在startService()中,首先通过了传入的类名获取了Class对象,然后使用反射机制,通过Class对象获取了PMS的构造函数,从而获得了一个PMS对象:

public SystemService startService(String className) {
    final Class serviceClass;
    serviceClass = (Class)Class.forName(className);
    return startService(serviceClass);
}
public  T startService(Class serviceClass) {
    try {
        final T service;
        try {
        	//获取实例
            Constructor constructor = 
                  serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
        }
        mServices.add(service);//添加到List中,进行生命周期管理
        try {
            service.onStart();//启动服务
        } catch (RuntimeException ex) {
        }
        return service;
    }
}

     在获取了PMS的实例后,添加到了一个ArrayList中,只有在该ArrayList中的SystemService才能接收到生命周期方法回调;然后调用了onStart()方法.因此,对于PMS,先执行了PMS的构造方法,接着执行了onStart()方法。首先来看其构造方法:

public PowerManagerService(Context context) {
     super(context);
     mContext = context;
     //获取一个系统级别的HandlerThread,继承于Thread
     mHandlerThread = new ServiceThread(TAG,
             Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
     mHandlerThread.start();//开启线程
     //根据Looper实例化一个Handler
     mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
     mConstants = new Constants(mHandler);
     mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
	//电池监测相关
     mBatterySavingStats = new BatterySavingStats(mLock);
     mBatterySaverPolicy = new BatterySaverPolicy(mLock, mContext, mBatterySavingStats);
     mBatterySaverController = new BatterySaverController(mLock, mContext,
             BackgroundThread.get().getLooper(), mBatterySaverPolicy, mBatterySavingStats);
     mBatterySaverStateMachine = new BatterySaverStateMachine(
             mLock, mContext, mBatterySaverController);

     synchronized (mLock) {
    	 //获取当应用申请wakelock后让CUP保持激活状态的Suspendlocker实例
         mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
         //获取当显示屏开启、显示屏准备就绪或者有用户活动后让CPU保持激活状态的Suspendlocker
         mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
         //申请PowerManagerService.Display类型的suspendBloker锁
         mDisplaySuspendBlocker.acquire();
         //持有Display锁的bool值
         mHoldingDisplaySuspendBlocker = true;
         //AutoSuspend模式是否开启
         mHalAutoSuspendModeEnabled = false;
         //是否处于交互模式
         mHalInteractiveModeEnabled = true;
		//设置wakefulness表示亮屏状态
         mWakefulness = WAKEFULNESS_AWAKE;

         sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");

         nativeInit();//初始化
         nativeSetAutoSuspend(false);//设置是否开启anto suspend模式
         nativeSetInteractive(true);//设置是否处于交互模式
         nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
     }
 }

     在PMS构造方法中,首先获取了一个HandlerThread,然后使用该HandlerThread的Looper实例化PowerManagerHandler,如果不指定looper,则使用当前线程默认Looper,因此PowerManagerHandler会根据HandlerThread中的Looper,在HandlerThread中进行异步的操作;其次获取了两个Suspend锁,SuspendBlocker是一种锁机制,只用于系统内部,上层申请的wakelock锁在PMS中都会反映为SuspendBlocker锁。这里获取的两个Suspend锁在申请wakelock时会用到,这块在wakelock申请时会进行详细分析;最后,调用了本地方法,这几个方法会通过JNI层调用到HAL层。
     构造方法执行完毕后,执行onStart()方法:

@Override
public void onStart() {
    //发布到系统服务中
    publishBinderService(Context.POWER_SERVICE, new BinderService());
    //发布到本地服务
    publishLocalService(PowerManagerInternal.class, new LocalService());
	//设置Watchdog监听
    Watchdog.getInstance().addMonitor(this);
    Watchdog.getInstance().addThread(mHandler);
}

     在该方法中,首先对该服务进行Binder注册和本地注册,当进行Binder注册后,在其他模块中就可以通过Binder机制获取其实例,同理,当进行本地注册后,只有在System进程才能获取到其实例;最后设置Watchdog的监听。
     对服务进行远程注册,是通过Binder机制实现的,实际上,从代码中可以出,注册的并不是PMS本身,而是其内部类——BinderService,BinderService继承自IPowerManager.Stub,IPowerManager.Stub继承自Binder并且实现了IPowerManager,因此可以知道,BinderService作为Binder的服务端,可以和客户端进行交互;注册的过程在ServiceManager中进行的,如下:

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中进行注册,其注册方法如下:

public static  void addService(Class 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(),这个方法的功能是为所有的已启动的服务指定启动阶段,从而可以在指定的启动阶段来做指定的工作。源代码如下:

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个阶段做了处理,具体代码如下:
public void onBootPhase(int phase) {
      synchronized (mLock) {
          if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
          //统计启动的apk个数
              incrementBootCount();

          } else if (phase == PHASE_BOOT_COMPLETED) {
              final long now = SystemClock.uptimeMillis();
              mBootCompleted = true;
              //mDirty置位
              mDirty |= DIRTY_BOOT_COMPLETED;

              mBatterySaverStateMachine.onBootCompleted();
              //更新用户活动时间
              userActivityNoUpdateLocked(
                      now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
              //更新电源状态信息
              updatePowerStateLocked();

              if (!ArrayUtils.isEmpty(mBootCompletedRunnables)) {
                  Slog.d(TAG, "Posting " + mBootCompletedRunnables.length + " delayed runnables");
                  for (Runnable r : mBootCompletedRunnables) {
                      BackgroundThread.getHandler().post(r);
                  }
              }
              mBootCompletedRunnables = null;
          }
      }
  }

     在这个方法中,mDirty是一个二进制的标记位,用来表示电源状态哪一部分发生了改变,通过对其进行置位(|操作)、清零(~操作),得到二进制数各个位的值(0或1),进行不同的处理 ,此外,这个方法中调用到了updatePowerStateLocked()方法,这是整个PMS中最重要的方法,这块会在下文中进行详细分析。此时,SystemServer.startBootstrapServices()执行完毕,生命周期方法也执行完毕。对于PMS,在SystemServer.startOtherServices()中还进行了一步操作:
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
     因此,当PMS依次执行完构造方法、onStart()、onBootPhase()(会调用多次)方法后,执行的下一个方法是systemReady()方法,这个方法中主要有以下5个功能:
1.获取各类本地服务和远程服务,如屏保(DreamMangerService)、窗口(PhoneWindowManager)、电池状态监听服务(BatteryService)等服务,用于进行交互:

synchronized (mLock) {
mSystemReady = true;
mAppOps = appOps;
//和DreamManagerService交互
mDreamManager = getLocalService(DreamManagerInternal.class);
//和DisplayManagerService交互
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
//和WindowManagerService交互
mPolicy = getLocalService(WindowManagerPolicy.class);
//和BatteryService交互
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());
//获取BatteryStatsService
mBatteryStats = BatteryStatsService.getService();
//mNotifier用于PMS和其他系统服务间的交互,以及广播的发送
mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
mAppOps,
createSuspendBlockerLocked(“PowerManagerService.Broadcasts”),
mPolicy);
//无线充电相关
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
createSuspendBlockerLocked
(“PowerManagerService.WirelessChargerDetector”),
mHandler);
//监听Stetings中值的变化
mSettingsObserver = new SettingsObserver(mHandler);
//和LightsManager交互
mLightsManager = getLocalService(LightsManager.class);
mAttentionLight =
mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
//mDisplayPowerCallbacks提供PMS和Display的接口,当
//DisplayPowerController发生改变,通过该接口回调PMS中的实现
//initPowerManagement()方法中实例化了DisplayPowerController,
//DPC是和显示有关,如亮灭屏、背光调节
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
2.注册用于和其他Sytem交互的广播,如:

// Register for broadcasts from other components of the system.
//注册BatteryService中ACTION_BATTERY_CHANGED广播
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
//Dream相关
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);
//Dock相关
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DOCK_EVENT);
mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);

3.调用updateSettingsLocked()方法更新Settings中值的变化:

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);
//设备在一段时间不活动后进入休眠或者屏保状态的时间,15*1000ms
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT,
DEFAULT_SCREEN_OFF_TIMEOUT,
UserHandle.USER_CURRENT);
/设备在一段时间不活动后完全进入休眠状态之前的超时时间,
该值必须大于SCREEN_OFF_TIMEOUT,否则设置了屏保后来不及显示屏保就sleep
/
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);
//自动调节亮度值(>0.0 <1.0)
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;
}
//亮度调节模式,自动1,正常0
mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT);
//低电量模式是否可用,1表示true
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;
}
这里需要注意这两个值:mTemporaryScreenBrightnessSettingOverride和mTemporaryScerrnAutoBrightnessAdjustmentSettingsOverride,这两个值分别表示一个临时亮度值和临时自动亮度调节比例,和亮度的调节有关。之所以是临时亮度值,是因为在自动调节亮度关闭时,从Settings中或者SystemUI中拉进度条时,首先会通过Binder调用setTemporaryScreenBrightnessSettingOverride()方法将亮度值赋给它,如果调节完毕手指抬起,此时Settings.Global等里面亮度值发生变化,则在PMS中会回调SettingsObserver中的onChange()方法,又会回调updateSettingsLocked()方法,又置为-1和NaN,也就是上面这段方法。

4.调用readConfigurationLocked()方法读取配置文件中的默认值:

private 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);
//设备处于剧院模式时,插拔USB是否亮屏
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);
//是否屏保默认打开–false
mDreamsEnabledByDefaultConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsEnabledByDefault);
//充电和睡眠时屏保是否激活
mDreamsActivatedOnSleepByDefaultConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
//Dock时屏保是否激活
mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
//放电时是否允许进入屏保
mDreamsEnabledOnBatteryConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsEnabledOnBattery);
//充电时允许屏保的最低电量,使用-1禁用此功能
mDreamsBatteryLevelMinimumWhenPoweredConfig = resources.getInteger(
com.android.internal.R.integer.
config_dreamsBatteryLevelMinimumWhenPowered);
//放电时允许屏保的最低电量,使用-1禁用此功能,默认15
mDreamsBatteryLevelMinimumWhenNotPoweredConfig = resources.getInteger(
com.android.internal.R.integer.
config_dreamsBatteryLevelMinimumWhenNotPowered);
//电亮下降到该百分点,当用户活动超时后不进入屏保,默认5
mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
//如果为true,则直到关闭屏幕并执行屏幕关闭动画之后,才开始Doze,默认false
mDozeAfterScreenOffConfig = resources.getBoolean(
com.android.internal.R.bool.config_dozeAfterScreenOff);
//用户活动超时的最小时间,默认10000ms,必须大于0
mMinimumScreenOffTimeoutConfig = resources.getInteger(
com.android.internal.R.integer.config_minimumScreenOffTimeout);
//用户活动超时进入且关闭屏幕前屏幕变暗的最大时间,默认7000ms,必须大于0
mMaximumScreenDimDurationConfig = resources.getInteger(
com.android.internal.R.integer.config_maximumScreenDimDuration);
//屏幕变暗的时长比例,如果用于超时时间过短,则在7000ms的基础上按还比例减少,默认20%
mMaximumScreenDimRatioConfig = resources.getFraction(
com.android.internal.R.fraction.config_maximumScreenDimRatio, 1, 1);
//是否支持双击唤醒屏幕
mSupportsDoubleTapWakeConfig = resources.getBoolean(
com.android.internal.R.bool.config_supportDoubleTapWake);
}
5.注册SettingsObserver监听:

// 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),

至此,systemReady()方法中分析完毕。执行完这个方法后,PMS的启动过程分析完毕。在下文中进行核心方法的分析。

你可能感兴趣的:(Android,PMS,电源管理服务,AndroidP)