(图片来源网络,侵删)
阅读5分钟,每日十点、和您一起终身学习,这里是程序员Android概述PowerManagerService 是负责管理、协调设备电源管理的系统服务之一,设备常见功能如亮灭屏、亮度调节、低电量模式、保持CPU唤醒等,都会通过PMS的协调和处理。其继承自SystemService,因此具有SystemService子类的共性:具有生命周期方法,由SystemServer启动、注册到系统服务中,通过Binder和其他组件进行交互等。其生命周期方法如下:构造方法:通过反射调用,获取实例;onstart()方法:开启对应的SystemService;onBootPhase()方法:在SystemService服务的启动过程中指定服务的启动阶段,每个阶段指定特定的工作;由于是系统服务,不仅需要掌握其启动流程,还要了解和其他服务之间的交互,下面就PMS的流程和功能进行具体的分析。PMS类图如下,其中红色部分表示在本篇文章中分析到的类:PMS类图1.1.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<SystemService> serviceClass; serviceClass = (Class<SystemService>)Class.forName(className); return startService(serviceClass);}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) { } 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 ); mHandlerThread.start();//开启线程 //根据Looper实例化一个Handler mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); 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; //本地方法 nativeInit();//初始化 nativeSetAutoSuspend(false);//设置是否开启anto suspend模式 nativeSetInteractive(true);//设置是否处于交互模式 nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0); getPowerHintSceneIdConfig(); }}在PMS构造方法中,首先获取了一个HandlerThread,然后使用该HandlerThread的Looper实例化PowerManagerHandler,如果不指定looper,则使用当前线程默认Looper,因此PowerManagerHandler会根据HandlerThread中的Looper,在HandlerThread中进行异步的操作;其次获取了两个Suspend锁,SuspendBlocker是一种锁机制,只用于系统内部,上层申请的wakelock锁在PMS中都会反映为SuspendBlocker锁。这里获取的两个Suspend锁在申请wakelock时会用到,这块在wakelock申请时会进行详细分析;最后,调用了本地方法,这几个方法会通过JNI层调用到HAL层。构造方法执行完毕后,执行onStart()方法:@Overridepublic 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 <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(),这个方法的功能是为所有的已启动的服务指定启动阶段,从而可以在指定的启动阶段来做指定的工作。源代码如下: Starts the specified boot phase for all system services that have been started up to this point. @param phase The boot phase to start.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中定义了六个阶段:1.SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY这是一个依赖 项,只有DisplayManagerService中进行了对应处理;SystemService.PHASE_LOCK_SETTINGS_READY:经过这个引导阶段后,服务才可以接收到wakelock相关设置数据;3.SystemService.PHASE_SYSTEM_SERVICES_READY经过这个引导阶段 后,服务才可以安全地使用核心系统服务4.SystemService.PHASE_ACTIVITY_MANAGER_READY:经过这个引导阶 段后,服务可以发送广播5.SystemService.PHASE_THIRD_PARTY_APPS_CAN_START:经过这个引 导阶段后,服务可以启动第三方应用,第三方应用也可以通过Binder来调 用服务。6.SystemService.PHASE_BOOT_COMPLETED:经过这个引导阶段后,说明服务启动完成,这时用户就可以和设备进行交互。因此,只要在其他模块中调用了SystemServiceManager.startBootPhase(),都会触发各自的onBootPhase()。PMS的onBootPhase()方法只对引导阶段的2个阶段做了处理,具体代码如下:@Overridepublic void onBootPhase(int phase) { synchronized (mLock) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { //统计启动的apk个数 incrementBootCount(); } else if (phase == PHASE_BOOT_COMPLETED) { mBootCompleted = true; PMSFactory.getInstance().createPowerManagerServiceUtils(mContext) .setBootCompleted(true); //mDirty置位 mDirty |= DIRTY_BOOT_COMPLETED; //更新用户活动时间 userActivityNoUpdateLocked( now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); //更新电源状态信息 updatePowerStateLocked(); ...... } }}在这个方法中,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.注册用于和其他System交互的广播,如: // 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); //设备在一段时间不活动后进入休眠或者屏保状态的时间,151000ms 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的启动过程分析完毕。在下文中进行核心方法的分析。
0 评论