PowerManagerService的启动流程
PowerManagerServcie是Android系统电源管理的核心服务,它在Framework层建立起一个策略控制方案,向下决策HAL层以及kernel层来控制设备待机状态,控制显示屏,背光灯,距离传感器,光线传感器等硬件设备的状态。向上提供给应用程序相应的操作接口,比如听音乐时持续保持系统唤醒,应用通知来临唤醒手机屏幕等场景等,PMS也是系统的核心服务,启动流程的时序图如下:
启动流程时序图
根据PowerManagerService的启动流程时序图,可以简单的将启动过程分为图中的几个步骤。
根据代码来详细分析
PowerManagerService是系统的核心服务,在SystemServer中启动。SystemServer在系统启动的时候会启动三种服务,引导关键服务,核心服务和其他服务。
- startBootstrapServices(); //启动引导服务
- startCoreServices();//启动核心服务
- startOtherServices();//其他服务
在启动引导关键服务的方法中,创建PowerManagerService对象,并将它启动了起来
- mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
接着我们看下startService相关的代码实现。
- public <T extends SystemService> T startService(Class<T> serviceClass) {
- ……
- final T service;
- try {
- Constructor<T> constructor = serviceClass.getConstructor(Context.class);
- service = constructor.newInstance(mContext);
- //构造PowerManangerService对象
- } catch (InstantiationException ex) {
- ……
- }
- // Register it.
- mServices.add(service); //将PowerManangerService添加到LocalService中
- // Start it.
- try {
- service.onStart(); //调用PowerManagerService的onStart方法
- } catch (RuntimeException ex) {
- ……
- }
- return service;
- }
在startService方法中,利用反射方法构造PowerManagerService的对象,将它添加到本地service变量中,然后调用了PowerManagerService的onStart方法。
那么我们首先来分析PowerManagerService的构造方法,然后在分析PowerManagerService的onStart方法。
PowerManagerService的构造方法分析
- public PowerManagerService(Context context) {
- super(context);
- mContext = context;
- mHandlerThread = new ServiceThread(TAG,
- Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
- mHandlerThread.start();
- //创建一个HandlerThread,并启动
- mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
- //基于这个HandlerThread创建一个相关的Handler对象,用于向handlerThread中发送消息
- synchronized (mLock) {
- mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
- //该WakeLock用于控制CPU
- mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
- //该wakeLock用于控制屏幕
- mDisplaySuspendBlocker.acquire();
- mHoldingDisplaySuspendBlocker = true;
- mHalAutoSuspendModeEnabled = false;
- mHalInteractiveModeEnabled = true;
- mWakefulness = WAKEFULNESS_AWAKE;
- //初始化wakefulness的状态
- nativeInit();
- //调用native层初始化
- nativeSetAutoSuspend(false);
- nativeSetInteractive(true);
- nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
- }
- }
第一步:
在PowerManagerService的构造方法中,首先创建了一个消息发送和处理的Handler和两种WakeLock锁
1. PowerManagerService.WakeLocks,主要用于控制CPU的唤醒
2. PowerManagerService.Display 主要用于控制屏幕的点亮和熄灭
关于createSuspendBlockerLocked方法的实现
- private SuspendBlocker createSuspendBlockerLocked(String name) {
- SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
- mSuspendBlockers.add(suspendBlocker);
- return suspendBlocker;
- }
在该方法中创建了一个SuspendBlockerImpl对象,下面我们再来看下的acquire()方法如何实现
- public void acquire() {
- synchronized (this) {
- mReferenceCount += 1;
- if (mReferenceCount == 1) {
- nativeAcquireSuspendBlocker(mName);
- }
- }
- }
计数加1,然后nativeAcquireSuspendBlocker(mName)方法通过JNI调用native层的nativeAcquireSuspendBlocker方法。
- static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
- ScopedUtfChars name(env, nameStr);
- acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
- }
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层初始化相关资源。
- static void nativeInit(JNIEnv* env, jobject obj) {
- gPowerManagerServiceObj = env->NewGlobalRef(obj);
- status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
- (hw_module_t const**)&gPowerModule);
- if (!err) {
- gPowerModule->init(gPowerModule);
- } else {
- ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
- }
- }
在nativeInit()方法中,创建了一个对应的Native层PowerManagerService,然后调用了gPowerModule的init函数。以下是power_module的结构类型
- struct power_module HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .module_api_version = POWER_MODULE_API_VERSION_0_2,
- .hal_api_version = HARDWARE_HAL_API_VERSION,
- .id = POWER_HARDWARE_MODULE_ID,
- .name = "Default Power HAL",
- .author = "The Android Open Source Project",
- .methods = &power_module_methods,
- },
- .init = power_init,
- .setInteractive = power_set_interactive,
- .powerHint = power_hint,
- };
Power_module的初始化代码,gPowerModule->init方法对应的是power_init 这个应该是由硬件厂商来实现的,不同的硬件初始化方式也不一样,我们看先htc相关的实现方式. Power_init实际就是在cpu的节点中写入了一些初始化的值。
- static void power_init(struct power_module __unused *module)
- {
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/timer_rate",
- "20000");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/timer_slack",
- "20000");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/min_sample_time",
- "80000");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/hispeed_freq",
- "1530000");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load",
- "99");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/target_loads",
- "65 228000:75 624000:85");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay",
- "20000");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/boostpulse_duration",
- "1000000");
- sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/io_is_busy", "0");
- calculate_max_cpu_freq();
- }
onStart函数分析:
- public void onStart() {
- publishBinderService(Context.POWER_SERVICE, new BinderService());
- publishLocalService(PowerManagerInternal.class, new LocalService());
- }
onStart方法实现比较简单,就是将PowerManagerService对象注册到ServiceManager中和LocalService中。
SystemReady函数分析:
根据分析,当System系统准备完成后,SystemServer会回调systemReady函数。先看PMS的systemReady函数具体干了些什么。
- public void systemReady(IAppOpsService appOps) {
- 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();
- //获取屏幕的亮度值,最大亮度,最小亮度,默认亮度
- 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);
- //settings的监听器
- mLightsManager = getLocalService(LightsManager.class);
- //LED指示灯管理服务
- mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
- // 初始化屏幕显示服务
- mDisplayManagerInternal.initPowerManagement(
- mDisplayPowerCallbacks, mHandler, sensorManager);
- //第二步:注册相关的BroadCastReceiver
- 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);
- //第三步.注册设置变化的监听器
- final ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.SCREENSAVER_ENABLED),
- false, mSettingsObserver, UserHandle.USER_ALL);
- ……
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.DOUBLE_TAP_TO_WAKE),
- false, mSettingsObserver, UserHandle.USER_ALL);
- //双击唤醒屏幕
- // 第四步: 从文件读取默认的配置信息
- readConfigurationLocked();
- //读取设置信息,并更新相关的变量
- updateSettingsLocked();
- // 第五步
- mDirty |= DIRTY_BATTERY_STATE;
- //更新电源的相关信息
- updatePowerStateLocked();
- }
- }
systemReady方法代码虽然很长,但是逻辑大致可以分为五个步骤
第一步:初始化相关的变量和服务
初始化了DreamManager,DisplayManager,PowerManager,BatteryStats,LightManager等相关的变量,初始化了屏幕亮度最大、最小和默认三个数值。
第二步:注册相关的广播接收器
注册了电量变化、用户切换和Dream等相关的广播接收器
当电量发生变化,调用handleBatteryStateChangedLocked方法处理电源变化的逻辑。
- private void handleBatteryStateChangedLocked() {
- mDirty |= DIRTY_BATTERY_STATE;
- updatePowerStateLocked();
- }
最终调用updatePowerStateLocked更新电源状态,该方法稍后分析
第三步:注册相关设置的变化监听
监听设置中相关信息的变化,例如灭屏时间,屏幕亮度,低电量的值,双击唤醒等
当settings中的关于电量的设置发生变化的时候,settingsObserver接收到变化监听,调用handleSettingsChangedLocked方法来处理settings变化的逻辑。
- private void handleSettingsChangedLocked() {
- updateSettingsLocked();
- updatePowerStateLocked();
- }
调用updateSettingsLocked方法,从新读取设置信息,更新设置信息,调用updatePowerStateLocked更新电源状态信息。
第四步:配置文件中读取相关的配置信息,更新setting中设置的信息
调用readConfigurationLocked方法,从xml文件中读取预置的配置信息,并赋值给相应的变量。
调用updateSettingLocked方法,根据预置的变量信息和Settings中配置的信息来初始化Setting的相关变量。
第五步:更新电源的状态信息
调用updatePowerStateLocked来更新电源状态信息。该方法是PowerManagerService的核心方法,后面会详细分析。
总结:PowerManagerService启动流程图如下。
到此PowerManagerService的启动流程就分析完成了。下面分析PMS的核心方法updatePowerStateLocked()方法。