AndroidN新增物理按键[android7.1.2][msm8953]

1.概述

本文基于qcom msm8953 android7.1.2平台,最近硬件改版需要新增一个MODE的按键,目的是发送一个广播供用户层使用。

2.实现(由下往上->(kernel->frameworks))

先列举下该功能实现所涉及到的文件
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注册gpio_key 上报的key_value

1.找到平台对应内核dtsi配置文件。我这里是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>;  //驱动上报的值,该值是新增,默认没有,该值不是frameworks中keyevents中的值,具体后面说明
+			gpio-key,wakeup;
+			debounce-interval = <15>;
 		};
 	};

2.新增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 frameworks native层转换 kernel上报的key value值

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*/

完成这两步后,驱动上报的key value值249经过frameworks native层的处理到frameworks java层就会是我们在keyevent中得到的值了,这里不研究是怎么处理的。留个坑,后面分析Android input的时候再补上。

2.3 frameworks java层 配置keyevent 值,并且修改gpio_keys.kl映射文件

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:这里说明下怎么找到本平台对应使用的kl文件?
1.可以先确定key在kernel注册的是什么节点(如果知道,可直接略过)
cat proc/bus/input/devices 可以查看
简单点:直接getevent 按按钮就知道是哪个,如图:
AndroidN新增物理按键[android7.1.2][msm8953]
2.查看对应kl文件 dumpsys input | grep “gpio-keys”
AndroidN新增物理按键[android7.1.2][msm8953]

2.4 frameworks java层根据keyevent事件处理新增按键事件

这里实现方式是可变多样的,可自行调整

+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 实现功能 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);
     }
 
+    // 执行命令并且输出结果
+    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.总结

若单纯的只是对Android input 做些简单的修修补补,add new 之类的操作,想必是很简单的,但我们能这样简单轻松的在Android input中做些简单的新增就能实现我们想要的功能,这肯定是离不开Android系统内部对input的实现的,本文这里不对Android input作分析,留个坑给自己,后面分析input再来补上。
ps:本文好像留了两个坑,这里统计下。

4.参考

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

上一篇:Codeforces Round #767 (Div. 2)


下一篇:转:js监控键盘大小写事件