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 按按钮就知道是哪个,如图:
2.查看对应kl文件 dumpsys input | grep “gpio-keys”
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