Http://www.cnblogs.com/andtt/articles/2145563.html
For keystroke events, call Mdevices[i]->layoutmap->map to map. The mapping is actually done by Keylayoutmap::map, the Keylayoutmap class reads the configuration file Qwerty.kl, and the configuration file QWERTY.KL determines the mapping of the key value. You can change the mapping of the key values by modifying the./development/emulator/keymaps/qwerty.kl.
JNI function
In the Frameworks/base/services/jni/com_android_server_keyinputqueue.cpp file, a function is provided to Java Android_server_keyinputqueue_ Readevent, used to read input device events.
- 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 invokes Hub->getevent to read the event and then transforms it into a Java structure.
Event brokered Threads
A thread is created in Frameworks/base/services/java/com/android/server/keyinputqueue.java, which iterates through the events and then puts the events into the event queue.
- 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;
- Readevent (EV);
- send = Preprocessevent (di, Ev);
- Addlocked (Di, curtime, Ev.flags, ..., me);
- }
- }
- };
Input Event Distribution Thread
An input event distribution thread was created in Frameworks/base/services/java/com/android/server/windowmanagerservice.java, which is responsible for distributing the event to the appropriate window.
- Mqueue.getevent
- Dispatchkey/dispatchpointer/dispatchtrackball
keypad, touch screen process Analysis
Key Touch screen Flow analysis:
Windowmanagerservice Constructors for class
Windowmanagerservice ()
Mqueue = new Keyq ();
Because Windowmanagerservice.java (frameworks\base\services\java\com\android\server) has:
Private class Keyq extends Keyinputqueue
KEYQ is the implementation of the abstract class Keyinputqueue, so when the new Keyq class is actually created in the Keyinputqueue class
A thread inputdevicereader specifically used to punch the device to read key events, code:
Thread mthread = new Thread ("Inputdevicereader") {
public void Run ()
{
Called in the Loop: readevent (EV);
...
send = Preprocessevent (di, Ev);
The Preprocessevent function of the Keyq class is actually called
...
int keycode = rotatekeycodelocked (Ev.keycode);
int[] map = Mkeyrotationmap;
for (int i=0; i<n; i+=2)
{
if (map[i] = = keycode)
return map[i+1];
} //
Addlocked (Di, Curtime, Ev.flags,rawinputevent.class_keyboard,newkeyevent (Di, di.mdowntime, CurTime, Down,keycode, 0, Scancode,...));
Queuedevent ev = obtainlocked (device, when, flags, ClassType, event);
}
}
Readevent () is actually called in Com_android_server_keyinputqueue.cpp (FRAMEWORKS\BASE\SERVICES\JNI):
Static Jboolean android_server_keyinputqueue_readevent (jnienv* env, Jobject clazz,jobject event)
BOOL res = hub->getevent (&deviceid, &type, &scancode, &keycode,&flags, &value, &when);
The call is in EventHub.cpp (Frameworks\base\libs\ui):
BOOL Eventhub::getevent (int32_t* Outdeviceid, int32_t* Outtype,
int32_t* Outscancode, int32_t* outkeycode, uint32_t *outflags,
int32_t* Outvalue, nsecs_t* outwhen)
Read device operation was called in the function: res = read (MFDS[I].FD, &iev, sizeof (Iev));
The constructor Windowmanagerservice () calls new Keyq () and then calls the following:
Minputthread = new Inputdispatcherthread ();
...
Minputthread.start ();
To start a thread inputdispatcherthread
Run ()
Process ();
Queuedevent ev = mqueue.getevent (...)
Because the Windowmanagerservice class: Final Keyq mqueue;
So actually the inputdispatcherthread thread actually reads the key event from the Keyq event queue.
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
===============================================================
Keyinputqueue.java (Frameworks\base\services\java\com\android\server):
Threads mthread = new Thread ("Inputdevicereader") is called locally:
Readevent (EV); Read key. Readevent is called the file:
Functions in Com_android_server_keyinputqueue.cpp (FRAMEWORKS\BASE\SERVICES\JNI):
Static Jboolean android_server_keyinputqueue_readevent (jnienv* env, Jobject Clazz,
Jobject event)
The android_server_keyinputqueue_readevent include:
hub = new Eventhub;
BOOL res = hub->getevent (&deviceid, &type, &scancode, &keycode,
&flags, &value, &when);
The Hub->getevent call is
Functions in the EventHub.cpp (frameworks\base\libs\ui) file:
BOOL Eventhub::getevent (int32_t* Outdeviceid, int32_t* Outtype,
int32_t* Outscancode, int32_t* outkeycode, uint32_t *outflags,
int32_t* Outvalue, nsecs_t* outwhen)
Read the key.
Class Refbase::weakref_impl:public Refbase::weakref_type
After the system is booted, Android will
static const char *device_path = "/dev/input";
BOOL Eventhub::openplatforminput (void)
res = Scan_dir (Device_path);
Open the device by using the following function.
int Eventhub::open_device (const char *devicename)
{
...
FD = open (DeviceName, O_RDWR);
...
MFDS[MFDCOUNT].FD = FD;
Mfds[mfdcount].events = Pollin;
...
IOCTL (MFDS[MFDCOUNT].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);
...
}
When the device is turned on, if Device->classes&class_keyboard is not equal to 0 indicates the keyboard.
Common input devices are defined as:
enum {
Class_keyboard = 0x00000001,//keyboard
Class_alphakey = 0x00000002,//
Class_touchscreen = 0x00000004,//touch screen
Class_trackball = 0x00000008//trackball
};
When you turn on the keyboard device, you get the device name by the above IOCTL, and the command word eviocgname is defined in the file:
The kernel/include/linux/input.h.
#define EVIOCGNAME (len) _ioc (_ioc_read, ' E ', 0x06, len)/* Get device Name */
The device name is defined in the kernel keyboard driver file drivers/input/keyboard/pxa27x_keypad.c: Pxa27x-keypad
static 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 is an environment variable that can be known in android Command mode by printenv: System
So Keylayoutfilename is:/SYSTEM/USR/KEYLAYOUT/PXA27X-KEYPAD.KL
The PXA27X-KEYPAD.KL defines the key mapping, which reads as follows:
----------------------
# 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 POUND
Key STAR
# Functional KEYS
Key 231 MENU wake_dropped
Key 192 back Wake_dropped
Key 193 HOME WAKE
Key 107 DEL WAKE
Key 102 Call Wake_dropped
Key 158 Endcall wake_dropped
Key Dpad_center WAKE
Key Volume_up
Key Volume_down
----------------------
If the keyboard mapping file is not defined, the system's/SYSTEM/USR/KEYLAYOUT/QWERTY.KL is used by default
You can modify the/system/usr/keylayout/qwerty.kl file to change the key mapping for Android.
Device->layoutmap->load (keylayoutfilename) is the file that is called:
Functions in KeyLayoutMap.cpp (FRAMEWORKS\BASE\LIBS\UI):
status_t keylayoutmap::load (const char* filename) by parsing PXA27X-KEYPAD.KL
The mapping relation of the keys is saved in:keyedvector<int32_t,key> M_keys; In
Called when a key event is obtained:
status_t Keylayoutmap::map (int32_t scancode, int32_t *keycode, uint32_t *flags)
The mapping relationship keyedvector<int32_t,key> M_keys Converts the scan code to a key that can be identified andorid the upper layer.
Android Event handling (key, touch screen and scroll ball implementation details)