Android配置Framework Power 键短按长按逻辑

interceptKeyBeforeQueueing

Framework任何按键的上报都在PhoneWindowManager 中 interceptKeyBeforeQueueing 这里开始,power 键也是如此,而且interceptKeyBeforeQueueing的 会对一些特殊的按键进行处理,其中就有power 键

先看下这函数的一些官方注解,在

frameworks\base\services\core\java\com\android\server\wm\InputMonitor.java

    /* Provides an opportunity for the window manager policy to intercept early key

    * processing as soon as the key has been read from the device. */

    @Override

    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {

        return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);

    }


    /* Provides an opportunity for the window manager policy to intercept early motion event

    * processing when the device is in a non-interactive state since these events are normally

    * dropped. */

    @Override

    public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {

        return mService.mPolicy.interceptMotionBeforeQueueingNonInteractive(

                whenNanos, policyFlags);

    }


    /* Provides an opportunity for the window manager policy to process a key before

    * ordinary dispatch. */

    @Override

    public long interceptKeyBeforeDispatching(

            InputWindowHandle focus, KeyEvent event, int policyFlags) {

        WindowState windowState = focus != null ? (WindowState) focus.windowState : null;

        return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);

    }


    /* Provides an opportunity for the window manager policy to process a key that

    * the application did not handle. */

    @Override

    public KeyEvent dispatchUnhandledKey(

            InputWindowHandle focus, KeyEvent event, int policyFlags) {

        WindowState windowState = focus != null ? (WindowState) focus.windowState : null;

        return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);

    }

另外需要注意到这个函数中interceptKeyBeforeQueueing 的 result = ACTION_PASS_TO_USER;

    /**

    * Pass this event to the user / app.  To be returned from

    * {@link #interceptKeyBeforeQueueing}.

    */

    public final static int ACTION_PASS_TO_USER = 0x00000001;

这个标志位标识是否将按键进一步往上传递到 interceptKeyBeforeDispatching 等等…,之前有一次调试的时候在这里拦截power 键后没有操作这个flag 导致往上interceptKeyBeforeDispatching 还能收到案件消息



回到 interceptKeyBeforeQueueing 这里面对power 键会调用

private void interceptPowerKeyDown(KeyEvent event, boolean interactive)

和  interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled)


 interceptPowerKeyDown

有个逻辑是判断是否进入长按流程

if ((hasLongPressOnPowerBehavior() ....)) {

Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);

msg.setAsynchronous(true);

mHandler.sendMessageDelayed(msg,

ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());

}

通过 MSG_POWER_LONG_PRESS 这个hanlder msg 的调用时走到 powerLongPress();

而 powerLongPress(); 中会根据配置的对应长按模式进行对应的处理

private void powerLongPress() {

    final int behavior = getResolvedLongPressOnPowerBehavior();

    switch (behavior) {

    case LONG_PRESS_POWER_NOTHING:

        break;

    case LONG_PRESS_POWER_GLOBAL_ACTIONS:

        mPowerKeyHandled = true;

        if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {

            performAuditoryFeedbackForAccessibilityIfNeed();

        }

        showGlobalActionsInternal();

        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(behavior == LONG_PRESS_POWER_SHUT_OFF);

        break;

    }

}

interceptPowerKeyUp

主要是调用

powerPress(eventTime, interactive, mPowerKeyPressCounter);

        // Done.  Reset our state.

        finishPowerKeyPress();


而power press 中会根据配置的对应短按模式进行相应的处理


            switch (mShortPressOnPowerBehavior) {

                case SHORT_PRESS_POWER_NOTHING:

                    break;

                case SHORT_PRESS_POWER_GO_TO_SLEEP:

                    mPowerManager.goToSleep(eventTime,

                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);

                    break;

                case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:

                    mPowerManager.goToSleep(eventTime,

                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,

                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);

                    break;

                case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:

                    mPowerManager.goToSleep(eventTime,

                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,

                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);

                    launchHomeFromHotKey();



那么如何修改这些配置呢


其配置流程是在PhoneWindowManager init函数的时候配置的

        mShortPressOnPowerBehavior = mContext.getResources().getInteger(

                com.android.internal.R.integer.config_shortPressOnPowerBehavior);

        mLongPressOnPowerBehavior = mContext.getResources().getInteger(

                com.android.internal.R.integer.config_longPressOnPowerBehavior);


这些config的修改是在

frameworks/base/core/res/res/values/config.xml

以Android 7.1 为例,其配置值对应的模式为

    static final int SHORT_PRESS_POWER_NOTHING = 0;

    static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1;

    static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2;

    static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3;

    static final int SHORT_PRESS_POWER_GO_HOME = 4;


    static final int LONG_PRESS_POWER_NOTHING = 0;

    static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;

    static final int LONG_PRESS_POWER_SHUT_OFF = 2;

static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;

你可能感兴趣的:(Android配置Framework Power 键短按长按逻辑)