您的位置:首页 > 其它

PowerManagerService学习笔记一

2014-02-08 20:28 363 查看
PowerManagerService(PMS): 主要负责Android系统中电源管理方面的工作。与其直接关系的类成员有如下几个:

PowerManagerService从IPowerManager.Stub派生,并实现了Watchdog.Monitor及LocalPowerManager接口;

IPowerManager.Stub及其内部类Proxy均有aidl工具处理IPower-Mangaer.aidl后得到;

客户端使用PowerManager类,其内部通过BinderProxy端的mService成员变量与PowerManagerService进行Binder通信;

PowerManagerService(PMS)的创建

PMS有SystemServer在ServerThread中创建,这里有几个关键的过程

//SystemServer.java
//ServerThread的run方法
//关键点1
power = new PowerManagerService();
/*注册到SM中*/
ServiceManager.addService(Context.POWER_SERVICE,power);
//关键点2
power.init(context, lights, ActivityManagerService.self(), battery);
......//其它服务
//关键点3
power.systemReady();
......//系统启动完毕会受到ACTION_BOOT_COMPLETED广播
//关键点4
//PMS处理ACTION_BOOT_COMPLETED广播

关键点1:
PowerManagerService() {
// Hack to get our uid... should have a func for this.
long token = Binder.clearCallingIdentity();
MY_UID = Process.myUid();
MY_PID = Process.myPid();
Binder.restoreCallingIdentity(token);

// XXX remove this when the kernel doesn't timeout wake locks
//设置超时间为1周
Power.setLastUserActivityTimeout(7*24*3600*1000); // one week

// assume nothing is on yet
//重要的两个成员变量
mUserState = mPowerState = 0;

//将自己添加到看门狗的监控管理队列中
Watchdog.getInstance().addMonitor(this);
}


关键点2:
init主要完成以下几方面的工作:

1> 对一些成员变量进行赋值;

2> 调用nativeInit方法初始化Native层;

3> 调用updateNativePowerStateLocked方法更新Native层的电源状态;

4> 创建mScreenOffThread线程,按Power键关闭屏幕时,屏幕不是突然变黑,而是一个渐暗的过程。mScreenOffThread线程就是用于控制关闭屏幕过程中的亮度调节;

5> 创建mHandlerThread线程,该线程是PMS的主要工作线程;

6> 初始化mHandlerThread线程相关信息;

7> 强制触发一次用户事件;

各方面共做对应的源码:

1>成员变量说明

 


2>nativeInit

//com_android_server_PowerManagerService.cpp

static void android_server_PowerManagerService_nativeInit(JNIEnv* env, jobject obj) {
//创建一个全局引用对象
gPowerManagerServiceObj = env->NewGlobalRef(obj);
}
3> updateNativePowerStateLocked(待学习)
4> mScreenOffThread创建

//PowerManagerService.java

mInitComplete = false;
mScreenOffThread = new HandlerThread("PowerManagerService.mScreenOffThread") {
@Override
protected void onLooperPrepared() {
mScreenOffHandler = new Handler();
synchronized (mScreenOffThread) {
mInitComplete = true;
mScreenOffThread.notifyAll();
}
}
};
mScreenOffThread.start();
//等待mScreenOffThread线程创建完毕
synchronized (mScreenOffThread) {
while (!mInitComplete) {
try {
mScreenOffThread.wait();
} catch (InterruptedException e) {
// Ignore
}
}
}
5> mHandlerThread创建
mInitComplete = false;
mHandlerThread = new HandlerThread("PowerManagerService") {
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
初始化mHandlerThread线程
initInThread();
}
};
mHandlerThread.start();
//等待mHandlerThread线程创建完毕
synchronized (mHandlerThread) {
while (!mInitComplete) {
try {
mHandlerThread.wait();
} catch (InterruptedException e) {
// Ignore
}
}
}
6> initInThread分析
a. PMS需要了解外面的状态,所以会注册一些广播接收对象,接收诸如启动完毕,电池变化等广播; 

b. PMS所从事的电源管理工作需要一些规则,需要对其做一些配置,这些配置信息有些是固定的(编译后无法改变),有些是可以在Settings数据库中动态设定的;

c. PMS需要对法发送一些通知,诸如,屏幕关闭/开启;

d. 源代码

对于数据库中的参数配置,需要加入监测机制,通知PMS更新相关配置。

void initInThread() {
mHandler = new Handler();

mBroadcastWakeLock = new UnsynchronizedWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
mProximityPartialLock = new UnsynchronizedWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
//创建广播通知的intent,用于通知SCREEN_ON/SCREEN_OFF消息
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);

//取得参数配置,编译时确定,运行过程中无法修改
Resources resources = mContext.getResources();
mAnimateScreenLights = resources.getBoolean(
com.android.internal.R.bool.config_animateScreenLights);

mUnplugTurnsOnScreen = resources.getBoolean(
com.android.internal.R.bool.config_unplugTurnsOnScreen);

