1. 程式人生 > >Android home key以及menu key怎麼起作用的

Android home key以及menu key怎麼起作用的

void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {


    case EventEntry::TYPE_KEY: {
        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
        if (isAppSwitchDue) {
            if (isAppSwitchKeyEventLocked(typedEntry)) {
                resetPendingAppSwitchLocked(true);
                isAppSwitchDue = false;
            } else if (dropReason == DROP_REASON_NOT_DROPPED) {
                dropReason = DROP_REASON_APP_SWITCH;
            }
        }
        if (dropReason == DROP_REASON_NOT_DROPPED
                && isStaleEventLocked(currentTime, typedEntry)) {
            dropReason = DROP_REASON_STALE;
        }
        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
            dropReason = DROP_REASON_BLOCKED;
        }
        done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
        break;
    }
}
到了
bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
        DropReason* dropReason, nsecs_t* nextWakeupTime) {




if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
ALOGE("lisa-dispatchKeyLocked+1");
            CommandEntry* commandEntry = postCommandLocked(
                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
            if (mFocusedWindowHandle != NULL) {
                commandEntry->inputWindowHandle = mFocusedWindowHandle;
            }




}
到了


void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
        CommandEntry* commandEntry) {
        ALOGE("lisa-doInterceptKeyBeforeDispatchingLockedInterruptible+1");
    KeyEntry* entry = commandEntry->keyEntry;


    KeyEvent event;
    initializeKeyEvent(&event, entry);


    mLock.unlock();


    nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
            &event, entry->policyFlags);


    mLock.lock();


    if (delay < 0) {
        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
    } else if (!delay) {
        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
    } else {
        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
        entry->interceptKeyWakeupTime = now() + delay;
    }
    entry->release();
}
到了




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


        if (keyCode == KeyEvent.KEYCODE_HOME) {//matt


            // 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;
Log.d(TAG, "lisa-interceptKeyBeforeDispatching+1" );
                    return -1;
                }


                if (canceled) {
                    Log.i(TAG, "Ignoring HOME; event canceled.");
Log.d(TAG, "lisa-interceptKeyBeforeDispatching+2" );
                    return -1;
                }


                // If an incoming call is ringing, HOME is totally disabled.
                // (The user is already on the InCallUI at this point,
                // and his ONLY options are to answer or reject the call.)
                TelecomManager telecomManager = getTelecommService();
                if (telecomManager != null && telecomManager.isRinging()) {
                    Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
Log.d(TAG, "lisa-interceptKeyBeforeDispatching+3" );
                    return -1;
                }



                // Delay handling home if a double-tap is possible.
               
                   if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {
  Log.d(TAG, "lisa-interceptKeyBeforeDispatching+4" );
                    mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
                    mHomeDoubleTapPending = true;
                    mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
                            ViewConfiguration.getDoubleTapTimeout());

                    return -1;
                }



               handleShortPressOnHome();

Log.d(TAG, "lisa-interceptKeyBeforeDispatching+5" );
                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
                    Log.d(TAG, "lisa-interceptKeyBeforeDispatching+6" );
                    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
                        Log.d(TAG, "lisa-interceptKeyBeforeDispatching+7" );
                        return -1;
                    }
                }
            }


            // Remember that home is pressed and handle special actions.
        if (repeatCount == 0) {
                mHomePressed = true;
                if (mHomeDoubleTapPending) {
                    mHomeDoubleTapPending = false;
                    mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);
                    handleDoubleTapOnHome();
                } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI
                        || mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
                    preloadRecentApps();
                }
            } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                if (!keyguardOn) {
                    handleLongPressOnHome(event.getDeviceId());
                }
            }
Log.d(TAG, "lisa-interceptKeyBeforeDispatching+13" );
            return -1;
        } 


}
這段對應的log:
12-11 14:41:19.190  2427  3305 E InputDispatcher: lisa-dispatchKeyLocked
12-11 14:41:19.190  2427  3305 E InputDispatcher: lisa-dispatchKeyLocked+1
12-11 14:41:19.190  2427  3305 E InputDispatcher: lisa-doInterceptKeyBeforeDispatchingLockedInterruptible+1
12-11 14:41:19.191  2427  3305 D WindowManager: lisa-interceptKeyBeforeDispatching
12-11 14:41:19.191  2427  3305 D WindowManager: lisa-interceptKeyBeforeDispatching+13
12-11 14:41:19.191  2427  3305 E InputDispatcher: lisa-dispatchKeyLocked
12-11 14:41:19.229  2427  3305 E InputDispatcher: lisa-dispatchKeyLocked
12-11 14:41:19.229  2427  3305 E InputDispatcher: lisa-dispatchKeyLocked+1
12-11 14:41:19.229  2427  3305 E InputDispatcher: lisa-doInterceptKeyBeforeDispatchingLockedInterruptible+1
12-11 14:41:19.229  2427  3305 D WindowManager: lisa-interceptKeyBeforeDispatching
12-11 14:41:19.239  2427  3305 D WindowManager: lisa-interceptKeyBeforeDispatching+5
12-11 14:41:19.239  2427  3305 E InputDispatcher: lisa-dispatchKeyLocked


