Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 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 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.cppvoid InputDispatcher::notifyKey(const NotifyKeyArgs* args) {……//这里的mPolicy是InputManagermPolicy->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.javapublic static WindowManagerPolicy makeNewWindowManager() {//sPolicy就是Policy的实例化        return sPolicy.makeNewWindowManager();}Policy.java    public WindowManagerPolicy makeNewWindowManager() {        return new PhoneWindowManager();}至此,正式调用PhoneWindowManager的实例。因此处理hardkey的相关代码是在PhoneWindowManager中了