frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
case KeyEvent.KEYCODE_POWER: { //电源按键处理
try {
if (mWindowManager.getDualScreenFlag()) {
if (mWindowManager.getSecondDisplayTaskId() != -1) {
break;
}
}
} catch (RemoteException e) {
}
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
通过这段代码我们知道,当电源键按下时执行 interceptPowerKeyDown(event, interactive); 方法;电源键弹起时,执行interceptPowerKeyUp(event, interactive, canceled) 。
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
// Hold a wake lock until the power key is released.
if (!mPowerKeyWakeLock.isHeld()) {
mPowerKeyWakeLock.acquire();
}
// Cancel multi-press detection timeout.
if (mPowerKeyPressCounter != 0) {
mHandler.removeMessages(MSG_POWER_DELAYED_PRESS);
}
// Detect user pressing the power button in panic when an application has
// taken over the whole screen.
boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags),
isNavBarEmpty(mLastSystemUiFlags));
if (panic) {
mHandler.post(mHiddenNavPanic);
}
// Latch power key state to detect screenshot chord.
if (interactive && !mScreenshotChordPowerKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
mScreenshotChordPowerKeyTriggered = true;
mScreenshotChordPowerKeyTime = event.getDownTime();
interceptScreenshotChord();
}
// Stop ringing or end call if configured to do so when power is pressed.
TelecomManager telecomManager = getTelecommService();
boolean hungUp = false;
if (telecomManager != null) {
if (telecomManager.isRinging()) {
// Pressing Power while there's a ringing incoming
// call should silence the ringer.
telecomManager.silenceRinger();
} else if ((mIncallPowerBehavior
& Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
&& telecomManager.isInCall() && interactive) {
// Otherwise, if "Power button ends call" is enabled,
// the Power button will hang up any current active call.
hungUp = telecomManager.endCall();
}
}
GestureLauncherService gestureService = LocalServices.getService(
GestureLauncherService.class);
boolean gesturedServiceIntercepted = false;
if (gestureService != null) {
gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
mTmpBoolean);
if (mTmpBoolean.value && mGoingToSleep) {
mCameraGestureTriggeredDuringGoingToSleep = true;
}
}
// 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
|| mScreenshotChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
if (!mPowerKeyHandled) { //!mPowerKeyHandled排除非长按状态
if (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()) {//电源键是否支持长按
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
} else { // 屏幕休眠时 先去唤醒
wakeUpFromPowerKey(event.getDownTime());
if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {//是否支持黑屏长按电源
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
mBeganFromNonInteractive = true;
} else {
final int maxCount = getMaxMultiPressPowerCount();
if (maxCount <= 1) {
mPowerKeyHandled = true;
} else {
mBeganFromNonInteractive = true;
}
}
}
}
}
通过这里Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS); mHandler.sendMessageDelayed(msg,ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()););我们看到系统发了长按电源键的Message
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ENABLE_POINTER_LOCATION:
enablePointerLocation();
break;
case MSG_DISABLE_POINTER_LOCATION:
disablePointerLocation();
break;
case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK:
dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj);
break;
case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
break;
case MSG_DISPATCH_SHOW_RECENTS:
showRecentApps(false, msg.arg1 != 0);
break;
case MSG_DISPATCH_SHOW_GLOBAL_ACTIONS:
showGlobalActionsInternal();
break;
case MSG_KEYGUARD_DRAWN_COMPLETE:
if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
finishKeyguardDrawn();
break;
case MSG_KEYGUARD_DRAWN_TIMEOUT:
Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
finishKeyguardDrawn();
break;
case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");
finishWindowsDrawn();
break;
case MSG_HIDE_BOOT_MESSAGE:
handleHideBootMessage();
break;
case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
launchVoiceAssistWithWakeLock(msg.arg1 != 0);
break;
case MSG_POWER_DELAYED_PRESS:
powerPress((Long)msg.obj, msg.arg1 != 0, msg.arg2);
finishPowerKeyPress();
break;
case MSG_POWER_LONG_PRESS://这里我们看到长按电源的处理
powerLongPress();
break;
case MSG_UPDATE_DREAMING_SLEEP_TOKEN:
updateDreamingSleepToken(msg.arg1 != 0);
break;
case MSG_REQUEST_TRANSIENT_BARS:
WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS) ?
mStatusBar : mNavigationBar;
if (targetBar != null) {
requestTransientBars(targetBar);
}
break;
case MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU:
showTvPictureInPictureMenuInternal();
break;
case MSG_BACK_LONG_PRESS:
backLongPress();
finishBackKeyPress();
break;
case MSG_DISPOSE_INPUT_CONSUMER:
disposeInputConsumer((InputConsumer) msg.obj);
break;
case MSG_BACK_DELAYED_PRESS:
backMultiPressAction((Long) msg.obj, msg.arg1);
finishBackKeyPress();
break;
}
}
}
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
switch (behavior) {
case LONG_PRESS_POWER_NOTHING:
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
performAuditoryFeedbackForAccessibilityIfNeed();
}
showGlobalActionsInternal();
break;
case LONG_PRESS_POWER_SHUT_OFF:
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
break;
}
}
进入这段后,我们看到长按电源键出对话框的操作就是在这里了。showGlobalActionsInternal();
所以,我们要改变长按电源键的时间,就是之前我们看到的
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS); mHandler.sendMessageDelayed(msg,ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()););
这段:改为
// 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
|| mScreenshotChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
if (!mPowerKeyHandled) {
Log.d(TAG,"interactive...1:"+interactive);
if (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()) {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,5000);
//ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
} else {
wakeUpFromPowerKey(event.getDownTime());
if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,5000);
//ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
mBeganFromNonInteractive = true;
} else {
final int maxCount = getMaxMultiPressPowerCount();
if (maxCount <= 1) {
mPowerKeyHandled = true;
} else {
mBeganFromNonInteractive = true;
}
}
}
}
注:以上代码摘自7.1源码