




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
按键事件对于按键事件,调用mDevices-layoutMap-map进行映射。映射实际是由 KeyLayoutMap:map完成的,KeyLayoutMap类里读取配置文件qwerty.kl,由配置 文件 qwerty.kl 决定键值的映射关系。你可以通过修 改./development/emulator/keymaps/qwerty.kl来改变键值的映射关系。JNI 函数在 frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp文 件中,向 JAVA提供了函数android_server_KeyInputQueue_readEvent,用于读 取输入设备事件。C代码: static jboolean android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz, jobject event) gLock.lock(); sp hub = gHub; if (hub = NULL) hub = new EventHub; gHub = hub; gLock.unlock(); int32_t deviceId; int32_t type; int32_t scancode, keycode; uint32_t flags; int32_t value; nsecs_t when; bool res = 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); return res; readEvent调用hub-getEvent读了取事件,然后转换成JAVA的结构。事件中转线程在frameworks/base/services/java/com/android/server/KeyInputQueue.java 里创建了一个线程,它循环的读取事件,然后把事件放入事件队列里。Java代码: Thread mThread = new Thread(InputDeviceReader) public void run() android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY); try RawInputEvent ev = new RawInputEvent(); while (true) InputDevice di; / block, doesnt release the monitor readEvent(ev); boolean send = false; boolean configChanged = false; if (false) Log.i(TAG, Input event: dev=0x + Integer.toHexString(ev.deviceId) + type=0x + Integer.toHexString(ev.type) + scancode= + ev.scancode + keycode= + ev.keycode + value= + ev.value); if (ev.type = RawInputEvent.EV_DEVICE_ADDED) synchronized (mFirst) di = newInputDevice(ev.deviceId); mDevices.put(ev.deviceId, di); configChanged = true; .; 按键、触摸屏流、轨迹球程分析输入事件分发线程在frameworks/base/services/java/com/android/server/WindowManagerService.java里创建了一个输入事件分发线程,它负责把事件分发到相应的窗口上去。按键触摸屏流程分析: WindowManagerService类的构造函数 WindowManagerService() mQueue = new KeyQ();因为 WindowManagerService.java (frameworksbaseservicesjavacomandroidserver)中有:private class KeyQ extends KeyInputQueue implements KeyInputQueue.FilterCallbackKeyQ 是抽象类 KeyInputQueue 的实现,所以 new KeyQ类的时候实际上在 KeyInputQueue 类中创建了一个线程 InputDeviceReader 专门用来从设备读取按键事件,代码:Thread mThread = new Thread(InputDeviceReader) public void run() / 在循环中调用: readEvent(ev); . send = preprocessEvent(di, ev); /实际调用的是 KeyQ 类的 preprocessEvent 函数 . int keycode = rotateKeyCodeLocked(ev.keycode); int map = mKeyRotationMap; for (int i=0; igetEvent(&deviceId, &type, &scancode, &keycode,&flags, &value, &when)调用的是EventHub.cpp (frameworksbaselibsui)中的: bool EventHub:getEvent (int32_t* outDeviceId, int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen)在函数中调用了读设备操作:res = read(mFDs.fd, &iev, sizeof(iev);在构造函数 WindowManagerService()调用 new KeyQ() 以后接着调用了: mInputThread = new InputDispatcherThread(); . mInputThread.start();来启动一个线程 InputDispatcherThread run() process(); QueuedEvent ev = mQueue.getEvent(.)因为WindowManagerService类中: final KeyQ mQueue;所以实际上 InputDispatcherThread 线程实际上从 KeyQ 的事件队列中读取按键事件,在process() 方法中进行处理事件。 switch (ev.classType) case RawInputEvent.CLASS_KEYBOARD: . dispatchKey(KeyEvent)ev.event, 0, 0); mQueue.recycleEvent(ev); break; case RawInputEvent.CLASS_TOUCHSCREEN: /Log.i(TAG, Read next event + ev); dispatchPointer(ev, (MotionEvent)ev.event, 0, 0); break; case RawInputEvent.CLASS_TRACKBALL: dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0); break; =补充一些内容:在写程序时,需要捕获KEYCODE_HOME、KEYCODE_ENDCALL、KEYCODE_POWER这几个按键,但是这几个按键系统做了特殊处理,在进行dispatch之前做了一些操作,HOME除了Keygaurd之外,不分发给任何其他APP,ENDCALL和POWER也类似,所以需要我们系统处理之前进行处理。我的做法是自己定义一个FLAG,在自己的程序中添加此FLAG,然后在WindowManagerServices.java中获取当前窗口的FLAG属性,如果是我们自己设置的那个FLAG,则不进行特殊处理,直接分发按键消息到我们的APP当中,由APP自己处理。这部分代码最好添加在Overrideboolean preprocessEvent(InputDevice device, RawInputEvent event)方法中,这个方法是KeyInputQueue中的一个虚函数,在处理按键事件之前的一个“预处理”。PS:对HOME键的处理好像必需要修改PhoneWindowManager.java中的interceptKeyTi方法,具体可以参考对KeyGuard程序的处理。 = 系统底层事件处理过程在系统启动后,android 会通过 static const char *device_path = /dev/input; bool EventHub:penPlatformInput(void) res = scan_dir(device_path);通过下面的函数打开设备。 int EventHub:pen_device(const char *deviceName) . fd = open(deviceName, O_RDWR); . mFDsmFDCount.fd = fd; mFDsmFDCount.events = POLLIN; . ioctl(mFDsmFDCount.fd, EVIOCGNAME(sizeof(devname)-1), devname); . const char* root = getenv(ANDROID_ROOT); snprintf(keylayoutFilename, sizeof(keylayoutFilename), %s/usr/keylayout/%s.kl, root, tmpfn); . device-layoutMap-load(keylayoutFilename); . 打开设备的时候,如果 device-classes&CLASS_KEYBOARD 不等于 0 表明是键盘。常用输入设备的定义有:enum CLASS_KEYBOARD = 0x00000001, /键盘 CLASS_ALPHAKEY = 0x00000002, / CLASS_TOUCHSCREEN = 0x00000004, /触摸屏 CLASS_TRACKBALL = 0x00000008 /轨迹球 ;打开键盘设备的时候通过上面的 ioctl 获得设备名称,命令字 EVIOCGNAME 的定义在文件:kernel/include/linux/input.h 中。#define EVIOCGNAME(len) _IOC(_IOC_READ, E, 0x06, len) /* get device name */在内核键盘驱动文件 drivers/input/keyboard/pxa27x_keypad.c 中定义了设备名称:pxa27x-keypadstatic struct platform_driver pxa27x_keypad_driver = .probe = pxa27x_keypad_probe, .remove = _devexit_p(pxa27x_keypad_remove), .suspend = pxa27x_keypad_suspend, .resume = pxa27x_keypad_resume, .driver = .name = pxa27x-keypad, .owner = THIS_MODULE, ,;ANDROID_ROOT 为环境变量,在android的命令模式下通过 printenv 可以知道它为: system所以 keylayoutFilename 为:/system/usr/keylayout/pxa27x-keypad.klpxa27x-keypad.kl 定义了按键映射,具体内容如下: # NUMERIC KEYS 3x4 key 2 1 key 3 2 key 4 3 key 5 4 key 6 5 key 7 6 key 8 7 key 9 8 key 10 9 key 11 0 key 83 POUND key 55 STAR # FUNCTIONAL KEYS key 231 MEN
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2025学年江西省上饶市万年县人教版四年级下册期末考试数学试卷(无答案)
- 内江师范自考题库及答案
- 家客认证考试试题及答案
- 法治知识考试试卷及答案
- 2025年初级普车考试试题及答案
- 2025年咸阳二建考试试题及答案
- 2025年城市防洪考试题及答案
- 军用油库综合视频监控系统技术方案
- 新中考美术考试题及答案
- 情景交际答题课件
- 2025秋人教部编版三年级上册语文教学计划
- 实验室常规玻璃仪器的操作及注意事项课件
- 临时用地复垦与方案
- 语言学纲要课件
- 地下室开槽引流方案
- 电子课件-《市场营销》-A45-2298完整版教学课件全书电子讲义(最新)
- 新苏教版科学六年级上册教学计划含进度表
- 2021年新苏教版科学六年级上册知识点整理
- 美的观念(玛丽艳)
- 农药学原理课件--作用机制研究的思路和方法
- 区委书记在全区惠企政策解读会上的讲话
评论
0/150
提交评论