if(mFDs[i].revents){
LOGV("reventsfor%d=0x%08x",i,mFDs[i].revents);
if(mFDs[i].revents&POLLIN){
res=read(mFDs[i].fd,&iev,sizeof(iev));
if(res==sizeof(iev)){
LOGV("%sgot:
t0=%d,t1=%d,type=%d,code=%d,v=%d",
mDevices[i]->path.string(),
....
}
4.那么framework中那个模块再调用EventHub呢,接着往下查。
在framework目录中,输入下面的命令查找
#find.-name"*.cpp"|grep-vEventHub|xargsgrepEventHub
./base/services/jni/com_android_server_KeyInputQueue.cpp:
#include
./base/services/jni/com_android_server_KeyInputQueue.cpp:
staticspgHub;
./base/services/jni/com_android_server_KeyInputQueue.cpp:
sphub=gHub;
./base/services/jni/com_android_server_KeyInputQueue.cpp:
hub=newEventHub;
./base/services/jni/com_android_server_KeyInputQueue.cpp:
sphub=gHub;
./base/services/jni/com_android_server_KeyInputQueue.cpp:
hub=newEventHub;
5.从查找结果中得知,在jni文件com_android_server_KeyInputQueue.cpp文件中有对EventHub进行调用。
打开并阅读com_android_server_KeyInputQueue.cpp文件得知,在下面的函数中调用了EventHub的getEvent函数
staticjboolean
android_server_KeyInputQueue_readEvent(JNIEnv*env,jobjectclazz,
jobjectevent)
{
gLock.lock();
sphub=gHub;
if(hub==NULL){
hub=newEventHub;
gHub=hub;
}
gLock.unlock();
int32_tdeviceId;
int32_ttype;
int32_tscancode,keycode;
uint32_tflags;
int32_tvalue;
nsecs_twhen;
boolres=hub->getEvent(&deviceId,&type,&scancode,&keycode,
&flags,&value,&when);
env->SetIntField(event,gInputOffsets.mDeviceId,(jint)deviceId);
env->SetIntField(event,gInputOffsets.mType,(jint)type);
env->SetIntField(event,gInputOffsets.mScancode,(jint)scancode);
env->SetIntField(event,gInputOffsets.mKeycode,(jint)keycode);
env->SetIntField(event,gInputOffsets.mFlags,(jint)flags);
env->SetIntField(event,gInputOffsets.mValue,value);
env->SetLongField(event,gInputOffsets.mWhen,
(jlong)(nanoseconds_to_milliseconds(when)));
returnres;
}
6.根据jni的调用规则,在本文件中查找对于的java函数。
staticJNINativeMethodgInputMethods[]={
/*name,signature,funcPtr*/
{"readEvent","(Landroid/view/RawInputEvent;)Z",
(void*)android_server_KeyInputQueue_readEvent},
....
7.接着顺藤摸瓜,找到对应的java文件,base/services/java/com/android/server/KeyInputQueue.java
privatestaticnativebooleanreadEvent(RawInputEventoutEvent);
在一个线程中会调用readEvent函数。
ThreadmThread=newThread("InputDeviceReader"){
publicvoidrun(){
if(DEBUG)Slog.v(TAG,"InputDeviceReader.run()");
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
RawInputEventev=newRawInputEvent();
while(true){
try{
InputDevicedi;
//block,doesn'treleasethemonitor
readEvent(ev);
booleansend=false;
booleanconfigChanged=false;
if(false){
Slog.i(TAG,"Inputevent:
dev=0x"
+Integer.toHexString(ev.deviceId)
+"type=0x"+Integer.toHexString(ev.type)
+"scancode="+ev.scancode
+"keycode="+ev.keycode
+"value="+ev.value);
}
8.那是谁启动这个线程呢?
?
?
查找mThread变量,得知在KeyInputQueue的构造函数中会启动这个线程。
KeyInputQueue(Contextcontext,HapticFeedbackCallbackhapticFeedbackCallback){
if(MEASURE_LATENCY){
lt=newLatencyTimer(100,1000);
}
Resourcesr=context.getResources();
BAD_TOUCH_HACK=r.getBoolean(com.android.internal.R.bool.config_filterTouchEvents);
JUMPY_TOUCH_HACK=r.getBoolean(com.android.internal.R.bool.config_filterJumpyTouchEvents);
mHapticFeedbackCallback=hapticFeedbackCallback;
readExcludedDevices();
PowerManagerpm=(PowerManager)context.getSystemService(
Context.POWER_SERVICE);
mWakeLock=pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"KeyInputQueue");
mWakeLock.setReferenceCounted(false);
mFirst=newQueuedEvent();
mLast=newQueuedEvent();
mFirst.next=mLast;
mThread.start();
}
9.那这个KeyInputQueue是在哪里被实例化呢?
而且查看KeyInputQueue类的声明,得知它是一个abstractclass.
publicabstractclassKeyInputQueue
{
.....
}
说明它肯定会被某个类继承.接着查找。
/frameworks$find.-name"*.java"|grep-vKeyInputQueue|xargsgrepKeyInputQueue
./policies/base/phone/com/android/internal/policy/impl/KeyguardViewMediator.java:
*{@linkcom.android.server.KeyInputQueue}'sand{@linkandroid.view.WindowManager}'s.
./base/services/java/com/android/server/PowerManagerService.java:
&&!
"KeyInputQueue".equals(tag))){
./base/services/java/com/android/server/WindowManagerService.java:
importcom.android.server.KeyInputQueue.QueuedEvent;
./base/services/java/com/android/server/WindowManagerService.java:
implementsWatchdog.Monitor,KeyInputQueue.HapticFeedbackCallback{
./base/services/java/com/android/server/WindowManagerService.java:
returnKeyInputQueue.getSwitchState(sw);
./base/services/java/com/android/server/WindowManagerService.java:
returnKeyInputQueue.getSwitchState(devid,sw);
./base/services/java/com/android/server/WindowManagerService.java:
returnKeyInputQueue.hasKeys(keycodes,keyExists);
./base/services/java/com/android/server/WindowManagerService.java:
privateclassKeyQextendsKeyInputQueue
./base/services/java/com/android/server/WindowManagerService.java:
implementsKeyInputQueue.FilterCallback{
./base/services/java/com/android/server/InputDevice.java:
//ForusebyKeyInputQueueforkeepingtrackofthecurrenttouch
./base/services/java/com/android/server/InputDevice.java:
if(KeyInputQueue.BAD_TOUCH_HACK){
./base/services/java/com/android/server/InputDevice.java:
Slog.i("KeyInputQueue","Updating:
"+currentMove);
./base/services/java/com/android/server/InputDevice.java:
Slog.i("KeyInputQueue","Updating:
"+currentMove);
10.从上面的查找结果得知,会在WindowManagerService.java中有一个KeyQ类继承KeyInputQueue类,再在这个文件中查找KeyQ类在哪里定义并实例化的,找到在其构造函数里实例化的。
privateWindowManagerService(Contextcontext,PowerManagerService