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
@OverridepublicintinterceptKeyBeforeQueueing(KeyEvent event,intpolicyFlags) { ...finalbooleanisDefaultDisplayOn = mDefaultDisplayPolicy.isAwake();finalbooleandisplayOn = Display.isOnState(mDefaultDisplay.getState());finalbooleaninteractiveAndOn = interactive && isDefaultDisplayOn && displayOn;if((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {handleKeyGesture(event, interactiveAndOn);}2. PhoneWindowManager#handleKeyGesture
privatevoidhandleKeyGesture(KeyEvent event,booleaninteractive) {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.privatebooleanhandleCameraGesture(KeyEvent event,booleaninteractive) { // add by monet, do not handle camera gesture.如果是VR设备,这里会直接return false。if(SystemProperties.getBoolean("persist.xr.vrmode",true)) {returnfalse; }...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
voidinterceptKey(KeyEvent event,booleaninteractive) {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
privatebooleaninterceptKeyUp(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())); }短按Messagemsg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, mActiveRule.mKeyCode, 1, mActiveRule);msg.setAsynchronous(true); mHandler.sendMessage(msg); mActiveRule = null;returntrue; }
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
privateclassKeyHandlerextendsHandler { KeyHandler() {super(Looper.myLooper()); } @OverridepublicvoidhandleMessage(Message msg) {finalSingleKeyRule rule = (SingleKeyRule) msg.obj;if(rule == null) { Log.wtf(TAG, "No active rule.");return; }finalintkeyCode = msg.arg1;finalintpressCount = msg.arg2;switch(msg.what) {caseMSG_KEY_LONG_PRESS:if(DEBUG) { Log.i(TAG, "Detect long press " + KeyEvent.keyCodeToString(keyCode)); }rule.onLongPress(mLastDownTime);break;caseMSG_KEY_VERY_LONG_PRESS:if(DEBUG) { Log.i(TAG, "Detect very long press " + KeyEvent.keyCodeToString(keyCode)); }rule.onVeryLongPress(mLastDownTime);break;caseMSG_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. */privatefinalclassPowerKeyRuleextendsSingleKeyGestureDetector.SingleKeyRule { PowerKeyRule() {super(KEYCODE_POWER); } @Override短按一次voidonPress(longdownTime) { powerPress(downTime, 1 /*count*/, mSingleKeyGestureDetector.beganFromNonInteractive()); }@Override长按voidonLongPress(longeventTime) {if(mSingleKeyGestureDetector.beganFromNonInteractive() && !mSupportLongPressPowerWhenNonInteractive) { Slog.v(TAG, "Not support long press power when device is not interactive.");return; } powerLongPress(eventTime); } @OverridevoidonVeryLongPress(longeventTime) { mActivityManagerInternal.prepareForPossibleShutdown(); powerVeryLongPress(); } @Override多次按voidonMultiPress(longdownTime,intcount) { powerPress(downTime, count, mSingleKeyGestureDetector.beganFromNonInteractive()); }
8. PhoneWindowManager#powerPress
privatevoidpowerPress(longeventTime,intcount,booleanbeganFromNonInteractive) {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; }finalbooleaninteractive = mDefaultDisplayPolicy.isAwake(); Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive + " count=" + count + " beganFromNonInteractive=" + beganFromNonInteractive + " mShortPressOnPowerBehavior=" + mShortPressOnPowerBehavior);if(count == 2) { powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior); }elseif(count == 3) { powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior); }elseif(count > 3 && count <= getMaxMultiPressPowerCount()) { Slog.d(TAG, "No behavior defined for power press count " + count); }elseif(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 nothingif(!DeviceIntegrationUtils.DISABLE_DEVICE_INTEGRATION && BlackScreenWindowManager.getInstance().interceptPowerKey()) {return; }switch(mShortPressOnPowerBehavior) {caseSHORT_PRESS_POWER_NOTHING:break;caseSHORT_PRESS_POWER_GO_TO_SLEEP: sleepDefaultDisplayFromPowerButton(eventTime, 0);break;caseSHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: sleepDefaultDisplayFromPowerButton(eventTime, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);break;caseSHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:if(sleepDefaultDisplayFromPowerButton(eventTime, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE)) { launchHomeFromHotKey(DEFAULT_DISPLAY); }break;caseSHORT_PRESS_POWER_GO_HOME: shortPressPowerGoHome();break;caseSHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: {if(mDismissImeOnBackKeyPressed) { InputMethodManagerInternal.get().hideCurrentInputMethod( SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME); }else{ shortPressPowerGoHome(); }break; }caseSHORT_PRESS_POWER_LOCK_OR_SLEEP: {if(mKeyguardDelegate == null || !mKeyguardDelegate.hasKeyguard() || !mKeyguardDelegate.isSecure(mCurrentUserId) || keyguardOn()) { sleepDefaultDisplayFromPowerButton(eventTime, 0); }else{ lockNow(null /*options*/); }break; }caseSHORT_PRESS_POWER_DREAM_OR_SLEEP: { attemptToDreamFromShortPowerButtonPress(true, () -> sleepDefaultDisplayFromPowerButton(eventTime, 0));break; } } } }