AndroidN adds physical keys [android7.1.2][msm8953]

Posted by samshel on Mon, 12 Aug 2019 04:01:06 +0200

1. Overview

Based on the qcom msm8953 Android 7.1.2 platform, a new MODE key is required for the latest hardware modification in order to send a broadcast for the user layer to use.

2. Implementation (from bottom to top-> (kernel->frameworks))

First list the files involved in the implementation of this function
device/qcom/msm8953_64/gpio-keys.kl
frameworks/base/core/java/android/view/KeyEvent.java
frameworks/base/core/res/res/values/attrs.xml
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
frameworks/native/include/android/keycodes.h b/include/android/keycodes.h
frameworks/native/include/input/InputEventLabels.h
kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi
kernel/msm-3.18/include/uapi/linux/input.h

2.1 kernel registers key_value reported by gpio_key

1. Find the platform corresponding kernel dtsi configuration file.I'm here kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi

diff --git a/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi b/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi
index 87c248f..254b677 100755
--- a/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi
+++ b/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi
@@ -288,13 +288,24 @@
 			debounce-interval = <15>;
 		};*/
+		//key mode 249
+		mode_button {
+			label = "mode_button";
+			gpios = <&tlmm 33 0x1>;
+			linux,input-type = <1>;
+			linux,code = <249>;  //The value reported by the driver, which is newly added and not by default, is not the value in keyevents in frameworks, as explained later
+			gpio-key,wakeup;
+			debounce-interval = <15>;
 		};
 	};

2. Add key value
kernel/msm-3.18/include/uapi/linux/input.h

+#define KEY_SYSTEM_MODE		249	/*add by hogo@wmz for system_key_mode 20190805 */

2.2 Framework native layer transforms the key value reported by kernel s

frameworks/native/include/android/keycodes.h b/include/android/keycodes.h

+    /** fingerprint mode key, mode. */
+    AKEYCODE_SYSTEM_KEY_MODE = 284

frameworks/native/include/input/InputEventLabels.h

+    DEFINE_KEYCODE(SYSTEM_KEY_MODE), /*add by hogo@wmz for mode key 20190805*/

After completing these two steps, the key value 249 reported by the driver is processed by the frameworks native layer to the frameworks java layer, which is what we get in the keyevent. We will not study how to handle it here.Leave a hole and fill it later when you analyze Android input.

2.3 frameworks java layer configures keyevent values and modifies the gpio_keys.kl mapping file

frameworks/base/core/res/res/values/attrs.xml

+	<!--add by hogo@wmz for mode key 20190805 -->
+        <enum name="KEYCODE_SYSTEM_KEY_MODE" value="284" />

frameworks/base/core/java/android/view/KeyEvent.java

+    /** fingerprint mode key, mode. */
+    AKEYCODE_SYSTEM_KEY_MODE = 284

device/qcom/msm8953_64/gpio-keys.kl

+#add by hogo@wmz for mode key 20190805
+key 249	  SYSTEM_KEY_MODE

ps: How can I find the kl file for this platform?
1. You can first determine which node the key registers with the kernel (skip it if you know it)
cat proc/bus/input/devices can be viewed
Simple point: Just press the button directly to get tevent to know which one is, as shown in the figure:

2. View the corresponding kl file dumpsys input | grep "gpio-keys"

2.4 Framework KS Java layer handles new key events based on keyevent events

The implementation here is variable and self-adjustable

+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;

+	    //add by hogo@wmz for mode key 20190805
+            case KeyEvent.KEYCODE_SYSTEM_KEY_MODE: {
+                result &= ~ACTION_PASS_TO_USER;
+		if(down)
+		{
+	            	//Slog.e(TAG, "if ");
+		}
+		else
+		{
+	            	//Slog.e(TAG, "else ");
+			Intent intent = new Intent(ACTION_ENG_MODE_SWITCH);
+			mContext.sendBroadcast(intent);
+			//mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+			//mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
+                            //null, null, null, 0, null, null);			
+		}
+                break;
+            }

2.5 Overview of implementing git diff

project device/
diff --git a/qcom/msm8953_64/gpio-keys.kl b/qcom/msm8953_64/gpio-keys.kl
index 0e02155..ced3ca5 100755
--- a/qcom/msm8953_64/gpio-keys.kl
+++ b/qcom/msm8953_64/gpio-keys.kl
@@ -25,9 +25,12 @@
 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#key 115   VOLUME_UP
+key 115   VOLUME_UP
 key 114   VOLUME_DOWN
-#key 102   HOME
+key 102   HOME
 key 528   FOCUS
 key 766   CAMERA
 key 158	  BACK
