Mtk hardware startup to disable Bluetooth: mtk hardware ScanCode and keycode application example, mtkscancode
Project requirements: Because android5.0 is not used in this project, a third-party module is required to enable bluetooth audio slave. The third-party module is controlled through GPIO on the android motherboard. The UI enables or disables the Bluetooth search function by selecting a graph or pressing a kpd combination.
1. User button Detection:
Standard behavior, user's combination of buttons, inside the kernel sends scancode to the upper layer, and then the framework converts scancode to keyevent of keycode, which will be accepted and processed by PhoneWindows.
For mtk, keys to keycode have been encapsulated. The encapsulated tool is dct.
For example, if the key of our project combination is KCOL2 + KROW1, we can select our configuration in the graphic tool.
In the example, we set the keycode of this case to SYM.
Of course, you can also define a new keycode by yourself. If it is too troublesome for me, You can directly use the ready-made key. For how to define a new key, see the appendix:
2. detects the user's key-pressing behavior and sends the corresponding intent
The above keycode was received by PhoneWindowManager. java before being sent to various windows. There is a method in it:
@ Override
Public intinterceptKeyBeforeQueueing (KeyEvent event, int policyFlags, booleanisScreenOn ){
Looking at the name, we can see the role of this function. We intercept the following in the Code:
If (keyCode = KeyEvent. KEYCODE_SYM ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button action! ");
If (down ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button down! ");
}
If (up ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button up! ");
}
Return 1;
}
Of course, KEYCODE_SYM is the keycode defined in the original system. It is actually the choice of the input method. We need to block this function, in alps/frameworks/base/core/java/android/view/inputmethod/InputMethodManager. java:
/**
* @ Hide
*/
Public voiddispatchKeyEvent (Context context, int seq, KeyEvent key,
FinishedEventCallback callback ){
Booleanhandled = false;
/* Zcfdebug -- <
Synchronized (mH ){
If (DEBUG) Log. d (TAG, "dispatchKeyEvent ");
If (mCurMethod! = Null ){
If (key. getAction () = KeyEvent. ACTION_DOWN
& Key. getKeyCode () = KeyEvent. KEYCODE_SYM ){
ShowInputMethodPickerLocked ();
Handled = true;
} Else {
Try {
If (DEBUG) Log. v (TAG, "dispatch key:" + mCurMethod );
Final long startTime = SystemClock. uptimeMillis ();
EnqueuePendingEventLocked (startTime, seq, mCurId, callback );
MCurMethod. dispatchKeyEvent (seq, key, mInputMethodCallback );
Return;
} Catch (RemoteException e ){
Log. w (TAG, "IME died:" + mCurId + "dropping:" + key, e );
}
}
}
}
Zcfdebug --> */
Callback. finishedEvent (seq, handled );
}
Just comment out the original functions.
According to our project definition, press the button for 3-5 seconds to turn on the search function for the Bluetooth Status Power, and press for more than 8 seconds to turn off. When it is disabled, there is no action when you press for 8 seconds.
If (keyCode = KeyEvent. KEYCODE_SYM ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button action! ");
If (down ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button down! ");
// LastSymKeyDownTime = System. currentTimeMillis ();
LastSymKeyDownTime = event. getEventTime ();
}
If (up ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button up! ");
SymKeyPressTime = event. getEventTime ()-lastSymKeyDownTime;
// SymKeyPressTime = System. currentTimeMillis ()-lastSymKeyDownTime;
Log. e ("zcfdebug", "theSymKeyPressTime is" + SymKeyPressTime );
If (SymKeyPressTime> 2000 & SymKeyPressTime <5000 ){
Log. e ("zcfdebug", "nowwe catch the bluetooth press 3 second! ");
}
If (SymKeyPressTime> 7000 ){
Log. e ("zcfdebug", "nowwe catch the bluetooth press 8 second! ");
}
}
Return 1;
}
The Bluetooth switch and other actions are implemented in the apk program outside. We only need to send the intent implementation and the code is as follows:
If (keyCode = KeyEvent. KEYCODE_SYM ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button action! ");
If (down ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button down! ");
// LastSymKeyDownTime = System. currentTimeMillis ();
LastSymKeyDownTime = event. getEventTime ();
}
If (up ){
Log. e ("zcfdebug", "nowwe catch the bluetooth button up! ");
SymKeyPressTime = event. getEventTime ()-lastSymKeyDownTime;
// SymKeyPressTime = System. currentTimeMillis ()-lastSymKeyDownTime;
Log. e ("zcfdebug", "theSymKeyPressTime is" + SymKeyPressTime );
If (SymKeyPressTime> 2000 & SymKeyPressTime <5000 ){
Log. e ("zcfdebug", "nowwe catch the bluetooth press 3 second! ");
Intent btStartStopIntent = new Intent (BT_STARTSTOP );
MContext. sendBroadcast (btStartStopIntent );
}
If (SymKeyPressTime> 7000 ){
Log. e ("zcfdebug", "nowwe catch the bluetooth press 8 second! ");
Intent btPairIntent = new Intent (BT_PAIR );
MContext. sendBroadcast (btPairIntent );
}
}
Return 1;
}
How the application receives and processes intent will be described in the next article
Appendix: Howto add a new key on android ICS \ ICS2:
[Description]
How to add a new keyon android ICS/ICS2
[Solution]
1. Add the new button option to the DCTtool keypad list file.
Add a new key to alps \ mediatek \ source \ dct \ Keypad_YuSu.cmp, such as the SMS shortcut key
KEY_SYM
KEY_SMS
KEY_0
2. Enable DCTtool and add a new key, such as SMS, in the corresponding key bit in the keypad matrix. Then Save
3. Modify the input. h file of the linux keyboard code.
Since preloader \ uboot \ kernel \ factory is used separately, the input. h In the corresponding file path should be modified.
Add a key value for the new button
Kernel \ include \ linux \ input. h
Bionic \ libc \ kernel \ common \ linux \ input. h
External \ kernel-headers \ original \ linux \ input. h
External \ qemu \ linux_keycodes.h
Mediatek \ plaform \ mt6575 \ preloader \ src \ drivers \ inc \ linux \ input. h
Mediatek \ plaform \ mt6575 \ uboot \ inc \ linux \ input. h
For example, KEY_SMS
# Define KEY_SMS 252
4. Added keypadlayout file keyboard ing, linux and androidkey ing
Mediatek \ config \ <projectname> \ mt6575-kpd.kl
For example:
Key 252 SMS
Among them, 252 is the linux key code, and SMS is the key value recognized by android. If you need to WAKE up the system, you also need to add WAKE
If the new button is an uncommon character on the keyboard, modify: mediatek \ config \ <project name> \ mt6575-kpd.kcm
5. Modify the keycode for Java Recognition
Framework/base/include/ui/KeyCodelabels. h
Added after the KEYCODES Data Structure
{"SMS", 220}
Framework/base/native/include/android/KeyCodes. h
Add AKEYCODE_SMS = 220 to the key definition;
6. Modify Java Keyboard Events
Framework/base/core/java/android/view/keyevent. java
/**
* @ Hide
*/
Public static finalint KEYCODE_SMS = 220;
The last button is the newly added
Private static finalint LAST_KEYCODE = KEYCODE_SMS;
The above/**/annotated code is android non-open API or variable definition, you need to add JavaDoc recognition, otherwise you need to run
Line makeupdate-api can be built
For system buttons, modify framework/base/libs/ui/input. cpp.
Added caseAKEYCODE_SMS for isSystemKey:
7. Modify the XML file descriptor framework/base/core/res/values/attr. xml
<Enumname = "KEYCODE_SMS" value = "220"/>
8. added the test verification log in android
Framework \ base \ policy \ src \ com \ android \ internal \ polidy \ impl \ phoneWindowManager. java
Added in interceptKeyBeforeDispatching ()
If (keycode = KeyEvent. KEYCODE_SMS ){
Log. d (TAG, "interceptKeyTi KEYCODE_SMS keyCode =" + keyCode + "down =" + down +"
RepeatCount = "+ repeatCount +" keyguardOn = "+ keyguardOn +" mHomePressed = "+
9. Check the log or add the test APK.
Kernal log:
<4> [1, 253.828234] kpd: register = fffe ffff
<4> [1, 253.828825] kpd :( pressed) HW keycode = 0
<4> [253.829348] kpd: report Linux keycode = 252
<4> [1, 253.829857] kpd: save new keymap state
<4> [1, 254.030814] kpd: register = ffff
<4> [1, 254.031405] kpd :( released) HW keycode = 0
<4> [254.031936] kpd: report Linux keycode = 252
<4> [1, 254.032445] kpd: save new keymap state
Android log:
WindowManager: interceptKeyTq keycode = 220 screenIsOn = true keyguardActive = false
PolicyFlags = #2000000 down = false canceled = false
D WindowManager: interceptKeyTi keyCode = 220 down = false repeatCount = 0 keyguardOn = false
MHomePressed = falsecanceled = false
D WindowManager: interceptKeyTi KEYCODE_SMS keyCode = 220 down = false repeatCount = 0
KeyguardOn = falsemHomePressed = false canceled = false