Android keyboard system code analysis (1)

Source: Internet
Author: User

Open_device function in eventhub. cpp File

In the user State, an open_device function closely related to the kernel state is located in the eventhub. cpp file. This function has a large number of underlying operations to complete upper-layer hardware operations. The first part of the function is:

Int eventhub: open_device (const char * devicename)

The parameters are obtained by the scan_dir () function. Here, devicename = "/dev/input/event0"



For (attempt = 0; attempt <10; attempt ++ ){

FD = open (devicename, o_rdwr );

If (FD> = 0) break;

Usleep (100 );

}

This loop gives the system 10 chances to open the device. If it fails, it will continue to try again after 100usec.

---

If (IOCTL (FD, eviocgversion, & version ))

If (IOCTL (FD, eviocgid, & ID ))

If (IOCTL (FD, eviocgname (sizeof (name)-1), & name) <1)

Obtain the driver version number, ID number, and device name through the ioctl interface.



List <string8 >:: iterator iter = Mexico cludeddevices. Begin ();

List <string8 >:: iterator end = mexcludeddevices. End ();

For (; iter! = End; ITER ++ ){

Const char * test = * ITER;

If (strcmp (name, test) = 0 ){

Logi ("ignoring event ID % s driver % s/n", devicename, test );

Close (FD );

FD =-1;

Return-1;

}

}

Check whether the device execution column is changed. If the device name in the list is the same as that obtained in the previous step (the device has been enabled), disable the device.



If (IOCTL (FD, eviocgphys (sizeof (location)-1), & location) <1)

If (IOCTL (FD, eviocguniq (sizeof (idstr)-1), & idstr) <1)


Int devid = 0;

If (devid> = mnumdevicesbyid) {// mnumdevicesbyid is initialized to 0 in the constructor;

// The following content will be executed;

Device_ent * new_devids = (device_ent *) realloc (mdevicesbyid,

Sizeof (mdevicesbyid [0]) * (devid + 1 ));

If (new_devids = NULL ){

LogE ("out of memory ");

Return-1;

}



Mdevicesbyid [devid]. seq = (mdevicesbyid [devid]. seq + (1 <seq_shift) & seq_mask;


Device_t * Device = new device_t (devid | mdevicesbyid [devid]. seq, devicename, name );

When a new device_t is added, the following parameters are transmitted:

Eventhub: device_t (int32_t _ id, const char * _ path, const char * name)

: ID (_ id), path (_ path), name (name), classes (0)

, Keybitmask (null), layoutmap (New keylayoutmap (), next (null ){

}

The layoutmap is initialized to: New keylayoutmap (). Therefore, the keylayoutmap ();


IOCTL (FD, eviocgbit (ev_key, sizeof (key_bitmask), key_bitmask)> = 0)

Use the ioctl interface to obtain the keyboard mask.



Const char * root = getenv ("android_root ");

Snprintf (keylayoutfilename, sizeof (keylayoutfilename ),

"% S/usr/keylayout/% S. KL", root, tmpfn );

Bool defaultkeymap = false;

If (access (keylayoutfilename, r_ OK )){

Snprintf (keylayoutfilename, sizeof (keylayoutfilename ),

"% S/usr/keylayout/% s", root, "qwerty. KL ");

Defaultkeymap = true;

}

Device-> layoutmap-> load (keylayoutfilename );

This code is used to load the keyboard layout file. By

Snprintf (keylayoutfilename, sizeof (keylayoutfilename )......

The keylayoutfilename is related to tmptn. It can be seen from strcpy (tmpfn, name); tmptn = Name. In the previous ioctl interface, the device name has been obtained. Name = qwerty2 can be known from the simulator startup log. If access (keylayoutfilename, r_ OK) is false, the default layout file Qwerty. KL is used.




Device-> layoutmap-> load (keylayoutfilename );

Next, load the keyboard layout file.


After entering the load function, we can see the file loading process clearly.

Int FD = open (filename, o_rdonly); // open the file

Off_t Len = lseek (FD, 0, seek_end); // get the object Length

Char * Buf = (char *) malloc (LEN + 1); // open a buffer for reading files

If (read (FD, Buf, Len )! = Len) // read the file content to the buffer

Buf [Len] = '/0' // indicates the end of the file



Int line = 1;

Char const * P = Buf;

Enum {begin, scancode, keycode, flag} state = begin;

While (true ){

String8 token = next_token (& P, & line );

The first statement to enter this endless loop is string8 token = next_token (& P, & line), and the return value of this function is: Return string8 (begin, end-begin ); from the string8 constructor, we know what next_token returns:

String8: string8 (const char16_t * o, size_t Len)

: Mstring (allocfromutf16 (O, Len )){}

We can see that the string8 constructor initializes a String constant (const char * mstring ;)

This string constant will be used later:

Scancode = strtol (token. String (), & End, 0 );

Because the prototype of the token. String function is;

Inline const char * string8: string () const

{

Return mstring;

}



All of the above operations on the underlying layer, such:

FD = open (devicename, o_rdwr );

If (IOCTL (FD, eviocgversion, & version ))

Not directly operate the keyboard driver, but the event processing driver. That is to say, the event processing driver encapsulates the keyboard driver.

Next, we will analyze the underlying DRIVER:

Keyboard driver function goldfish_events.c

Input core driver function input. c

Event Processing driver function evdev. c

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.