Android14 WMS-Power键短按流程
目录
1. PhoneWindowManager#interceptKeyBeforeQueueing
2. PhoneWindowManager#handleKeyGesture
3. PhoneWindowManager#handleCameraGesture
4. SingleKeyGestureDetector#interceptKey
5. SingleKeyGestureDetector#interceptKeyUp
6. SingleKeyGestureDetector#KeyHandler#handleMessage
7. PhoneWindowManager#PowerKeyRule#onPress
8. PhoneWindowManager#powerPress
WMS中事件分发从
interceptKeyBeforeDispatching->interceptKeyBeforeQueueing
1. PhoneWindowManager#interceptKeyBeforeQueueing
http://10.12.16.211:8080/source/xref/LA.QSSI.14.0.r1/LINUX/android/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java#interceptKeyBeforeQueueing
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
...
final boolean isDefaultDisplayOn = mDefaultDisplayPolicy.isAwake();
final boolean displayOn = Display.isOnState(mDefaultDisplay.getState());
final boolean interactiveAndOn = interactive && isDefaultDisplayOn && displayOn;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
handleKeyGesture(event, interactiveAndOn);
}
2. PhoneWindowManager#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) { 如果连续按power键会拉起camera,如果这个power事件被消费了,会直接return,不往下继续走短按power流程了 mPowerKeyHandled = handleCameraGesture(event, interactive); if (mPowerKeyHandled) { // handled by camera gesture. mSingleKeyGestureDetector.reset(); return; } } mSingleKeyGestureDetector.interceptKey(event, interactive); }
3. PhoneWindowManager#handleCameraGesture
// The camera gesture will be detected by GestureLauncherService.
private boolean handleCameraGesture(KeyEvent event, boolean interactive) {
// add by monet, do not handle camera gesture.
如果是VR设备,这里会直接return false。
if (SystemProperties.getBoolean("persist.xr.vrmode", true)) {
return false;
}...
4. SingleKeyGestureDetector#interceptKey
http://10.12.16.211:8080/source/xref/LA.QSSI.14.0.r1/LINUX/android/frameworks/base/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
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(event);
}
}
5. SingleKeyGestureDetector#interceptKeyUp
private boolean interceptKeyUp(KeyEvent event) {…
if (event.getKeyCode() == mActiveRule.mKeyCode) { // Directly trigger short press when max count is 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, mActiveRule); msg.setAsynchronous(true); mHandler.sendMessage(msg); mActiveRule = null; return true; }
6. SingleKeyGestureDetector#KeyHandler#handleMessage
http://10.12.16.211:8080/source/xref/LA.QSSI.14.0.r1/LINUX/android/frameworks/base/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java#425
private class KeyHandler extends Handler { KeyHandler() { super(Looper.myLooper()); } @Override public void handleMessage(Message msg) { final SingleKeyRule rule = (SingleKeyRule) msg.obj; if (rule == null) { Log.wtf(TAG, "No active rule."); return; } final int keyCode = msg.arg1; final int pressCount = msg.arg2; switch(msg.what) { case MSG_KEY_LONG_PRESS: if (DEBUG) { Log.i(TAG, "Detect long press " + KeyEvent.keyCodeToString(keyCode)); } rule.onLongPress(mLastDownTime); break; case MSG_KEY_VERY_LONG_PRESS: if (DEBUG) { Log.i(TAG, "Detect very long press " + KeyEvent.keyCodeToString(keyCode)); } rule.onVeryLongPress(mLastDownTime); break; case MSG_KEY_DELAYED_PRESS: if (DEBUG) { Log.i(TAG, "Detect press " + KeyEvent.keyCodeToString(keyCode) + ", count " + pressCount); } if (pressCount == 1) { 短按一次走这里 rule.onPress(mLastDownTime); } else { rule.onMultiPress(mLastDownTime, pressCount); } break; }
7. PhoneWindowManager#PowerKeyRule#onPress
http://10.12.16.211:8080/source/xref/LA.QSSI.14.0.r1/LINUX/android/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java#2481
/** * Rule for single power key gesture. */ private final class PowerKeyRule extends SingleKeyGestureDetector.SingleKeyRule { PowerKeyRule() { super(KEYCODE_POWER); } @Override 短按一次 void onPress(long downTime) { powerPress(downTime, 1 /*count*/, mSingleKeyGestureDetector.beganFromNonInteractive()); }@Override 长按 void onLongPress(long eventTime) { if (mSingleKeyGestureDetector.beganFromNonInteractive() && !mSupportLongPressPowerWhenNonInteractive) { Slog.v(TAG, "Not support long press power when device is not interactive."); return; } powerLongPress(eventTime); } @Override void onVeryLongPress(long eventTime) { mActivityManagerInternal.prepareForPossibleShutdown(); powerVeryLongPress(); } @Override 多次按 void onMultiPress(long downTime, int count) { powerPress(downTime, count, mSingleKeyGestureDetector.beganFromNonInteractive()); }
8. PhoneWindowManager#powerPress
private void powerPress(long eventTime, int count, boolean beganFromNonInteractive) { count为按power键的次数
// SideFPS still needs to know about suppressed power buttons, in case it needs to block an auth attempt.
if (count == 1) {
mSideFpsEventHandler.notifyPowerPressed();
}
if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
return;
}
final boolean interactive = mDefaultDisplayPolicy.isAwake();
Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive + " count=" + count + " beganFromNonInteractive=" + beganFromNonInteractive + " mShortPressOnPowerBehavior=" + mShortPressOnPowerBehavior);
if (count == 2) {
powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
} else if (count == 3) {
powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
} else if (count > 3 && count <= getMaxMultiPressPowerCount()) {
Slog.d(TAG, "No behavior defined for power press count " + count);
} else if (count == 1 && interactive && !beganFromNonInteractive) {
if (mSideFpsEventHandler.shouldConsumeSinglePress(eventTime)) {
Slog.i(TAG, "Suppressing power key because the user is interacting with the " + "fingerprint sensor");
return;
}
// Device Integration: If the power button is handled by black screen, then do nothing
if (!DeviceIntegrationUtils.DISABLE_DEVICE_INTEGRATION
&& BlackScreenWindowManager.getInstance().interceptPowerKey()) {
return;
}
switch (mShortPressOnPowerBehavior) {
case SHORT_PRESS_POWER_NOTHING:
break;
case SHORT_PRESS_POWER_GO_TO_SLEEP:
sleepDefaultDisplayFromPowerButton(eventTime, 0);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
sleepDefaultDisplayFromPowerButton(eventTime,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
if (sleepDefaultDisplayFromPowerButton(eventTime,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE)) {
launchHomeFromHotKey(DEFAULT_DISPLAY);
}
break;
case SHORT_PRESS_POWER_GO_HOME:
shortPressPowerGoHome();
break;
case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: {
if (mDismissImeOnBackKeyPressed) {
InputMethodManagerInternal.get().hideCurrentInputMethod(
SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME);
} else {
shortPressPowerGoHome();
}
break;
}
case SHORT_PRESS_POWER_LOCK_OR_SLEEP: {
if (mKeyguardDelegate == null || !mKeyguardDelegate.hasKeyguard() || !mKeyguardDelegate.isSecure(mCurrentUserId) || keyguardOn()) {
sleepDefaultDisplayFromPowerButton(eventTime, 0);
} else {
lockNow(null /*options*/);
}
break;
}
case SHORT_PRESS_POWER_DREAM_OR_SLEEP: {
attemptToDreamFromShortPowerButtonPress(
true,
() -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
break;
}
}
}
}