1、主要会用到如下这个类中的方法
InputManagerService:interceptKeyBeforeQueueing
WindowManagerCallbacks:interceptKeyBeforeQueueing
InputManagerCallback :interceptKeyBeforeQueueing
WindowManagerPolicy : interceptKeyBeforeQueueing
PhoneWindowManager.java : interceptKeyBeforeQueueing
2、PhoneWindowManager Power键点击分析:
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
final int keyCode = event.getKeyCode();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
|| event.isWakeKey();
......
final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
final boolean canceled = event.isCanceled();
final int displayId = event.getDisplayId();
final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
......
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
① 从此处进入Power键灭屏流程
handleKeyGesture(event, interactiveAndOn);
}
......
// Handle special keys.
switch (keyCode) {
......
case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0,
mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));
// Any activity on the power button stops the accessibility shortcut
result &= ~ACTION_PASS_TO_USER;
......
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactiveAndOn);
} else {
interceptPowerKeyUp(event, canceled);
}
break;
}
.......
}
return result;
}
handleKeyGesture:
private void handleKeyGesture(KeyEvent event, boolean interactive) {
if (mKeyCombinationManager.interceptKey(event, interactive)) {
// handled by combo keys manager.
mSingleKeyGestureDetector.reset();
return;
}
if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) {
mPowerKeyHandled = handleCameraGesture(event, interactive);
if (mPowerKeyHandled) {
// handled by camera gesture.
mSingleKeyGestureDetector.reset();
return;
}
}
②开始intercept key
mSingleKeyGestureDetector.interceptKey(event, interactive);
}
SingleKeyGestureDetector : interceptKey()
void interceptKey(KeyEvent event, boolean interactive) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
// Store the non interactive state when first down.
if (mDownKeyCode == KeyEvent.KEYCODE_UNKNOWN || mDownKeyCode != event.getKeyCode()) {
mBeganFromNonInteractive = !interactive;
}
interceptKeyDown(event);
} else {
③ 在interceptkeyup的时候开始处理灭屏事件
interceptKeyUp(event);
}
}
灭屏流程是写在interceptPowerKeyUp中,因为在按下power的事件下包含很多实现,包括长按灭屏或者双击多击power事件,因此将灭屏流程写在interceptPowerKeyUp中。
SingleKeyGestureDetector : interceptKeyUp()
private boolean interceptKeyUp(KeyEvent event) {
mHandler.removeMessages(MSG_KEY_LONG_PRESS);
mHandler.removeMessages(MSG_KEY_VERY_LONG_PRESS);
mDownKeyCode = KeyEvent.KEYCODE_UNKNOWN;
if (mActiveRule == null) {
return false;
}
// 判断是否已经处理为长按事件
if (mHandledByLongPress) {
mHandledByLongPress = false;
mKeyPressCounter = 0;
return true;
}
final long downTime = event.getDownTime();
if (event.getKeyCode() == mActiveRule.mKeyCode) {
// Directly trigger short press when max count is 1.
// 最大连击次数默认为1
if (mActiveRule.getMaxMultiPressCount() == 1) {
if (DEBUG) {
Log.i(TAG, "press key " + KeyEvent.keyCodeToString(event.getKeyCode()));
}
Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, mActiveRule.mKeyCode,
1, downTime);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
return true;
}
// This could be a multi-press. Wait a little bit longer to confirm.
mKeyPressCounter++;
Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, mActiveRule.mKeyCode,
mKeyPressCounter, downTime);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(ms