一、Power、Home、Menu、back以及Vol+、Vol-的處理
我們知道,在WindowManagerService創建的時候會聲明一個InputManager的實例,這個InputManager又會通過NativeInit實現將mCallbacks、looper等添加到C++中實現創建InputDispatcher和InputReader。然後將這兩個實例各加入到InputDispatcherThread和InputReaderThread之中,實現讀取輸入事件並且進行派發。
1、InputManager.java:
構造函數中有如下實現:
this.mCallbacks = new Callbacks();
這個很關鍵,它就是在C++層實現回調的方法。然後通過NativeInit添加到C++中去了。
private final class Callbacks {
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean
isScreenOn) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
event, policyFlags, isScreenOn);
}
public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
return mWindowManagerService.mInputMonitor.
interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
}
……
}
這些都是通過WindowManagerService調用mPolicy的實現具體功能的函數
2、com_Android_server_InputManager.cpp
在android_server_InputManager_nativeInit函數中又有如下操作:
gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
這裡又將InputManager.java中實現的callbacks放到了NativeInputManager中的mCallbacksObj了。
同時構建InputManager:mInputManager = new InputManager(eventHub, this, this);
3、InputManager.cpp
在構造函數中有:
mDispatcher = new InputDispatcher(dispatcherPolicy);
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
再由
class NativeInputManager : public virtual RefBase,
public virtual InputReaderPolicyInterface,
public virtual InputDispatcherPolicyInterface,
public virtual PointerControllerPolicyInterface {
}我們可以知道,InputManager的構造函數的第二個參數實際上就是InputDispatcherPolicyInterface的實現,也就是com_android_server_InputManager的實例。
由InputDispatcher的聲明我們知道,這裡policy自然就是com_android_server_InputManager了
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
mPolicy(policy),
mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(NULL),
mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
mCurrentInputTargetsValid(false),
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE)
在InputReader讀取事件之後會喚醒InputDiapatcher函數,之後就開始調用InputDispatcher::notifyKey。詳細分析參見:
http://blog.csdn.net/luoshengyang/article/details/6882903
4、InputDispatcher.cpp
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
……
//這裡的mPolicy是InputManager
mPolicy->interceptKeyBeforeQueueing(&event, policyFlags);
……
}
5、回到com_android_server_InputManager:
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
uint32_t& policyFlags) {
if ((policyFlags & POLICY_FLAG_TRUSTED)) {
if (keyEventObj) {
//這裡,我們清晰地看到,mCallbacksObj是InputManager.java中的Callbacks了
//也就是調用它的interceptKeyBeforeQueueing了
wmActions = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing,
keyEventObj, policyFlags, isScreenOn);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0;
}
android_view_KeyEvent_recycle(env, keyEventObj);
env->DeleteLocalRef(keyEventObj);
}
}
}
我們回到步驟1的Callbacks定義:
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean
isScreenOn) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
event, policyFlags, isScreenOn);
}
InputMonitor.java
public int interceptKeyBeforeQueueing(
KeyEvent event, int policyFlags, boolean isScreenOn) {
return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
}
這裡mService是WindowManagerService,mPolicy 則是如下定義(WindowManagerService中)
final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
PolicyManager.java
public static WindowManagerPolicy makeNewWindowManager() {
//sPolicy就是Policy的實例化
return sPolicy.makeNewWindowManager();
}
Policy.java
public WindowManagerPolicy makeNewWindowManager() {
return new PhoneWindowManager();
}
至此,正式調用PhoneWindowManager的實例。
因此處理hardkey的相關代碼是在PhoneWindowManager中了