Android event Transfer Mechanism

Source: Internet
Author: User

The driver is loaded during system startup.ProgramInitialize the hardware device and enter the bool eventhub: openplatforminput (void) function. The main function of this function is to scan the/dev/input directory to obtain the input device. How to obtain it? Use the Linux API res = scan_dir (device_path); this function is called

While (DE = readdir (DIR ))){

Strcpy (filename, de-> d_name );

Open_device (devname );

}

Constantly read the directory file and open the device through open_device. The specific function to open the device is FD = open (devicename, o_rdwr). To open the function in read/write mode, this function calls the implementation function in file_operations in the driver.

All input devices are enabled.

 

When the windowmanagerservice service class is running, the internal class keyq object will be created in the constructor. The keyinputqueue class inherited by this class. Of course, you must enter the constructor of this class. In the constructor of the keyinputqueue class, the anonymous internal class thread ("inputdevicereader") is started. The thread reads the driver event and places it in the message queue. The specific implementation is:

 

Thread mthread = new thread ("inputdevicereader "){

Public void run (){

Rawinputevent EV = new rawinputevent ();

While (true ){

Inputdevice di;

Readevent (EV );

}

}

 

This thread continues to run and runs cyclically through readevent (); this function is a native method. The specific implementation is

Static jboolean

Android_server_keyinputqueue_readevent (jnienv * ENV, jobject clazz,

Jobject event)

{

Glock. Lock ();

Sp <eventhub> 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 );

}

The above steps obtain the event queuedevent.

After obtaining the event, pass

 

Private void addlocked (inputdevice device, long when, int flags,

Int classtype, object event ){

Boolean poke = mfirst. Next = mlast;

 

Queuedevent EV = obtainlocked (device, when, flags, classtype, event );

Queuedevent P = mlast. Prev;

While (P! = Mfirst & eV. When <p. When ){

P = P. Prev;

}

Ev. Next = P. Next;

Ev. Prev = P;

P. Next = EV;

Ev. Next. Prev = EV;

Ev. inqueue = true;

}

This function is added to the Message Queue. The message queue is a two-way connection table with the final queuedevent mfirst header and tail respectively;

Final queuedevent mlast; this function inserts a new message before the end.

 

The message queue is available. You also need to read the queue. An internal thread is opened in the windowmanagerservice. Java class at the same time.

Minputthread = new inputdispatcherthread ();

Minputthread. Start ();

 

This thread is parallel to the write queue thread. After the thread gets up

Public void run (){

While (true ){

Try {

Process ();

} Catch (exception e ){

Log. E (TAG, "exception in input dispatcher", e );

}

}

}

This process () function reads messages. The specific implementation is

Private void process (){

Android. OS. process. setthreadpriority (

Android. OS. process. thread_priority_urgent_display );

While (true ){

Queuedevent EV = mqueue. getevent (

(INT )((! Configchanged & curtime <nextkeytime)

? (Nextkeytime-curtime): 0 ));

}

The specific implementation of the getevent () function is

Queuedevent getevent (long timeoutms ){

Long begin = systemclock. uptimemillis ();

Final long end = begin + timeoutms;

Long Now = begin;

Synchronized (mfirst ){

While (mfirst. Next = mlast & End> now ){

Queuedevent P = mfirst. Next;

Mfirst. Next = P. Next;

Mfirst. Next. Prev = mfirst;

P. inqueue = false;

Return P;

}

}

Messages are read continuously. If there is no message, the messages are blocked. If there is a message, the messages are read and referenced. Then, the message is deleted from the two-way connection table. After a message is obtained, the message is sent to a specific AP Based on the device type of the message input. For example

Switch (EV. classtype ){

Case rawinputevent. class_keyboard:

Dispatchkey (keyevent) eV. event, 0, 0 );

Mqueue. recycleevent (EV );

Break;

Case rawinputevent. class_touchscreen:

Dispatchpointer (EV, (motionevent) eV. event, 0, 0 );

Break;

Case rawinputevent. class_trackball:

Dispatchtrackball (EV, (motionevent) eV. event, 0, 0 );

Break;

Case rawinputevent. class_configuration_changed:

Configchanged = true;

Break;

Default:

Mqueue. recycleevent (EV );

Break;

}

 

Of course, this involves a lot of details. If you are interested, please take a look. At the same time, the mutex mechanism of read/write queues is also worth learning.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.