1.前言
在14.0的系统rom定制化开发中,在12.0的系统之前默认的都是长按电源键弹出关机对话框,而在13以后
就改成音量+电源键弹出对话框,由于使用不方便,所以就改成默认长按弹出关机对话框功能
2.framework中实现默认长按电源键弹出关机对话框功能的核心类
frameworks/base/services/core/java/com/android/server/policy/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
3.framework中实现默认长按电源键弹出关机对话框功能的核心功能分析和实现
PhoneWindowManager是供系统进程使用,是WindowManagerService 的一部分,WindowManagerService
会利用PhoneWindowManager 决定一些策略来处理UI ,PhoneWindowManager作为WindowManagerService的对象,
主要用来管理和window有关的接口,通常在PhoeWindowManage.java中这个类由于实现了
的 WindowManagerPolicy接口,所以平时主要就是处理电源键,音量键等事件的拦截处理
在接收到底层的相关按键事件后,就来处理相关的按键事件
PhoneWindowManager主要管理Android 手机的特定UI行为、包括定义窗口的分层、窗口的类型、input事件的调度和窗口的布局
3.1 PhoneWindowManager.java中相关按键源码分析
在实现framework中实现默认长按电源键弹出关机对话框功能的核心功能中,通过上述的分析得知,
在PhoneWindowManager.java中的相关源码中,这里主要是处理按键事件的核心类,通过
底层上报的事件,来具体处理,所以说长按事件同样也是在这里处理的
private void initKeyCombinationRules() {
....
mKeyCombinationManager.addRule(
new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_VOLUME_UP) {
@Override
boolean preCondition() {
return mAccessibilityShortcutController
.isAccessibilityShortcutAvailable(isKeyguardLocked());
}
@Override
void execute() {
interceptAccessibilityShortcutChord();
}
@Override
void cancel() {
cancelPendingAccessibilityShortcutAction();
}
});
mKeyCombinationManager.addRule(
new TwoKeysCombinationRule(KEYCODE_VOLUME_UP, KEYCODE_POWER) {
@Override
boolean preCondition() {
switch (mPowerVolUpBehavior) {
case POWER_VOLUME_UP_BEHAVIOR_MUTE:
return mRingerToggleChord != VOLUME_HUSH_OFF;
default:
return true;
}
}
@Override
void execute() {
switch (mPowerVolUpBehavior) {
case POWER_VOLUME_UP_BEHAVIOR_MUTE:
// no haptic feedback here since
interceptRingerToggleChord();
mPowerKeyHandled = true;
break;
case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
performHapticFeedback(
HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
"Power + Volume Up - Global Actions");
//showGlobalActions();
mPowerKeyHandled = true;
break;
default:
break;
}
}
@Override
void cancel() {
switch (mPowerVolUpBehavior) {
case POWER_VOLUME_UP_BEHAVIOR_MUTE:
cancelPendingRingerToggleChordAction();
break;
case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
cancelGlobalActionsAction();
break;
}
}
});
}
}
在上述的PhoneWindowManager.java的上述源码中分析得知,在init(Context context, IWindowManager windowManager,
WindowManagerFuncs windowManagerFuncs)初始化事件中,就通过调用
initKeyCombinationRules()来初始化了一些按键监听的规则,同样的就是在这个方法中
在new TwoKeysCombinationRule(KEYCODE_VOLUME_UP, KEYCODE_POWER)
通过注册了电源键和音量+键来作为弹窗关机对话框的规则,所以这里就需要注释掉原来的
新增的弹窗对话框的规则,来作为实现默认弹窗开机对话框的功能的实现,接下来继续分析下
长按电源键的处理事件,然后修改为弹出默认关机对话框的功能
private final class PowerKeyRule extends SingleKeyGestureDetector.SingleKeyRule {
PowerKeyRule(int gestures) {
super(KEYCODE_POWER, gestures);
}
@Override
int getMaxMultiPressCount() {
return getMaxMultiPressPowerCount();
}
@Override
void onPress(long downTime) {
powerPress(downTime, 1 /*count*/,
mSingleKeyGestureDetector.beganFromNonInteractive());
}
@Override
long getLongPressTimeoutMs() {
if (getResolvedLongPressOnPowerBehavior() == LONG_PRESS_POWER_ASSISTANT) {
return mLongPressOnPowerAssistantTimeoutMs;
} else {
return super.getLongPressTimeoutMs();
}
}
@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());
}
}
private void powerLongPress(long eventTime) {
final int behavior = getResolvedLongPressOnPowerBehavior();
Slog.d(TAG, "powerLongPress: eventTime=" + eventTime
+ " mLongPressOnPowerBehavior=" + mLongPressOnPowerBehavior);
switch (behavior) {
case LONG_PRESS_POWER_NOTHING:
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
"Power - Long Press - Global Actions");
showGlobalActions();
break;
case LONG_PRESS_POWER_SHUT_OFF:
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
mPowerKeyHandled = true;
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
"Power - Long Press - Shut Off");
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
break;
case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
mPowerKeyHandled = true;
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
"Power - Long Press - Go To Voice Assist");
launchVoiceAssist(mAllowStartActivityForLongPressOnPowerDuringSetup);
break;
case LONG_PRESS_POWER_ASSISTANT:
mPowerKeyHandled = true;
performHapticFeedback(HapticFeedbackConstants.ASSISTANT_BUTTON, false,
"Power - Long Press - Go To Assistant");
final int powerKeyDeviceId = Integer.MIN_VALUE;
launchAssistAction(null, powerKeyDeviceId, eventTime,
AssistUtils.INVOCATION_TYPE_POWER_BUTTON_LONG_PRESS);
break;
}
}
在PhoneWindowManager.java中相关按键源码分析得知,在PhoneWindowManager.java中的内部类PowerKeyRule,
在这个内部类中,监听一些按键的回调事件,在onLongPress(long eventTime)中这个长按电源键中,在这里
powerLongPress(eventTime);这个方法中,具体处理各种长按事件,在打印相关的长按电源键的事件中,在
powerLongPress(eventTime);这个方法中的behavior中的类型中 LONG_PRESS_POWER_ASSISTANT处理
相关电源长按的事件,所以这里需要注释掉原来的处理事件的方法,把showGlobalActions();中的
长按弹出关机对话框的事件,这样就可以实现长按电源键弹出关机对话框的功能,
接下来具体实现这个功能的,
switch (behavior) {
case LONG_PRESS_POWER_NOTHING:
@@ -1206,12 +1206,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
launchVoiceAssist(mAllowStartActivityForLongPressOnPowerDuringSetup);
break;
case LONG_PRESS_POWER_ASSISTANT:
- mPowerKeyHandled = true;
+ /*mPowerKeyHandled = true;
performHapticFeedback(HapticFeedbackConstants.ASSISTANT_BUTTON, false,
"Power - Long Press - Go To Assistant");
final int powerKeyDeviceId = Integer.MIN_VALUE;
launchAssistAction(null, powerKeyDeviceId, eventTime,
- AssistUtils.INVOCATION_TYPE_POWER_BUTTON_LONG_PRESS);
+ AssistUtils.INVOCATION_TYPE_POWER_BUTTON_LONG_PRESS);*/
+ mPowerKeyHandled = true;
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
+ "Power - Long Press - Global Actions");
+ showGlobalActions();
break;
}
}
在上述的在PhoneWindowManager.java中相关按键源码分析得知,在具体处理长按按键的事件中
在powerLongPress(eventTime);这个方法中的behavior中的类型中 LONG_PRESS_POWER_ASSISTANT处理这个电源长按事件中,所以说在这里注释掉原来的
处理电源长按事件的功能,添加处理弹出关机对话框的功能,就是添加case LONG_PRESS_POWER_GLOBAL_ACTIONS:的相关代码移植到
LONG_PRESS_POWER_ASSISTANT的处理事件中,就实现了默认长按电源键
弹出关机对话框的功能了