Android 14.0 framework中实现默认长按电源键弹出关机对话框功能

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的处理事件中,就实现了默认长按电源键

弹出关机对话框的功能了

相关推荐
大耳猫4 小时前
主动测量View的宽高
android·ui
帅次6 小时前
Android CoordinatorLayout:打造高效交互界面的利器
android·gradle·android studio·rxjava·android jetpack·androidx·appcompat
枯骨成佛7 小时前
Android中Crash Debug技巧
android
kim565912 小时前
android studio 更改gradle版本方法(备忘)
android·ide·gradle·android studio
咸芝麻鱼12 小时前
Android Studio | 最新版本配置要求高,JDK运行环境不适配,导致无法启动App
android·ide·android studio
无所谓จุ๊บ12 小时前
Android Studio使用c++编写
android·c++
csucoderlee13 小时前
Android Studio的新界面New UI,怎么切换回老界面
android·ui·android studio
kim565913 小时前
各版本android studio下载地址
android·ide·android studio
饮啦冰美式13 小时前
Android Studio 将项目打包成apk文件
android·ide·android studio
夜色。13 小时前
Unity6 + Android Studio 开发环境搭建【备忘】
android·unity·android studio