+
+#add by hogo@wmz for mode key 20190805
+key 249	  SYSTEM_KEY_MODE
project frameworks/base/
diff --git a/api/current.txt b/api/current.txt
old mode 100644
new mode 100755
index 3466b04..95ac6f3
--- a/api/current.txt
+++ b/api/current.txt
@@ -41602,6 +41602,7 @@ package android.view {
     field public static final int KEYCODE_SWITCH_CHARSET = 95; // 0x5f
     field public static final int KEYCODE_SYM = 63; // 0x3f
     field public static final int KEYCODE_SYSRQ = 120; // 0x78
+    field public static final int KEYCODE_SYSTEM_KEY_MODE = 284; // 0x11c
     field public static final int KEYCODE_SYSTEM_NAVIGATION_DOWN = 281; // 0x119
     field public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282; // 0x11a
     field public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283; // 0x11b
diff --git a/api/system-current.txt b/api/system-current.txt
index 2f5cb2f..761c0b0 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -44780,6 +44780,7 @@ package android.view {
     field public static final int KEYCODE_SWITCH_CHARSET = 95; // 0x5f
     field public static final int KEYCODE_SYM = 63; // 0x3f
     field public static final int KEYCODE_SYSRQ = 120; // 0x78
+    field public static final int KEYCODE_SYSTEM_KEY_MODE = 284; // 0x11c
     field public static final int KEYCODE_SYSTEM_NAVIGATION_DOWN = 281; // 0x119
     field public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282; // 0x11a
     field public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283; // 0x11b
diff --git a/api/test-current.txt b/api/test-current.txt
index 77e36ab..0f5154d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -41688,6 +41688,7 @@ package android.view {
     field public static final int KEYCODE_SWITCH_CHARSET = 95; // 0x5f
     field public static final int KEYCODE_SYM = 63; // 0x3f
     field public static final int KEYCODE_SYSRQ = 120; // 0x78
+    field public static final int KEYCODE_SYSTEM_KEY_MODE = 284; // 0x11c
     field public static final int KEYCODE_SYSTEM_NAVIGATION_DOWN = 281; // 0x119
     field public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282; // 0x11a
     field public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283; // 0x11b
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index b73acda..1c1a4e3 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -804,8 +804,10 @@ public class KeyEvent extends InputEvent implements Parcelable {
     public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282;
     /** Key code constant: Consumed by the system for navigation right */
     public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283;
+    /** Key code constant: Consumed by the system for mode key add by hogo@wmz 20190805 */
+    public static final int KEYCODE_SYSTEM_KEY_MODE = 284;
 
-    private static final int LAST_KEYCODE = KEYCODE_SYSTEM_NAVIGATION_RIGHT;
+    private static final int LAST_KEYCODE = KEYCODE_SYSTEM_KEY_MODE;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
@@ -1857,6 +1859,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
             case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN:
             case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
             case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT:
+            case KeyEvent.KEYCODE_SYSTEM_KEY_MODE:
                 return true;
         }
 
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 066a538..7112b75 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1839,6 +1839,8 @@ i
         <enum name="KEYCODE_SYSTEM_NAVIGATION_DOWN" value="281" />
         <enum name="KEYCODE_SYSTEM_NAVIGATION_LEFT" value="282" />
         <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
+	<!--add by hogo@wmz for mode key 20190805 -->
+        <enum name="KEYCODE_SYSTEM_KEY_MODE" value="284" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 33e20a8..a167a1d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -161,6 +161,9 @@ import java.io.PrintWriter;
 import java.util.HashSet;
 import java.util.List;
 
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 /**
  * WindowManagerPolicy implementation for the Android phone UI.  This
  * introduces a new method suffix, Lp, for an internal lock of the
@@ -3503,7 +3506,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                 dispatchDirectAudioEvent(event);
                 return -1;
             }
-        }
+        } 
+	//add by hogo@wmz for mode key 20190805
+	/*else if(keyCode == KeyEvent.KEYCODE_SYSTEM_KEY_MODE)
+	{
+		execRootCmd("am broadcast -a android.intent.action.ENG_MODE_SWITCH");
+		return -1;
+	}*/
 
         // Toggle Caps Lock on META-ALT.
         boolean actionTriggered = false;
@@ -5798,6 +5807,49 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         mContext.sendBroadcastAsUser(errorIntent, UserHandle.CURRENT);
     }
 
+    // Execute commands and output results
+    public String execRootCmd(String cmd) {
+        String result = "";
+        DataOutputStream dos = null;
+        DataInputStream dis = null;
+
+        try {
+            java.lang.Process p = Runtime.getRuntime().exec("su");
+            dos = new DataOutputStream(p.getOutputStream());
+            dis = new DataInputStream(p.getInputStream());
+
+            dos.writeBytes(cmd + "\n");
+            dos.flush();
+            dos.writeBytes("exit\n");
+            dos.flush();
+            String line = null;
+            while ((line = dis.readLine()) != null) {
+                result += line;
+            }
+            p.waitFor();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (dos != null) {
+                try {
+                    dos.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (dis != null) {
+                try {
+                    dis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return result;
+    }
+
+    int cnt = 0;
+
     /** {@inheritDoc} */
     @Override
     public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
@@ -5811,6 +5863,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         final boolean canceled = event.isCanceled();
         final int keyCode = event.getKeyCode();
 
+	//wmz
+	/*if(KeyEvent.KEYCODE_VOLUME_DOWN == keyCode)
+	{
+		cnt++;
+		if(cnt == 2)
+		{
+			execRootCmd("am broadcast -a android.intent.action.ENG_MODE_SWITCH");
+			cnt = 0;
+		}
+		return 0;
+	}*/
+
         final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
 
         // If screen is off then we treat the case where the keyguard is open but hidden
@@ -5884,6 +5948,21 @@ public class PhoneWindowManager implements WindowManagerPolicy {
 
         // Handle special keys.
         switch (keyCode) {
+	    //add by hogo@wmz for mode key 20190805
+            case KeyEvent.KEYCODE_SYSTEM_KEY_MODE: {
+                result &= ~ACTION_PASS_TO_USER;
+		if(down)
+		{
+	            	//Slog.e(TAG, "if ");
+		}
+		else
+		{
+	            	//Slog.e(TAG, "else ");
+			Intent intent = new Intent(ACTION_ENG_MODE_SWITCH);
+			mContext.sendBroadcast(intent);
+			//mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+			//mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
+                            //null, null, null, 0, null, null);			
+		}
+                break;
+            }
             case KeyEvent.KEYCODE_BACK: {
                 if (down) {
                     interceptBackKeyDown();
project frameworks/native/
diff --git a/include/android/keycodes.h b/include/android/keycodes.h
index e202060..67a4e63 100644
--- a/include/android/keycodes.h
+++ b/include/android/keycodes.h
@@ -765,7 +765,9 @@ enum {
     /** fingerprint navigation key, left. */
     AKEYCODE_SYSTEM_NAVIGATION_LEFT = 282,
     /** fingerprint navigation key, right. */
-    AKEYCODE_SYSTEM_NAVIGATION_RIGHT = 283
+    AKEYCODE_SYSTEM_NAVIGATION_RIGHT = 283,
+    /** fingerprint mode key, mode. */
+    AKEYCODE_SYSTEM_KEY_MODE = 284
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h
index 0bd14ea..170ef47 100644
--- a/include/input/InputEventLabels.h
+++ b/include/input/InputEventLabels.h
@@ -323,6 +323,7 @@ static const InputEventLabel KEYCODES[] = {
     DEFINE_KEYCODE(SYSTEM_NAVIGATION_DOWN),
     DEFINE_KEYCODE(SYSTEM_NAVIGATION_LEFT),
     DEFINE_KEYCODE(SYSTEM_NAVIGATION_RIGHT),
+    DEFINE_KEYCODE(SYSTEM_KEY_MODE), /*add by hogo@wmz for mode key 20190805*/
 
     { NULL, 0 }
 };

project kernel/
diff --git a/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi b/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi
index 87c248f..254b677 100755
--- a/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi
+++ b/msm-3.18/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi
@@ -288,13 +288,24 @@
 			debounce-interval = <15>;
 		};*/
 
-		back_button {
+		//158 back
+		/*back_button {
 			label = "back_button";
 			gpios = <&tlmm 33 0x1>;
 			linux,input-type = <1>;
 			linux,code = <158>;
 			gpio-key,wakeup;
 			debounce-interval = <15>;
+		};*/
+		
+		//key mode 249
+		mode_button {
+			label = "mode_button";
+			gpios = <&tlmm 33 0x1>;
+			linux,input-type = <1>;
+			linux,code = <249>;
+			gpio-key,wakeup;
+			debounce-interval = <15>;
 		};
 	};
diff --git a/msm-3.18/include/uapi/linux/input.h b/msm-3.18/include/uapi/linux/input.h
index 7082516..be564da 100644
--- a/msm-3.18/include/uapi/linux/input.h
+++ b/msm-3.18/include/uapi/linux/input.h
@@ -481,6 +481,8 @@ struct input_keymap_entry {
 
 #define KEY_MICMUTE		248	/* Mute / unmute the microphone */
 
+#define KEY_SYSTEM_MODE		249	/*add by hogo@wmz for system_key_mode 20190805 */
+
 /* Code 255 is reserved for special needs of AT keyboard driver */
 
 #define BTN_MISC		0x100

3. Summary

Simple patches for Android inputs, add new and so on, would be very simple, but we can do simple additions in Android inputs to achieve the functions we want. This is certainly due to the input implementation within the Android system. Here we goDon't analyze Android input, leave a hole for yourself, and then analyze input to fill in.
ps: There seem to be two pits left in this article. Here's the statistics.

4. Reference

https://blog.csdn.net/weixin_42193691/article/details/82874476
https://blog.csdn.net/dkbdkbdkb/article/details/53667216
https://www.jianshu.com/p/dcd0e030fbf5
https://blog.csdn.net/tt11212/article/details/87608373

Topics: Java Android git Linux