PowerManagerService负责Android系统中电源管理方面的工作,为了简便我们在下文中将其简称为PMS。
我们先大致了解一下PMS在Android中的整体结构:
如上图所示,可以看出PMS的对外接口是PowerManager,其通过Binder通信来调用PMS中定义的BinderService的接口。
BinderService与PowerManger之间的通信接口由IPowerManager.aidl来进行约束。
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函数涉及到的流程。
一、构造函数
PowerManagerService的构造函数如下所示:
public PowerManagerService(Context context) {
............
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_DISPLAY, false );
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
synchronized (mLock) {
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
容易看出PMS的构造函数较为简单,仅需要进一步分析其native函数的作用。
在com_android_server_power_PowerManagerService.cpp中:
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));
}
}
static void nativeSetAutoSuspend(JNIEnv* , jclass , 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();
}
}
static void nativeSetInteractive(JNIEnv* , jclass , jboolean enable) {
if (gPowerModule) {
if (enable) {
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
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) {
gPowerModule->setFeature(gPowerModule, (feature_t)featureId, data_param);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
从上面的代码可以看出,PMS的构造函数还是比较简单的,就是创建一些基本的成员,然后利用native函数加载底层的动态库,并设置一些状态和标志位。
二、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类工作具体的流程。
1、publishBinderService
publishBinderService定义在PMS的父类SystemService中:
protected final void publishBinderService(String name, IBinder service) {
publishBinderService(name, service, false);
}
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
ServiceManager.addService(name, service, allowIsolated);
}
通过上述代码,PMS就将内部定义的BinderService注册到Service Manager进程,对应的名称为”power”。
2、publishLocalService
publishLocalService同样定义在PMS的父类SystemService中:
protected final <T> void publishLocalService(Class<T> type, T service) {
LocalServices.addService(type, service);
}
我们来看看LocalServices类的addService函数:
/**
* Adds a service instance of the specified interface to the global registry of local services.
*/
public static <T> void addService(Class<T> type, T service) {
synchronized (sLocalServiceObjects) {
if (sLocalServiceObjects.containsKey(type)) {
throw new IllegalStateException("Overriding service registration");
}
sLocalServiceObjects.put(type, service);
}
}
从代码来看,LocalServices的作用与单例模式有些相似,不过更为严格。
单例模式用于保证某个类只能创建出一个对象; LocalServices管理对象时,确保继承某个类或接口的对象只有一个。
目前,还看不出PMS利用LocalServices管理其内部的LocalService的理由,先在此留个悬念。
3、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构造一个HandlerChecker
Watchdog.getInstance().addThread(mHandler)
3.1 addThread
当PMS调用addThread时,watchDog利用mHandler构造一个HandlerChecker,然后周期性地调用HandlerChecker的scheduleCheckLocked方法:
public void scheduleCheckLocked() {
if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) {
mCompleted = true;
return;
}
if (!mCompleted) {
return;
}
mCompleted = false;
mCurrentMonitor = null;
mStartTime = SystemClock.uptimeMillis();
mHandler.postAtFrontOfQueue(this);
}
public void run() {
final int size = mMonitors.size();
for (int i = 0 ; i < size ; i++) {
synchronized (Watchdog.this) {
mCurrentMonitor = mMonitors.get(i);
}
mCurrentMonitor.monitor();
}
synchronized (Watchdog.this) {
mCompleted = true;
mCurrentMonitor = null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
3.2 addMonitor
当PMS调用watchDog的addMonitor函数后,watchDog就会周期性地调用PMS的monitor接口:
public void monitor() {
synchronized (mLock) {
}
}
PMS只要能在规定时间内获得mLock锁,watchDog就能确认PMS没有死锁,状态正常。
以上只是简略介绍了一下watchDog相关的内容,详情可以参考下面的博客。
Android6.0 watchdog
三、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);
mLightsManager = getLocalService(LightsManager.class);
mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
..................
..................
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();
updateSettingsLocked();
mDirty |= DIRTY_BATTERY_STATE;
updatePowerStateLocked();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
从代码来看,PMS在systemReady中主要是获得一些成员变量,注册一些广播接收对象、读取一些配置参数等。虽然PMS会与多个服务打交道,使得systemReady内容较为庞杂,但整个过程比较简单。
在systemReady函数的最后,调用了一个比较重要的函数updatePowerStateLocked。当PMS监控到终端发生重大变化时,将利用该函数集中更新所有相关的状态。updatePowerStateLocked涉及的内容较多,等对PMS整体有了初步的了解后,再来分析这个函数。
总结
本篇博客侧重于介绍PMS的启动过程,同时对PMS需要打交道的服务建立一个基本的认识。
原文地址: http://blog.youkuaiyun.com/gaugamela/article/details/52785041