5.4.2 Power按键处理分析
按键处理属于本书后续将会分析的输入系统的范围,此处仅对其中和Power键相关的代码进行分析,代码如下:
[—>com_android_server_InputManager.cpp:handleInterceptActions]
void NativeInputManager:handleInterceptActions(jint wmActions, nsecs_t when,
uint32_t&policyFlags){
//按下Power键并松开后,将设置wmActions为WM_ACTION_GO_TO_SLEEP,表示需要休眠
if(wmActions&WM_ACTION_GO_TO_SLEEP){
//利用JNI调用PMS的goToSleep函数
android_server_PowerManagerService_goToSleep(when);
}
//一般的输入事件将触发userActivity函数被调用,此时将唤醒手机
if(wmActions&WM_ACTION_POKE_USER_ACTIVITY){
//利用JNI调用PMS的userActivity函数。相关内容在前一节已经分析过了
android_server_PowerManagerService_userActivity(when,
POWER_MANAGER_BUTTON_EVENT);
}
……//其他处理
}
由以上代码中的注释可知,当按下Power键并松开时[1],将触发PMS的goToSleep函数被调用。下面来看goToSleep函数的代码:
[—>PowerManagerService.java:goToSleep]
public void goToSleep(long time)
{
goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
}
public void goToSleepWithReason(long time, int reason)
{
mContext.enforceCallingOrSelfPermission(//检查调用进程是否有DEVICE_POWER权限
android.Manifest.permission.DEVICE_POWER, null);
synchronized(mLocks){
goToSleepLocked(time, reason);//调用goToSleepLocked函数
}
}
[—>PowerManagerService.java:goToSleepLocked]
private void goToSleepLocked(long time, int reason){
if(mLastEventTime<=time){
mLastEventTime=time;
mWakeLockState=SCREEN_OFF;
int N=mLocks.size();
int numCleared=0;
boolean proxLock=false;
for(int i=0;i<N;i++){
WakeLock wl=mLocks.get(i);
if(isScreenLock(wl.flags)){
if(((wl.flags&LOCK_MASK)==
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
&&reason==WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR){
proxLock=true;//判断goToSleep的原因是否与接近传感器有关
}else{
mLocks.get(i).activated=false;//禁止和屏幕相关的WakeLock
numCleared++;
}
}//if(isScreenLock(wl.f(ags))判断结束
}//for循环结束
if(!proxLock){
mProxIgnoredBecauseScreenTurnedOff=true;
}
mStillNeedSleepNotification=true;
mUserState=SCREEN_OFF;
setPowerState(SCREEN_OFF, false, reason);//关闭屏幕
cancelTimerLocked();//从mHandler中撤销mTimeoutTask任务
}
}
掌握了前面的基础知识就会感到Power键的处理流程真的是很简单,读者是否也有同感呢?
[1]必须在一定时间内完成按下和松开Power键的操作,否则系统会认为是关机操作。详情将在即将出版的“卷 Ⅲ”输入系统一章进行分析。