客户需要把power键的短按休眠功能去除,并且把长按功能改成直接关机,我们先分析系统framework层处理按键的代码:
interceptKeyBeforeQueueing
power按键上来都会直接走这里,我们找到power按键处理的地方如下:
case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
看到这里就明白了,所以短按必定是在interceptPowerKeyUp里处理完成的,因为长按是在按住不放的情况下出来的,所以长按必定是在interceptPowerKeyDown这里处理的。我们先把短按屏蔽掉:
private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
final boolean handled = canceled || mPowerKeyHandled;
mScreenshotChordPowerKeyTriggered = false;
cancelPendingScreenshotChordAction();
cancelPendingPowerKeyAction();
if (!handled) {
if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) == 0) {
// Abort possibly stuck animations only when power key up without long press case.
mHandler.post(mWindowManagerFuncs::triggerAnimationFailsafe);
}
// Figure out how to handle the key now that it has been released.
mPowerKeyPressCounter += 1;
final int maxCount = getMaxMultiPressPowerCount();
final long eventTime = event.getDownTime();
if (mPowerKeyPressCounter < maxCount) {
// This could be a multi-press. Wait a little bit longer to confirm.
// Continue holding the wake lock.
Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
return;
}
// No other actions. Handle it immediately.
// powerPress(eventTime, interactive, mPowerKeyPressCounter);这句去掉就没有短按了
}
// Done. Reset our state.
finishPowerKeyPress();
}
下面就改长按的功能,找到
private void interceptPowerKeyDown(KeyEvent event, boolean interactive)
看到这个方法里有如下内容:
// When interactive, we're already awake.
// Wait for a long press or for the button to be released to decide what to do.
if (hasLongPressOnPowerBehavior()) {
if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
powerLongPress();
} else {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);//长按默认走这里,通过发送MSG_POWER_LONG_PRESS消息到handler处理
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
if (hasVeryLongPressOnPowerBehavior()) {
Message longMsg = mHandler.obtainMessage(MSG_POWER_VERY_LONG_PRESS);
longMsg.setAsynchronous(true);
mHandler.sendMessageDelayed(longMsg, mVeryLongPressTimeout);
}
}
}
这里接收长按消息处理
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_POWER_LONG_PRESS:
powerLongPress();
break;
最终长按都会到这里处理powerLongPress()
直接这样改就能实现把显示关机重启对话框改为直接关机功能
@@ -1306,14 +1307,21 @@
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
+ Log.i("fan","behavior is"+behavior);
switch (behavior) {
case LONG_PRESS_POWER_NOTHING:
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
- "Power - Long Press - Global Actions");
- showGlobalActionsInternal();
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ "Power - Long Press - Shut Off");
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
+ // performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ // "Power - Long Press - Global Actions");
+ //showGlobalActionsInternal();
break;
case LONG_PRESS_POWER_SHUT_OFF:
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
如果要去除短按2次进入camera,还是在这里修改 private void
interceptPowerKeyDown(KeyEvent event, boolean interactive) {
找到如下代码屏蔽即可:
/*这里屏蔽短按打开camera功能 GestureLauncherService gestureService = LocalServices.getService(
GestureLauncherService.class);
boolean gesturedServiceIntercepted = false;
if (gestureService != null) {
gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
mTmpBoolean);
if (mTmpBoolean.value && mRequestedOrGoingToSleep) {
mCameraGestureTriggeredDuringGoingToSleep = true;
}
}
*/
// Inform the StatusBar; but do not allow it to consume the event.
sendSystemKeyToStatusBarAsync(event.getKeyCode());
schedulePossibleVeryLongPressReboot();
// If the power key has still not yet been handled, then detect short
// press, long press, or multi press and decide what to do.
mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
|| mA11yShortcutChordVolumeUpKeyTriggered /*|| gesturedServiceIntercepted*/ //这里屏蔽
|| handledByPowerManager;