当前位置: 代码迷 >> Android >> android4.0 Power、home、menu等按键处置分析
  详细解决方案

android4.0 Power、home、menu等按键处置分析

热度:259   发布时间:2016-05-01 18:04:49.0
android4.0 Power、home、menu等按键处理分析

一、PowerHomeMenuback以及Vol+Vol-的处理

我们知道,在WindowManagerService创建的时候会声明一个InputManager的实例,这个InputManager又会通过NativeInit实现将mCallbackslooper等添加到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中了

  相关解决方案