PowerManagerService的启动流程
来源:互联网 发布:js在div中追加内容 编辑:程序博客网 时间:2024/05/16 04:45
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的sleep和wakeup流程
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- Android7.0 PowerManagerService(3) 核心函数updatePowerStateLocked的主要流程
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- Android7.0 PowerManagerService(3) 核心函数updatePowerStateLocked的主要流程
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- Android7.0 PowerManagerService(3) 核心函数updatePowerStateLocked的主要流程
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- Android7.0 PowerManagerService(3) 核心函数updatePowerStateLocked的主要流程
- android4.4 PowerManagerService流程分析
- android4.4 PowerManagerService流程分析
- PowerManagerService流程分析(电源管理)
- Android7.0 PowerManagerService(4) Power按键流程
- Android7.0 PowerManagerService Power按键流程
- Android7.0 PowerManagerService(4) Power按键流程
- Android7.0 PowerManagerService(4) Power按键流程
- Android7.0 PowerManagerService(1) 启动过程
- Linux内核分析:页回收导致的cpu load瞬间飙高的问题分析与思考
- Win8系统下安装Oracle11g时,安装程序报错:[INS-13001]环境不满足最低要求的解决方法
- Python-lambda表达式
- Poj 1061 青蛙的约会(扩展欧几里得)
- OkHttp的学习(一)
- PowerManagerService的启动流程
- POJ 1006 生理周期(水)
- button tast
- PHP Pthread多线程操作
- 八皇后问题
- 在linux下安装minicom
- 输出1到某个整数范围中所有的完数
- laravel框架目录结构
- debug和release的不同结果