PowerManagerService的启动流程

PowerManagerServcie是Android系统电源管理的核心服务,它在Framework层建立起一个策略控制方案,向下决策HAL层以及kernel层来控制设备待机状态,控制显示屏,背光灯,距离传感器,光线传感器等硬件设备的状态。向上提供给应用程序相应的操作接口,比如听音乐时持续保持系统唤醒,应用通知来临唤醒手机屏幕等场景等,PMS也是系统的核心服务,启动流程的时序图如下:

启动流程时序图

AAA

 

 

根据PowerManagerService的启动流程时序图,可以简单的将启动过程分为图中的几个步骤。

根据代码来详细分析

  PowerManagerService是系统的核心服务,在SystemServer中启动。SystemServer在系统启动的时候会启动三种服务,引导关键服务,核心服务和其他服务。

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. startBootstrapServices(); //启动引导服务  
  2. startCoreServices();//启动核心服务  
  3.  startOtherServices();//其他服务  

 

 

在启动引导关键服务的方法中,创建PowerManagerService对象,并将它启动了起来

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);  

接着我们看下startService相关的代码实现。

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public <T extends SystemService> T startService(Class<T> serviceClass) {  
  2.         ……  
  3.         final T service;  
  4.         try {  
  5.             Constructor<T> constructor = serviceClass.getConstructor(Context.class);  
  6.             service = constructor.newInstance(mContext);  
  7.             //构造PowerManangerService对象  
  8.         } catch (InstantiationException ex) {  
  9.             ……  
  10.         }  
  11.         // Register it.  
  12.         mServices.add(service); //将PowerManangerService添加到LocalService中  
  13.         // Start it.  
  14.         try {  
  15.             service.onStart(); //调用PowerManagerService的onStart方法  
  16.         } catch (RuntimeException ex) {  
  17.            ……  
  18.         }  
  19.         return service;  
  20.     }  

 

在startService方法中,利用反射方法构造PowerManagerService的对象,将它添加到本地service变量中,然后调用了PowerManagerService的onStart方法。

那么我们首先来分析PowerManagerService的构造方法,然后在分析PowerManagerService的onStart方法。

 

PowerManagerService的构造方法分析

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public PowerManagerService(Context context) {  
  2.         super(context);  
  3.         mContext = context;  
  4.         mHandlerThread = new ServiceThread(TAG,  
  5.                 Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);  
  6.         mHandlerThread.start();  
  7.         //创建一个HandlerThread,并启动  
  8.         mHandler = new PowerManagerHandler(mHandlerThread.getLooper());  
  9.         //基于这个HandlerThread创建一个相关的Handler对象,用于向handlerThread中发送消息  
  10.         synchronized (mLock) {  
  11.             mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");  
  12.             //该WakeLock用于控制CPU  
  13.             mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");  
  14.             //该wakeLock用于控制屏幕  
  15.             mDisplaySuspendBlocker.acquire();  
  16.             mHoldingDisplaySuspendBlocker = true;  
  17.             mHalAutoSuspendModeEnabled = false;  
  18.             mHalInteractiveModeEnabled = true;  
  19.   
  20.             mWakefulness = WAKEFULNESS_AWAKE;  
  21.             //初始化wakefulness的状态  
  22.             nativeInit();  
  23.             //调用native层初始化  
  24.             nativeSetAutoSuspend(false);  
  25.             nativeSetInteractive(true);  
  26.             nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);  
  27.         }  
  28.     }  

 

 

第一步:

在PowerManagerService的构造方法中,首先创建了一个消息发送和处理的Handler和两种WakeLock锁

1. PowerManagerService.WakeLocks,主要用于控制CPU的唤醒

2. PowerManagerService.Display 主要用于控制屏幕的点亮和熄灭

关于createSuspendBlockerLocked方法的实现

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. private SuspendBlocker createSuspendBlockerLocked(String name) {  
  2.     SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);  
  3.     mSuspendBlockers.add(suspendBlocker);  
  4.     return suspendBlocker;  
  5. }  

在该方法中创建了一个SuspendBlockerImpl对象,下面我们再来看下的acquire()方法如何实现

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public void acquire() {    
  2.         synchronized (this) {    
  3.             mReferenceCount += 1;    
  4.             if (mReferenceCount == 1) {    
  5.                 nativeAcquireSuspendBlocker(mName);    
  6.             }    
  7.         }    
  8.     }   

计数加1,然后nativeAcquireSuspendBlocker(mName)方法通过JNI调用native层的nativeAcquireSuspendBlocker方法。

[C++] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {    
  2.     ScopedUtfChars name(env, nameStr);    
  3.     acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());    
  4. }    

