PowerManagerService.java
case WAKEFULNESS_ASLEEP:
Slog.i(TAG, "Waking upfrom sleep...");
sendPendingNotificationsLocked();
mNotifier.onWakeUpStarted();
Notifier.java
onWakeUpStarted
/**
* Called when the device is waking up fromsleep and the
* display is about to be turned on.
*/
// True if there is a pending transitionthat needs to be reported.
synchronized (mLock) {
if (mActualPowerState !=POWER_STATE_AWAKE) {
mActualPowerState = POWER_STATE_AWAKE;
mPendingWakeUpBroadcast= true; //说明此时有待处理事务:唤醒设备
updatePendingBroadcastLocked();
updatePendingBroadcastLocked
// The currently broadcasted powerstate. This reflects what other parts ofthe
// system have observed.
mBroadcastInProgress= true; //此处表明正在发送系统广播期间
Messagemsg = mHandler.obtainMessage(MSG_BROADCAST);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
private final class NotifierHandler extendsHandler {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_BROADCAST:
sendNextBroadcast();
break;
}
private void sendNextBroadcast(){
// The currently broadcasted power state. This reflects what other parts of the
// system have observed.
private int mBroadcastedPowerState;
} else if (mBroadcastedPowerState== POWER_STATE_AWAKE) {
// Broadcasted power state isawake. Send asleep if needed.
if (mPendingWakeUpBroadcast ||mPendingGoToSleepBroadcast
|| mActualPowerState ==POWER_STATE_ASLEEP) {
mPendingGoToSleepBroadcast= false;
mBroadcastedPowerState =POWER_STATE_ASLEEP;
} else {
finishPendingBroadcastLocked();
return;
}
if (powerState == POWER_STATE_AWAKE) {
sendWakeUpBroadcast();
} else {
sendGoToSleepBroadcast(goToSleepReason);
}
private voidsendWakeUpBroadcast() {
if(ActivityManagerNative.isSystemReady()) {
mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL,null,
mWakeUpBroadcastDone, mHandler, 0, null, null);
// order BC,block likely
private final BroadcastReceiver mWakeUpBroadcastDone = newBroadcastReceiver() {
@Override
public void onReceive(Context context,Intent intent) {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
SystemClock.uptimeMillis()- mBroadcastStartTime, 1);
sendNextBroadcast();
}
};
private void finishPendingBroadcastLocked(){
mBroadcastInProgress = false;
mSuspendBlocker.release();
}
运行期间获取的日志信息:
GOTOSLEEP
04-29 14:27:26.677 D/PowerManagerNotifier( 6355): wangdong2 handle MSG_BROADCAST
04-29 14:27:26.677 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast
mBroadcastedPowerState=1 POWER_STATE_AWAKE
mPendingWakeUpBroadcast=false
mActualPowerState=2 POWER_STATE_ASLEEP
04-29 14:27:26.677 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast elseif if
04-29 14:27:26.687 D/PowerManagerNotifier( 6355): wangdong2 sendOrderedBroadcastAsUser mScreenOffIntent
04-29 14:27:26.697 D/PowerManagerNotifier( 6355): wangdong2 handle MSG_BROADCAST
04-29 14:27:26.697 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast mBroadcastedPowerState=2mPendingWakeUpBroadcast=false mActualPowerState=2
04-29 14:27:26.697 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast else else
04-29 14:27:26.787 D/PowerManagerNotifier( 6355): wangdong2 mGoToSleepBroadcastDone
WAKEUP
04-29 14:27:32.187 D/PowerManagerNotifier( 6355): wangdong2 handle MSG_BROADCAST
04-29 14:27:32.187 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast
mBroadcastedPowerState=2 POWER_STATE_ASLEEP
mPendingWakeUpBroadcast=true
mActualPowerState=1 POWER_STATE_AWAKE
04-29 14:27:32.187 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast else if
04-29 14:27:32.187 D/PowerManagerNotifier( 6355): wangdong2 sendOrderedBroadcastAsUser mScreenOnIntent
04-29 14:27:32.187 D/PowerManagerNotifier( 6355): wangdong2 handle MSG_BROADCAST
04-29 14:27:32.187 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast
mBroadcastedPowerState=1
mPendingWakeUpBroadcast=false
mActualPowerState=1
04-29 14:27:32.187 D/PowerManagerNotifier( 6355): wangdong2 sendNextBroadcast elseif else
04-29 14:27:32.527 D/PowerManagerNotifier( 6355): wangdong2 mWakeUpBroadcastDone
总结:
今天在分析系统优化策略,顺便把上次高通补丁理的更清楚一点,上次高通亮屏处理的补丁,这样看着比较清楚。
修改前为左图,必须等有序广播处理(图示椭圆区域)完之后,才能去释放资源(finishPendingBroadcastLocked,图示圆润矩形)。
修改后为右图,处理有序广播的同时,就去释放资源(即图示的分支箭头)。
多说一句,这个补丁就是为了处理单次亮屏事件,和源代码已经实现的处理多次亮屏事件,并不冲突。
PS:
finishPendingBroadcastLocked可以跟踪代码,最终会调用到电源管理的驱动代码上。
finishPendingBroadcastLocked--->
mSuspendBlocker.release(); --->
SuspendBlocker suspendBlocker = newSuspendBlockerImpl(name); --->
public void release() {nativeReleaseSuspendBlocker(mName); --->
release_wake_lock(name.c_str()); --->
int release_wake_lock(const char*id) (hardware/libhardware_legacy/power/power.c)
关于sendOrderedBroadcastAsUser 接口,是一个异步处理,发出去就返回了。官方API说明:
Like sendBroadcast(Intent),this method is asynchronous; it will return before resultReceiver.onReceive()is called.
sendNextBroadcast 调用里面的一些标志位说明:
(自己做了个笔记,你也可以参考看看,本文需要认真整理。)
mBroadcastedPowerState 表示手机当前电源状态,
但是在 sendNextBroadcast 中,如果是收到的是唤醒事件,就置为 POWER_STATE_AWAKE (虽然此时手机还没有最终唤醒)。
mPendingWakeUpBroadcast 表示有待处理的唤醒广播。
有唤醒操作(如按下power按键)时被置为true( 前提: if (mActualPowerState !=POWER_STATE_AWAKE))。
但是在 sendNextBroadcast 中(虽然广播还没处理完),被置为 false,说明已经接到该广播请求了。
mPendingGoToSleepBroadcast 休眠,同上。
mActualPowerState 表示当前想让设备处于的目标电源状态。
只要有唤醒操作(如按下power按键),这个值会被置为 true( 前提: if (mActualPowerState != POWER_STATE_AWAKE)) 。
总之,sendNextBroadcast 中, 怎么去处理接收到的电源事件广播,原则如下:
检查当前设备的电源状态 ---> 检查有没有待处理广播 ---> 检查期望目标状态和当前状态是否一致
代码说明:
onWakeUpStarted
synchronized (mLock) {
if (mActualPowerState !=POWER_STATE_AWAKE) {
//可以说,通过这个判断,限制了连续按下power按键情况下的广播发送,因为,第一次//按下power键时候,在sendNextBroadcast中,mActualPowerState已经被置为了 //POWER_STATE_AWAKE。
mActualPowerState = POWER_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
和
private void sendNextBroadcast() {
// Broadcasted power state isasleep. Send awake if needed.
if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|| mActualPowerState == POWER_STATE_AWAKE) {
mPendingWakeUpBroadcast = false;
mBroadcastedPowerState = POWER_STATE_AWAKE;
结合着使用,保证了第二次唤醒操作不会被处理,而是被丢弃。