从InputManagerService分析我们知道,当按下手机的Power键之后,按键事件会传到InputDispatcher 的notifyKey 方法,然后调用到调用了NativeInputManager的interceptKeyBeforeQueueing函数,最终在这个函数中会调用到PhoneWindowManager中的interceptKeyBeforeQueueing函数,以上主要属于InputManagerService的范畴,Power按键流程我们从PhoneWindowManager 的interceptKeyBeforeQueueing 方法开始分析。
方法interceptKeyBeforeQueueing关键步骤:
第一步:初始化关键变量
if (!mSystemBooted) {
return 0;
}
final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
final int keyCode = event.getKeyCode();
final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
首先判断系统是否启动完成,然后就是初始化一些关键变量
Interactive 表示屏幕是否点亮,这个变量表示PowerManagerService关于屏幕的状态
Down 表示是否是ActionDown事件
Canceled 事件是否取消
keyCode 按键编码
第二步,根据interative的状态的处理一些基本逻辑
if (interactive || (isInjected && !isWakeKey)) {
//事件传递给用户
result = ACTION_PASS_TO_USER;
isWakeKey = false;
} else if (!interactive && shouldDispatchInputWhenNonInteractive()) {
result = ACTION_PASS_TO_USER;
} else {
result = 0;
if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) {
isWakeKey = false;
}
}
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
if (isWakeKey) {
//直接唤醒系统
wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, " android.policy:KEY");
}
return result;
}
第三步,处理Power按键的事件
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
Power键按下
interceptPowerKeyDown(event, interactive);
} else {
Power键释放
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
首先是Power按键的事件的话,不再分发到应用,如果是ActionDown事件执行InterceptPowerKeyDown()方法,如果是ActionUP事件则执行InterceptPowerKeyUp()方法
下一步继续分析interceptPowerKeyDown方法
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
if (!mPowerKeyWakeLock.isHeld()) {
mPowerKeyWakeLock.acquire();
}