acquire_wake_lock()调用的是power.c文件中的acquire_wake_lock()方法。在该方法中通过往/sys/power/wake_lock,/sys/power/wake_unlock等文件中写入数据来进行底层持锁

第二步:

将mWakefulness变量初始化为WAKEFULNESS_AWAKE状态,mWakefulness 标识系统当前状态共有四种定义:

WAKEFULNESS_ASLEEP:表示系统当前处于休眠状态,只能被wakeUp()调用唤醒。
WAKEFULNESS_AWAKE:表示系统目前处于正常运行状态。

WAKEFULNESS_DREAMING:表示系统当前正处于互动屏保的状态。

WAKEFULNESS_DOZING:表示系统正处于“doze”状态

第三步:

然后调用nativieInit()方法,通过JNI方法在native层初始化相关资源。

[C++] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. static void nativeInit(JNIEnv* env, jobject obj) {  
  2.     gPowerManagerServiceObj = env->NewGlobalRef(obj);  
  3.   
  4.     status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,  
  5.             (hw_module_t const**)&gPowerModule);  
  6.     if (!err) {  
  7.         gPowerModule->init(gPowerModule);  
  8.     } else {  
  9.         ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));  
  10.     }  
  11. }  

 

在nativeInit()方法中,创建了一个对应的Native层PowerManagerService,然后调用了gPowerModule的init函数。以下是power_module的结构类型

[C++] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. struct power_module HAL_MODULE_INFO_SYM = {  
  2.     .common = {  
  3.         .tag = HARDWARE_MODULE_TAG,  
  4.         .module_api_version = POWER_MODULE_API_VERSION_0_2,  
  5.         .hal_api_version = HARDWARE_HAL_API_VERSION,  
  6.         .id = POWER_HARDWARE_MODULE_ID,  
  7.         .name = "Default Power HAL",  
  8.         .author = "The Android Open Source Project",  
  9.         .methods = &power_module_methods,  
  10.     },  
  11.   
  12.     .init = power_init,  
  13.     .setInteractive = power_set_interactive,  
  14.     .powerHint = power_hint,  
  15. };  

 

Power_module的初始化代码,gPowerModule->init方法对应的是power_init 这个应该是由硬件厂商来实现的,不同的硬件初始化方式也不一样,我们看先htc相关的实现方式. Power_init实际就是在cpu的节点中写入了一些初始化的值。

[C++] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. static void power_init(struct power_module __unused *module)  
  2. {  
  3.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/timer_rate",  
  4.                 "20000");  
  5.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/timer_slack",  
  6.                 "20000");  
  7.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/min_sample_time",  
  8.                 "80000");  
  9.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/hispeed_freq",  
  10.                 "1530000");  
  11.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load",  
  12.                 "99");  
  13.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/target_loads",  
  14.                 "65 228000:75 624000:85");  
  15.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay",  
  16.                 "20000");  
  17.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/boostpulse_duration",  
  18.                 "1000000");  
  19.     sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/io_is_busy", "0");  
  20.   
  21.     calculate_max_cpu_freq();  
  22. }  

 

onStart函数分析:

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public void onStart() {  
  2.         publishBinderService(Context.POWER_SERVICE, new BinderService());  
  3.         publishLocalService(PowerManagerInternal.class, new LocalService());  
  4.     }  

 

onStart方法实现比较简单,就是将PowerManagerService对象注册到ServiceManager中和LocalService中。

SystemReady函数分析:

