Android7.0 PowerManagerService(1) 启动过程
来源:互联网 发布:天谕动漫人物捏脸数据 编辑:程序博客网 时间:2024/05/22 15:27
Android7.0 PowerManagerService(1) 启动过程
PowerManagerService负责Android系统中电源管理方面的工作,为了简便我们在下文中将其简称为PMS。
我们先大致了解一下PMS在android中的整体结构:
如上图所示,可以看出PMS的对外接口是PowerManager,其通过Binder通信来调用PMS中定义的BinderService的接口。
BinderService与PowerManger之间的通信接口由IPowerManager.aidl来进行约束。
1、启动powermanagerservice
PMS由SystemServer来启动,我们看看SystemServer.Java中相关的代码:
private void startBootstrapServices() { .......... mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); ..........}private void startOtherServices() { ........ try { mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService()); ......... } catch (Throwable e) { ......... } ........}
SystemServer.java中PMS涉及的地方主要有两处:
1、利用startService启动PMS。
之前分析PKMS时我们已经提过,startService主要通过反射调用服务的构造函数,然后再调用服务的onStart函数。
2、调用PMS的systemReady方法。
接下来我们就分三部分,分别看看PMS的构造函数、onStart函数及systemReady函数涉及到的流程。
2、查看powermanagerservice 的构造函数
PowerManagerService的构造函数如下所示:
public PowerManagerService(Context context) { ............ //ServiceThread继承自HandlerThread,专门针对系统服务定义的,应该是优先级更高吧 mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/); mHandlerThread.start(); mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); synchronized (mLock) { //创建一些锁对象,同构acquire和release修改引用数 mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks"); mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display"); mDisplaySuspendBlocker.acquire(); mHoldingDisplaySuspendBlocker = true; mHalAutoSuspendModeEnabled = false; mHalInteractiveModeEnabled = true; mWakefulness = WAKEFULNESS_AWAKE; nativeInit(); nativeSetAutoSuspend(false); nativeSetInteractive(true); nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0); }}
容易看出PMS的构造函数较为简单,仅需要进一步分析其native函数的作用。
在com_android_server_power_PowerManagerService.cpp中:
static void nativeInit(JNIEnv* env, jobject obj) { //创建一个全局引用对象,引用PMS gPowerManagerServiceObj = env->NewGlobalRef(obj); //利用hw_get_module加载底层动态库,具体实现还是依赖与dlsym函数 status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID, (hw_module_t const**)&gPowerModule); if (!err) { //调用底层动态库的init函数 gPowerModule->init(gPowerModule); } else { ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err)); }}static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { if (enable) { ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off"); autosuspend_enable(); } else { ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on"); //初始时调用autosuspend_disable函数,定义于system/core/libsuspend/autosuspend.c中 //最终将调用到autosuspend_earlysuspend_disable函数,就是将底层的置为pwr_state_on的状态 autosuspend_disable(); }}static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { if (gPowerModule) { if (enable) { ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on"); //初始时,调用动态库的setInteractive函数,目前还不确定这个函数调用后的效果 gPowerModule->setInteractive(gPowerModule, true); } else { ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off"); gPowerModule->setInteractive(gPowerModule, false); } }}static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) { int data_param = data; if (gPowerModule && gPowerModule->setFeature) { //初始时,调用动态库的setFeature函数,将POWER_FEATURE_DOUBLE_TAP_TO_WAKE置为0 gPowerModule->setFeature(gPowerModule, (feature_t)featureId, data_param); }}
从上面的代码可以看出,PMS的构造函数还是比较简单的,就是创建一些基本的成员,然后利用native函数加载底层的动态库,并设置一些状态和标志位。
3、onstart()函数
接下来我们看看PMS的onStart函数:
public void onStart() { publishBinderService(Context.POWER_SERVICE, new BinderService()); publishLocalService(PowerManagerInternal.class, new LocalService()); Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler);}
从代码来看,onStart内容可以分成3类,即发布BinderService、发布LocalService和完成watchdog相关的工作。
我们分别看看这3类工作具体的流程。
4、publishBinderService()函数
publishBinderService定义在PMS的父类SystemService中:
//PMS中的BinderService继承自IPowerManager.Stub,实现了IBinder接口//name为PMS的名称,powerprotected final void publishBinderService(String name, IBinder service) { publishBinderService(name, service, false);}protected final void publishBinderService(String name, IBinder service, boolean allowIsolated) { //调用ServiceManger的接口,实际上利用Binder通信向Service Manger进程注册服务 ServiceManager.addService(name, service, allowIsolated);}
通过上述代码,PMS就将内部定义的BinderService注册到Service Manager进程,对应的名称为”power”。
5、publishLocalService()函数
publishLocalService同样定义在PMS的父类SystemService中:
//参数中的LocalService继承自PowerManagerInternal类protected final <T> void publishLocalService(Class<T> type, T service) { LocalServices.addService(type, service);}
从代码来看,LocalServices的作用与单例模式有些相似,不过更为严格。
单例模式用于保证某个类只能创建出一个对象; LocalServices管理对象时,确保继承某个类或接口的对象只有一个。
目前,还看不出PMS利用LocalServices管理其内部的LocalService的理由,先在此留个悬念。
6、watchdog相关工作
在之前的博客中,分析过Android 6.0中watchdog流程。
对于watchdog而言,Android 7.0与Android 6.0基本类似,这里仅再简单介绍一下涉及到的流程。
//PMS实现了Watchdog.Monitor接口,下面的代码将PMS加入到watchdog的mMonitorChecker中Watchdog.getInstance().addMonitor(this);//将PMS的ServiceThread对对应的handler传入watchdog中,watchdog将利用该handler构造一个HandlerCheckerWatchdog.getInstance().addThread(mHandler);
7、addThread()函数
当PMS调用addThread时,watchDog利用mHandler构造一个HandlerChecker,然后周期性地调用HandlerChecker的scheduleCheckLocked方法:
public void scheduleCheckLocked() { //PMS对应的HandlerChecker没有monitor,因此mMonitors.size()恒等于0 //调用MessageQueue的isPolling函数,判断是否处于polling状态; //当MessageQueue native层的looper处于等待状态,即没有事件需要处理时,isPolling返回true if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) { mCompleted = true; return; } if (!mCompleted) { // we already have a check in flight, so no need return; } mCompleted = false; mCurrentMonitor = null; mStartTime = SystemClock.uptimeMillis(); //HandlerChecker继承runnable,这里的意思是向PMS的handler发送一个HandlerChecker类型的runnable事件 mHandler.postAtFrontOfQueue(this);}public void run() { final int size = mMonitors.size(); //PMS对应的HandlerChecker的mMonitors.size为0,跳过 for (int i = 0 ; i < size ; i++) { synchronized (Watchdog.this) { mCurrentMonitor = mMonitors.get(i); } mCurrentMonitor.monitor(); } //只要PMS的mHandler在规定事件内,执行了上文传入的runnable事件,就说明没有阻塞,PMS是正常的 synchronized (Watchdog.this) { mCompleted = true; mCurrentMonitor = null; }}
8、addMonitor()函数
当PMS调用watchDog的addMonitor函数后,watchDog就会周期性地调用PMS的monitor接口:
public void monitor() { // Grab and release lock for watchdog monitor to detect deadlocks. synchronized (mLock) { }}
PMS只要能在规定时间内获得mLock锁,watchDog就能确认PMS没有死锁,状态正常。
以上只是简略介绍了一下watchDog相关的内容,详情可以参考下面的博客。
Android6.0 watchdog
9、systemReady()函数
接下来我们看一下PMS的systemReady函数:
public void systemReady(IAppOpsService appOps) { //这里持锁,意味者内部所有函数必须在规定事件内执行完毕 //否则watchDog将会检测到错误 synchronized (mLock) { mSystemReady = true; mAppOps = appOps; //注意下面的对象都是从LocalServices取出的,从之前PMS加入LocalServices的流程来看 //下面取出的实际上应该是继承抽象类的实际子类 //因此大概可以理解LocalServices的作用了,以抽象类名为key,保存实际的子类 //以key取出子类对象时,子类退化为抽象类,于是得到了实际对象,但仅能利用父类的接口 //整个设计演变为面向接口的编程 //从注释来看,与doze有关 mDreamManager = getLocalService(DreamManagerInternal.class); //显示管理相关 mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); //Window管理相关 mPolicy = getLocalService(WindowManagerPolicy.class); //电源管理相关 mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); //这里获取PowerManager就是为了方便获取下面三个系统属性 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting(); mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting(); //Sensor相关 SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); //系统电量统计有关 mBatteryStats = BatteryStatsService.getService(); // The notifier runs on the system server's main looper so as not to interfere // with the animations and other critical functions of the power manager. mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats, mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mPolicy); //无线充电检测相关 mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"), mHandler); mSettingsObserver = new SettingsObserver(mHandler); //lightService相关 mLightsManager = getLocalService(LightsManager.class); mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); // Initialize display power management. //调用DisplayManagerService内部的LocalService的函数 //创建出DisplayBlanker和DisplayPowerController mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager); //定义一堆BroadcastReceiver .................. //利用mSettingsObserver监听一堆数据库字段的变化 .................. //VR相关 IVrManager vrManager = (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE); try { vrManager.registerListener(mVrStateCallbacks); } catch (RemoteException e) { Slog.e(TAG, "Failed to register VR mode state listener: " + e); } //从资源文件中读取大量配置信息 readConfigurationLocked(); //读取数据库字段,保存到本地变量中 //必要时会进行一些实际的操作,例如设置feature到native层的动态库 updateSettingsLocked(); mDirty |= DIRTY_BATTERY_STATE; //更新全局的电源状态 updatePowerStateLocked(); }}
从代码来看,PMS在systemReady中主要是获得一些成员变量,注册一些广播接收对象、读取一些配置参数等。虽然PMS会与多个服务打交道,使得systemReady内容较为庞杂,但整个过程比较简单。
在systemReady函数的最后,调用了一个比较重要的函数updatePowerStateLocked。当PMS监控到终端发生重大变化时,将利用该函数集中更新所有相关的状态。updatePowerStateLocked涉及的内容较多,等对PMS整体有了初步的了解后,再来分析这个函数。
总结
本篇博客侧重于介绍PMS的启动过程,同时对PMS需要打交道的服务建立一个基本的认识。
文献参考:
1、 Android7.0 PowerManagerService(1) 启动过程
http://blog.csdn.net/gaugamela/article/details/52785041
- Android7.0 PowerManagerService(1) 启动过程
- Android7.0 PowerManagerService(1) 启动过程
- Android7.0 PowerManagerService(1) 启动过程
- Android7.0 PowerManagerService(1) 启动过程
- Android7.0 PowerManagerService(4) Power按键流程
- Android7.0 PowerManagerService亮灭屏分析(一)
- Android7.0 PowerManagerService亮灭屏分析(二)
- Android7.0 PowerManagerService亮灭屏分析(三)
- Android7.0 PowerManagerService Power按键流程
- Android7.0 PowerManagerService亮灭屏分析(一)
- Android7.0 PowerManagerService亮灭屏分析(二)
- Android7.0 PowerManagerService亮灭屏分析(三)
- Android7.0 PowerManagerService(4) Power按键流程
- Android7.0 PowerManagerService(4) Power按键流程
- Android7.0startActivity启动过程分析
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- Android7.0 PowerManagerService(3) 核心函数updatePowerStateLocked的主要流程
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- POJ 2155 二维树状数组+差分
- Linux下C语言用socket获取网页源码
- 快速排序 python版
- 【PAT】【Advanced Level】1087. All Roads Lead to Rome (30)
- 08:判断一个数能否同时被3和5整除
- Android7.0 PowerManagerService(1) 启动过程
- (源码分析)Android系统时间-自动获取
- Eigen介绍及简单使用
- LeetCode 219. Contains Duplicate II
- ubuntu16.04QT5.8安装和arm环境下的qte-5.8.0安装配置
- mysql字符串截取
- ELECTRICAL TYPE
- nginx配置本地虚拟域名
- react-native 代码编程规范、约定