歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android4.0 Power、home、menu等按鍵處理分析

Android4.0 Power、home、menu等按鍵處理分析

日期:2017/3/1 10:16:48   编辑:Linux編程

一、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中了

Copyright © Linux教程網 All Rights Reserved