android4.0 Power、home、menu等按键处理分析
一、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 InputReaderPolicyInte易做图ce,
public virtual InputDispatcherPolicyInte易做图ce,
public virtual PointerControllerPolicyInte易做图ce {
}我们可以知道,InputManager的构造函数的第二个参数实际上就是InputDispatcherPolicyInte易做图ce的实现,也就是com_android_server_InputManager的实例。
由InputDispatcher的声明我们知道,这里policy自然就是com_android_server_InputManager了
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInte易做图ce>& 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中了
作者:kakaBack补充:移动开发 , Android ,