根据分析,当System系统准备完成后,SystemServer会回调systemReady函数。先看PMS的systemReady函数具体干了些什么。

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public void systemReady(IAppOpsService appOps) {  
  2.         synchronized (mLock) {  
  3.             //第一步:初始化相关的变量  
  4.             mSystemReady = true;  
  5.             mAppOps = appOps;  
  6.             mDreamManager = getLocalService(DreamManagerInternal.class);  
  7. //初始化互动屏保管理  
  8.             mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);  
  9. //初始化屏幕显示管理服务  
  10.             mPolicy = getLocalService(WindowManagerPolicy.class);  
  11.             mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);  
  12. //初始化电池管理服务  
  13.   
  14.             PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);  
  15.             mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();  
  16.             mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();  
  17.             mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();  
  18. //获取屏幕的亮度值,最大亮度,最小亮度,默认亮度  
  19.             SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());  
  20. //获取传感器管理服务  
  21.             mBatteryStats = BatteryStatsService.getService();  
  22. //初始化电量统计服务  
  23.             mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,  
  24.                     mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),  
  25.                     mPolicy);  
  26.   
  27.             mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,  
  28.                     createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),  
  29.                     mHandler);  
  30.             mSettingsObserver = new SettingsObserver(mHandler);  
  31. //settings的监听器  
  32.             mLightsManager = getLocalService(LightsManager.class);  
  33. //LED指示灯管理服务  
  34.             mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);  
  35.   
  36.             // 初始化屏幕显示服务  
  37.             mDisplayManagerInternal.initPowerManagement(  
  38.                     mDisplayPowerCallbacks, mHandler, sensorManager);  
  39.             //第二步:注册相关的BroadCastReceiver  
  40.             IntentFilter filter = new IntentFilter();  
  41.             filter.addAction(Intent.ACTION_BATTERY_CHANGED);  
  42.             filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);  
  43.             mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);  
  44.             //注册电池变化的接收器  
  45.             filter = new IntentFilter();  
  46.             filter.addAction(Intent.ACTION_DREAMING_STARTED);  
  47.             filter.addAction(Intent.ACTION_DREAMING_STOPPED);  
  48.             mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);  
  49.             //注册屏保开始和结束的接收器  
  50.             filter = new IntentFilter();  
  51.             filter.addAction(Intent.ACTION_USER_SWITCHED);  
  52.             mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);  
  53.             //注册切换用户的接收器  
  54.             filter = new IntentFilter();  
  55.             filter.addAction(Intent.ACTION_DOCK_EVENT);  
  56.             mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);  
  57.               
  58.             //第三步.注册设置变化的监听器  
  59.             final ContentResolver resolver = mContext.getContentResolver();  
  60.             resolver.registerContentObserver(Settings.Secure.getUriFor(  
  61.                     Settings.Secure.SCREENSAVER_ENABLED),  
  62.                     false, mSettingsObserver, UserHandle.USER_ALL);  
  63.               
  64.             ……  
  65.             resolver.registerContentObserver(Settings.Secure.getUriFor(  
  66.                     Settings.Secure.DOUBLE_TAP_TO_WAKE),  
  67.                     false, mSettingsObserver, UserHandle.USER_ALL);  
  68.             //双击唤醒屏幕  
  69.             // 第四步: 从文件读取默认的配置信息  
  70.             readConfigurationLocked();  
  71.             //读取设置信息,并更新相关的变量  
  72.             updateSettingsLocked();  
  73.             // 第五步  
  74.             mDirty |= DIRTY_BATTERY_STATE;  
  75.             //更新电源的相关信息  
  76.             updatePowerStateLocked();  
  77.         }  
  78.     }  

systemReady方法代码虽然很长,但是逻辑大致可以分为五个步骤

第一步:初始化相关的变量和服务

初始化了DreamManager,DisplayManager,PowerManager,BatteryStats,LightManager等相关的变量,初始化了屏幕亮度最大、最小和默认三个数值。

第二步:注册相关的广播接收器

注册了电量变化、用户切换和Dream等相关的广播接收器

当电量发生变化,调用handleBatteryStateChangedLocked方法处理电源变化的逻辑。

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. private void handleBatteryStateChangedLocked() {  
  2.         mDirty |= DIRTY_BATTERY_STATE;  
  3.         updatePowerStateLocked();  
  4.     }  

 

最终调用updatePowerStateLocked更新电源状态,该方法稍后分析

第三步:注册相关设置的变化监听

监听设置中相关信息的变化,例如灭屏时间,屏幕亮度,低电量的值,双击唤醒等

当settings中的关于电量的设置发生变化的时候,settingsObserver接收到变化监听,调用handleSettingsChangedLocked方法来处理settings变化的逻辑。

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. private void handleSettingsChangedLocked() {  
  2.         updateSettingsLocked();  
  3.         updatePowerStateLocked();  
  4.     }  

 

调用updateSettingsLocked方法,从新读取设置信息,更新设置信息,调用updatePowerStateLocked更新电源状态信息。

第四步:配置文件中读取相关的配置信息,更新setting中设置的信息

 调用readConfigurationLocked方法,从xml文件中读取预置的配置信息,并赋值给相应的变量。

调用updateSettingLocked方法,根据预置的变量信息和Settings中配置的信息来初始化Setting的相关变量。

第五步:更新电源的状态信息

调用updatePowerStateLocked来更新电源状态信息。该方法是PowerManagerService的核心方法,后面会详细分析。

总结:PowerManagerService启动流程图如下。


BBB

到此PowerManagerService的启动流程就分析完成了。下面分析PMS的核心方法updatePowerStateLocked()方法。

posted on 2016-10-26 14:25  jamboo  阅读(627)  评论(0编辑  收藏  举报

导航