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;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容