home鍵源碼分析

這一次我們來分析下home的源碼。


1. dispatchUnhandledKey()
我們知道,在系統級別的按鍵處理都在PhoneWindowManager.java-->dispatchUnhandledKey()函數中進行處理的,我們看
f (!interceptFallback(win, fallbackEvent, policyFlags)) 
這一個判斷,其實這裏包含了很多信息,我們來看
private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) {
        int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags);
        if ((actions & ACTION_PASS_TO_USER) != 0) {
            long delayMillis = interceptKeyBeforeDispatching(
                    win, fallbackEvent, policyFlags);
            .........
            return false;
    }

是不是覺得在這個地方很熟悉”interceptKeyBeforeDispatching()”,
進入到這個函數裏來看,

public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
    if (keyCode == KeyEvent.KEYCODE_HOME) {
            // If we have released the home key, and didn't do anything else
            // while it was pressed, then it is time to go home!
            if (!down) {
                cancelPreloadRecentApps();

                mHomePressed = false;
                if (mHomeConsumed) {
                    mHomeConsumed = false;
                    return -1;
                }

                if (canceled) {
                    Log.i(TAG, "Ignoring HOME; event canceled.");
                    return -1;
                }

                // Delay handling home if a double-tap is possible.
                if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {
                    mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
                    mHomeDoubleTapPending = true;
                    mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
                            ViewConfiguration.getDoubleTapTimeout());
                    return -1;
                }

                handleShortPressOnHome();
                return -1;
            }

            // If a system window has focus, then it doesn't make sense
            // right now to interact with applications.
            WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
            if (attrs != null) {
                final int type = attrs.type;
                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
                        || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                    // the "app" is keyguard, so give it the key
                    return 0;
                }
                final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
                for (int i=0; i<typeCount; i++) {
                    if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
                        // don't do anything, but also don't pass it to the app
                        return -1;
                    }
                }
            }

            // Remember that home is pressed and handle special actions.
            if (repeatCount == 0) {
                mHomePressed = true;
                }
            .......
            handleShortPressOnHome();
            .......
            handleLongPressOnHome();
    .............
}

其實在這段代碼中,核心的只有兩個地方,
短按: handleShortPressOnHome();
長按: handleLongPressOnHome();
這就處理了home的兩個狀態值,這是整個系統所有的一個很關鍵的地方,下面,我們分別來重點關注一下這兩個地方。

  1. handleShortPressOnHome()
private void handleShortPressOnHome() {
       ......
        // Go home!
        launchHomeFromHotKey();
    }

這裏的註釋已經說明了很多問題,直接返回launcher桌面。

  1. handleLongPressOnHome()
private void handleLongPressOnHome() {
        .....
            if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                toggleRecentApps();
            } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_ASSIST) {
                launchAssistAction();
            }
        }
    }

從上面的調用來看,
toggleRecentApps()關閉最近使用的app;
launchAssistAction()提示沒有最近使用的app;

附錄堆棧信息:
at com.android.internal.policy.impl.PhoneWindowManager.dispatchUnhandledKey(PhoneWindowManager.java:3019)
at com.android.server.wm.InputMonitor.dispatchUnhandledKey(InputMonitor.java:581)
at com.android.server.input.InputManagerService.dispatchUnhandledKey(InputManagerService.java:1553

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章