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

弹出关机对话框的功能了

相关推荐
雨白1 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹3 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空5 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭5 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日6 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安6 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑6 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟10 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡12 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0012 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体