• Android Framework层Power键关机流程(一,Power长按键操作处理)


    一:Android处理Power按键长按操作

        在Framework层中,Android4.x对Power键(KeyEvent.KEYCODE_POWER)的操作,我们从PhoneWindowManager开始分析,在分析前我这里打印了该方法的堆栈调用信息。大家可以参考一下。

    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {

        ......

        android.util.Log.d("BILL",android.util.Log.getStackTraceString(new Throwable()));

        ......

    }

    1-13 19:35:32.458 D/BILL    (  718): java.lang.Throwable

    01-13 19:35:32.458 D/BILL    (  718): at com.android.internal.policy.impl.PhoneWindowManager.interceptKeyBeforeDispatching(PhoneWindowManager.java:2224)

    01-13 19:35:32.458 D/BILL    (  718): at com.android.server.wm.InputMonitor.interceptKeyBeforeDispatching(InputMonitor.java:501)

    01-13 19:35:32.458 D/BILL    (  718): at com.android.server.input.InputManagerService.interceptKeyBeforeDispatching(InputManagerService.java:1383)

    01-13 19:35:32.458 D/BILL    (  718): at dalvik.system.NativeStart.run(Native Method)

    调用流程如下(只贴出关键代码):


    interceptKeyBeforeDispatching()-->interceptPowerKeyDown()-->mPowerLongPress.run()


    1>

    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {

    ......

           case KeyEvent.KEYCODE_POWER: {
                    result &= ~ACTION_PASS_TO_USER;
                    if (down) {
                        mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn, event.getDownTime(),
                                isImmersiveMode(mLastSystemUiFlags));
                        if (isScreenOn && !mPowerKeyTriggered
                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                            mPowerKeyTriggered = true;
                            mPowerKeyTime = event.getDownTime();
                            interceptScreenshotChord();
                        }


                        ITelephony telephonyService = getTelephonyService();
                        boolean hungUp = false;
                        if (telephonyService != null) {
                            try {
                                if (telephonyService.isRinging()) {
                                    // Pressing Power while there's a ringing incoming
                                    // call should silence the ringer.
                                    telephonyService.silenceRinger();
                                /// M: [ALPS00093981] @{
                                } else if ((isScreenOn
                                    ||  mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR)
                                /// @}
                                    && (mIncallPowerBehavior
                                        & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
                                        && telephonyService.isOffhook()) {
                                    // Otherwise, if "Power button ends call" is enabled,
                                    // the Power button will hang up any current active call.
                                    hungUp = telephonyService.endCall();
                                }
                            } catch (RemoteException ex) {
                                Log.w(TAG, "ITelephony threw RemoteException", ex);
                            }
                        }
                        interceptPowerKeyDown(!isScreenOn || hungUp
                                || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);

                    } else {
                        mPowerKeyTriggered = false;
                        cancelPendingScreenshotChordAction();
                        if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
                            result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
                        }
                        mPendingPowerKeyUpCanceled = false;
                    }
                    break;
                }

    ......

    }

    注!红色为判断长按(down),蓝色为判断短按(up)。

    2>

        private void interceptPowerKeyDown(boolean handled) {
            mPowerKeyHandled = handled;
            if (!handled) {
                mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
            }
        }

    3>

    private final Runnable mPowerLongPress = new Runnable() {
    ......
                case LONG_PRESS_POWER_GLOBAL_ACTIONS:
                    mPowerKeyHandled = true;
                    if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
                        performAuditoryFeedbackForAccessibilityIfNeed();
                    }
                    sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
                    showGlobalActionsDialog();
                    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(resolvedBehavior == LONG_PRESS_POWER_SHUT_OFF);
                    break;
    ......
    };

    注:上述代码中下划线即弹出(关机、重启、飞行模式等选项)的对话框。







  • 相关阅读:
    linux之iptable案例
    nginx常用命令参数
    laravel中的多对多关系详解
    MySql计算时间差函数
    总结下Mysql分表分库的策略及应用
    swoole扩展实现真正的数据库连接池
    linux常用命令整理
    innodb mvcc实现机制
    mysqlslap 压力测试使用总结
    mysql索引总结
  • 原文地址:https://www.cnblogs.com/bill-technology/p/4130809.html
Copyright © 2020-2023  润新知