mScreenBrightnessDim = resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDim);

// read settings for auto-brightness
mUseSoftwareAutoBrightness = resources.getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available);
if (mUseSoftwareAutoBrightness) {
mAutoBrightnessLevels = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels);
mLcdBacklightValues = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
mButtonBacklightValues = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
mKeyboardBacklightValues = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
mLightSensorWarmupTime = resources.getInteger(
com.android.internal.R.integer.config_lightSensorWarmupTime);
}
//取得参数配置完毕
//取得数据库设置的配置参数
ContentResolver resolver = mContext.getContentResolver();
Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
"(" + Settings.System.NAME + "=?) or ("
+ Settings.System.NAME + "=?) or ("
+ Settings.System.NAME + "=?) or ("
+ Settings.System.NAME + "=?) or ("
+ Settings.System.NAME + "=?) or ("
+ Settings.System.NAME + "=?)",
new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN,
SCREEN_BRIGHTNESS_MODE, WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
null);
mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
//观察者模式,监视ContentQueryMap中内容的变化
SettingsObserver settingsObserver = new SettingsObserver();
mSettings.addObserver(settingsObserver);

// pretend that the settings changed so we will get their initial state
settingsObserver.update(mSettings, null);

//注册接收通知的BroadCastReceiver对象
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
mContext.registerReceiver(new BatteryReceiver(), filter);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
mContext.registerReceiver(new BootCompletedReceiver(), filter);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DOCK_EVENT);
mContext.registerReceiver(new DockReceiver(), filter);

// Listen for secure settings changes
//监视Settings数据库中secure表的变化
mContext.getContentResolver().registerContentObserver(
Settings.Secure.CONTENT_URI, true,
new ContentObserver(new Handler()) {
public void onChange(boolean selfChange) {
updateSettingsValues();
}
});
updateSettingsValues();

synchronized (mHandlerThread) {
mInitComplete = true;
mHandlerThread.notifyAll();
}
}
7> forceUserActivityLocked内部调用userActivity,调用该方法后手机被唤醒,屏幕超时时间也将重新计算
private void forceUserActivityLocked() {
if (isScreenTurningOffLocked()) {
// cancel animation so userActivity will succeed
mScreenBrightness.animating = false;
}
boolean savedActivityAllowed = mUserActivityAllowed;
mUserActivityAllowed = true;
//唤醒设备屏幕,超时时间重新计算
userActivity(SystemClock.uptimeMillis(), false);
mUserActivityAllowed = savedActivityAllowed;
}关键点3:
systemReady主要完成以下几方面工作:

1> PMS创建SensorManager,通过它可与对应的传感器交互;PMS仅仅启用特定的传感器,而来自传感器的数据将通过回调方式通知PMS,PMS根据时间作出回应;

2> 通过setPowerState方法设置电源状态为ALL_BRIGHT(不考虑,UserSoftwareAutoBrightness情况),此时屏幕及键盘都会点亮;

3> 通过BatteryStasService提供的方法,通知屏幕打开事件;

void systemReady() {
mSensorManager = new SensorManager(mHandlerThread.getLooper());
mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
// don't bother with the light sensor if auto brightness is handled in hardware
if (mUseSoftwareAutoBrightness) {
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}

// wait until sensors are enabled before turning on screen.
// some devices will not activate the light sensor properly on boot
// unless we do this.
if (mUseSoftwareAutoBrightness) {
// turn the screen on
setPowerState(SCREEN_BRIGHT);
} else {
// turn everything on
setPowerState(ALL_BRIGHT);
}

synchronized (mLocks) {
Slog.d(TAG, "system ready!");
mDoneBooting = true;

enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);

long identity = Binder.clearCallingIdentity();
try {
mBatteryStats.noteScreenBrightness(getPreferredBrightness());
mBatteryStats.noteScreenOn();
} catch (RemoteException e) {
// Nothing interesting to do.
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}

关键点4:

当系统的服务在systemReady中进行处理后,系统会发ACTION_BOOT_COMPLETED消息。

1> BootCompletedReceiver

private final class BootCompletedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
bootCompleted();
}
}
2> bootCompleted
void bootCompleted() {
Slog.d(TAG, "bootCompleted");
synchronized (mLocks) {
mBootCompleted = true;
userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
updateWakeLockLocked();
mLocks.notifyAll();
}
}
3> updateWakeLockLocked
private void updateWakeLockLocked() {
/*
mStayOnConditions用于控制当手机插上USB时,是否需要保持唤醒状态
mBatteryService.isPowered是否处于USB充电状态。
如果满足条件,PMS需要使用WakeLock来确保系统不掉电
*/
if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
// keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
mStayOnWhilePluggedInScreenDimLock.acquire();
mStayOnWhilePluggedInPartialLock.acquire();
} else {
mStayOnWhilePluggedInScreenDimLock.release();
mStayOnWhilePluggedInPartialLock.release();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: