Modify mouse buttons in Android framework

Source: Internet
Author: User

This is a problem encountered in actual work: you can modify the left, middle, and right button functions on the mouse in settings. There are four functions: Left click, right click, menu key and return key. The correspondence between buttons and functions can be stored using system properties, and the setting interface can be completed using radiobutton. There is nothing to say about this. Next, we should record how the mouse buttons change the function. Before that, let's review the basic knowledge-the process for handling input events.


The key values passed from the kernel are transcoded by eventhub, and then interpreted as events by inputreader, and then distributed by inputdispatcher. Inputmanager is the creator of inputreader and inputdispatcher threads. It has only one role, that is, it is used by windowmanagerservice to obtain key events from the native layer. Windowmanagerservice is responsible for interfacing with windows and distributing key messages. There are many articles about how to handle button events in detail. I will not repeat them here. Record the source code location and take a look at it later:


Event distribution to the frontend window:

/Frameworks/base/services/Java/COM/Android/Server/windowmanagerservice. Java

Message interception processing class:
/Frameworks/base/policy/src/COM/Android/Internal/policy/impl/phonewindowmanager. Java

Key event definition:
/Frameworks/base/CORE/Java/Android/View/keyevent. Java

Java layer input management:
/Frameworks/base/services/Java/COM/Android/Server/inputmanager. Java

Native layer input management:
/Frameworks/base/libs/UI/inputmanager. cpp

Event reading thread:
/Frameworks/base/libs/UI/inputreader. cpp

Event distribution thread:
/Frameworks/base/libs/UI/inputdispatcher. cpp

Key code and key value conversion:
/Frameworks/base/libs/UI/eventhub. cpp

After analyzing the processing process, we can find that the function corresponding to the mouse button needs to be modified. We should start with inputreader-What happened was determined by inputreader, and rawevent is only responsible for dropping the code value, inputdispatcher is only responsible for conveying the event translated by inputreader. We asked inputreader to lie and say the left-click event as the right-click event, and the right-click event as the intermediate key event. Isn't it done?


After recording the thinking process, we have found a solution to the problem. The following describes how to counter inputreader:


Int mmousekeysettingsupport = 1; // indicates whether the mouse key is set. If the mouse key is set, the value 1 indicates that the mouse key is set and the value 0 indicates that the mouse key is set. It can be read from the attribute. The read process is directly set to 1. static bool ispointerdown (int32_t buttonstate) {If (mmousekeysettingsupport) {// This function is used to determine whether a pointer is pressed. For example, clicking the left mouse button or right-click is a click event. Because amotion_event_button_tertiary needs to be used as the menu key, cancel it as a click. Return buttonstate & (Response | response) ;}else {return buttonstate & (Response | response) ;}} static void synthesizebuttonkeys (inputreadercontext * context, int32_t action, nsecs_t when, int32_t DeviceID, uint32_t source, uint32_t policyflags, int32_t lastbuttonstate, int32_t currentbutton State) {combine (context, action, when, DeviceID, source, policyflags, lastbuttonstate, currentbuttonstate, callback, akeycode_back); synthesizebuttonkey (context, action, when, DeviceID, source, policyflags, lastbuttonstate, currentbuttonstate, amotion_event_button_forward, akeycode_forward); // supports the menu key if (mmousekeysettingsupport) {synthesizebuttonkey (context, action, when, Device ID, source, policyflags, lastbuttonstate, currentbuttonstate, amotion_event_button_tertiary, akeycode_menu) ;}// The following is the key ing function, which is used to read the system property to obtain the corresponding function Enum {mouse_btn, iterator, iterator, iterator}; Enum {mouse_key_click = 0, mouse_key_menu, mouse_key_back, mouse_key_right, mouse_key_num}; iterator usage: getbuttonmapvalue (uint32_t key) const {If (Key> = keys) {return 0;} const char * properties [] = {"persist. SYS. mouse. BTN. left "," persist. SYS. mouse. BTN. middle "," persist. SYS. mouse. BTN. right "}; const struct stmousebtnfunc {char propvalue [16]; uint32_t func;} functions [] ={{" click ", amotion_event_button_primary}, {" menu ", comment }, {"back", amotion_event_button_back}, {"right", amotion_event_button_secondary }}; uint32_t defaultfunc [] = {amotion_event_butto N_primary, keys, amotion_event_button_back}; const char * unkonw_keyvalue = "unknow"; char * propvalue = new char [16]; property_get (properties [Key], propvalue, unkonw_keyvalue ); if (strcmp (propvalue, unkonw_keyvalue )! = 0) {for (INT I = 0; I <mouse_key_num; I ++) {If (strcmp (propvalue, functions [I]. propvalue) = 0) {return functions [I]. func ;}}return defaultfunc [Key];} // steal a column. Use getbuttonmapvalue to obtain the uint32_t cursorbuttonaccumulator: getbuttonstate () const {uint32_t result = 0; if (mbtnleft) {If (mmousekeysettingsupport) {result | = getbuttonmapvalue (mouse_btn_left); // left click} else {result | = amotion_event_button_primary;} alogd ("getbuttonstate. result = % d. ", result);} If (mbtnok1 | mbtnok2) {result | = amotion_event_button_primary;} If (mbtnright) {result | = amotion_event_button_back; // result | = success ;} if (mbtnmiddle) {If (mmousekeysettingsupport) {result | = getbuttonmapvalue (mouse_btn_middle); // intermediate key} else {result | = success;} alogd ("getbuttonstate. result = % d. ", result);} If (mbtnback | mbtnside) {If (mmousekeysettingsupport) {result | = getbuttonmapvalue (mouse_btn_right); // right-click} else {result | = amotion_event_button_back ;}} if (mbtnforward | mbtnextra) {result | = amotion_event_button_forward;} return result ;}


If you are familiar with the input message processing process in the framework, implementing the function is a simple process. If you have no clue when you encounter a problem, you may first understand the knowledge of the surrounding area before looking for a solution. The ability to solve a problem is far more important than solving the problem itself.


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.