到了
private void handleShortPressOnHome() {
        // Turn on the connected TV and switch HDMI input if we're a HDMI playback device.
        getHdmiControl().turnOnTv();


        // If there's a dream running then use home to escape the dream
        // but don't actually go home.
        if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
            mDreamManagerInternal.stopDream(false /*immediate*/);
            return;
        }


        // Go home!
        launchHomeFromHotKey();
    }




到了


void launchHomeFromHotKey() {
        launchHomeFromHotKey(true /* awakenFromDreams */, true /*respectKeyguard*/);
    }




到了


   void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) {
     Slog.e(TAG, "lisa-launchHomeFromHotKey");
        if (respectKeyguard) {
            if (isKeyguardShowingAndNotOccluded()) {
                // don't launch home if keyguard showing
                return;
            }


            if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
                // when in keyguard restricted mode, must first verify unlock
                // before launching home
                mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
                    @Override
                    public void onKeyguardExitResult(boolean success) {
                        if (success) {
                            try {
                                ActivityManagerNative.getDefault().stopAppSwitches();
                            } catch (RemoteException e) {
                            }
Slog.e(TAG, "lisa-launchHomeFromHotKey  1");
                            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
                            startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
                        }
                    }
                });
                return;
            }
        }


        // no keyguard stuff to worry about, just launch home!
        try {
            ActivityManagerNative.getDefault().stopAppSwitches();
        } catch (RemoteException e) {
        }
        if (mRecentsVisible) {
            // Hide Recents and notify it to launch Home
            if (awakenFromDreams) {
                awakenDreams();
            }
Slog.e(TAG, "lisa-launchHomeFromHotKey  2");
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
            hideRecentApps(false, true);
        } else {
            // Otherwise, just launch Home
            Slog.e(TAG, "lisa-launchHomeFromHotKey  3");
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
            startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
        }
    }


到了
 void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) {
        if (awakenFromDreams) {
            awakenDreams();
        }


        Intent dock = createHomeDockIntent();
        if (dock != null) {
            try {
                if (fromHomeKey) {
                    dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey);
                }
                startActivityAsUser(dock, UserHandle.CURRENT);
                return;
            } catch (ActivityNotFoundException e) {
            }
        }
Slog.e(TAG, "lisa-startDockOrHome");


        Intent intent;


        if (fromHomeKey) {
            intent = new Intent(mHomeIntent);
            intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey);
        } else {
            intent = mHomeIntent;
        }


        startActivityAsUser(intent, UserHandle.CURRENT);最後start activity 返回home 介面
    }


log如下
12-11 15:12:41.630  2373  3227 E InputDispatcher: lisa-dispatchKeyLocked
12-11 15:12:41.630  2373  3227 E InputDispatcher: lisa-dispatchKeyLocked+1
12-11 15:12:41.630  2373  3227 E InputDispatcher: lisa-doInterceptKeyBeforeDispatchingLockedInterruptible+1
12-11 15:12:41.631  2373  3227 D WindowManager: lisa-interceptKeyBeforeDispatching
12-11 15:12:41.631  2373  3227 D WindowManager: lisa-interceptKeyBeforeDispatching+13
12-11 15:12:41.631  2373  3227 E InputDispatcher: lisa-dispatchKeyLocked
12-11 15:12:41.685  2373  3227 E InputDispatcher: lisa-dispatchKeyLocked
12-11 15:12:41.685  2373  3227 E InputDispatcher: lisa-dispatchKeyLocked+1
12-11 15:12:41.686  2373  3227 E InputDispatcher: lisa-doInterceptKeyBeforeDispatchingLockedInterruptible+1
12-11 15:12:41.686  2373  3227 D WindowManager: lisa-interceptKeyBeforeDispatching
12-11 15:12:41.690  2373  3227 E WindowManager: lisa-launchHomeFromHotKey
12-11 15:12:41.690  2373  3227 E WindowManager: lisa-launchHomeFromHotKey  3
12-11 15:12:41.696  2373  3227 E WindowManager: lisa-startDockOrHome
12-11 15:12:41.704  2373  3227 D WindowManager: lisa-interceptKeyBeforeDispatching+5