【PWM】PhoneWindowManager之Power键事件处理。

序言:

1.所有FW系列的知识,皆基于Android 12。
2.PhoneWindowManager简称PWM。
3.PWM有超过6千行代码,不一一讲解,将分数篇,讲解不同事件的处理。

本篇将讲解Power事件的初始化流程,以及事件拦截。

一,PhoneWindowManager 是什么?

PWM负责Window System与FW的通信,处理与设备展示相关的事件。包括窗口管理,触摸事件,点击事件,以及Power键相关的事件处理。

二,Power键的初始化流程。

  1. 初始化入口:init(Context , WindowManagerFuncs )
    /** {@inheritDoc} */
    @Override
    public void init(Context context, WindowManagerFuncs windowManagerFuncs) {
        mContext = context;
        mWindowManagerFuncs = windowManagerFuncs;
        
        // 代码省略...
        // 初始化单个按键监听(也有组合键监听,不在此篇范畴)
        initSingleKeyGestureRules();
        // 代码省略...
    }
  1. 注册单按键监听:initSingleKeyGestureRules()

    private void initSingleKeyGestureRules() {
        /**
         * 初始化单键手势监听类,这里get(Context)的实现,
         * 并非我们预想的单例模式,而是为了方便初始化一些静态变量。
         * 详情可查对应方法,这里不赘述。
         **/
        mSingleKeyGestureDetector = SingleKeyGestureDetector.get(mContext);

        int powerKeyGestures = 0;
        
        // 判断当前设备是否支持Power键超长按事件
        if (hasVeryLongPressOnPowerBehavior()) {
            powerKeyGestures |= KEY_VERYLONGPRESS;
        }
        
        // 判断当前设备是否支持Power键长按事件
        if (hasLongPressOnPowerBehavior()) {
            powerKeyGestures |= KEY_LONGPRESS;
        }
       
        // 添加Power按键监听
        mSingleKeyGestureDetector.addRule(new PowerKeyRule(powerKeyGestures));

        // 判断当前设备是否支持长按Back事件
        if (hasLongPressOnBackBehavior()) {
            // 如果支持,则添加监听。
            mSingleKeyGestureDetector.addRule(new BackKeyRule(KEY_LONGPRESS));
        }
        
        // 暂时未知这个StemPrimary是干嘛用的,先忽略
        if (hasStemPrimaryBehavior()) {
            int stemPrimaryKeyGestures = 0;
            if (hasLongPressOnStemPrimaryBehavior()) {
                stemPrimaryKeyGestures |= KEY_LONGPRESS;
            }
            mSingleKeyGestureDetector.addRule(new StemPrimaryKeyRule(stemPrimaryKeyGestures));
        }
    }
  1. 私有内部类: PowerKeyRule。 这个类,注册了多个事件监听,这里,我们仅讲解长按事件,其它的事件,原理相近,不再赘述。

    /**
     * 监听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();
            }
        }

        // Power键长按事件
        @Override
        void onLongPress(long eventTime) {
            // 1. 判断用户当前是否有在使用设备,如果没有则返回。
            //    没有使用的情况包括:屏幕未解锁,息屏等。
            
            // 2.mSupportLongPressPowerWhenNonInteractive 为true时,
            //   就算没有在使用设备,也会触发powerLongPress(eventTime);
            if (mSingleKeyGestureDetector.beganFromNonInteractive()
                    && !mSupportLongPressPowerWhenNonInteractive) {
                Slog.v(TAG, "Not support long press power when device is not interactive.");
                return;
            }

            // 长按Power键事件处理
            powerLongPress(eventTime);
        }

        @Override
        void onVeryLongPress(long eventTime) {
            mActivityManagerInternal.prepareForPossibleShutdown();
            powerVeryLongPress();
        }

        @Override
        void onMultiPress(long downTime, int count) {
            powerPress(downTime, count, mSingleKeyGestureDetector.beganFromNonInteractive());
        }
    }
  1. 长按Power事件处理方法: powerLongPress。
  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");
                // Some devices allow the voice assistant intent during setup (and use that intent
                // to launch something else, like Settings). So we explicitly allow that via the
                // config_allowStartActivityForLongPressOnPowerInSetup resource in config.xml.
                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;
        }
    }

如上面代码所示,如果需要,在关机前处理一些逻辑,比如,Show个Dialog或做其它业务操作,可以在这个地方,加处理逻辑。但需要注意的是,需要在onPowerKeyHandled = true; 后面添加,不然,有可能会导致interceptKeyUp的handled值不正确。

      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;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值