PowerManagerService的启动流程
Posted zhenjie_chang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()方法。
以上是关于PowerManagerService的启动流程的主要内容,如果未能解决你的问题,请参考以下文章
PowerManagerService启动-Android12
PowerManagerService启动-Android12
深入了解PowerManagerService之Android 11.0 Power 键亮屏灭屏流程分析