android 发送onkey广播,Android 添加键值并上报从驱动到上层

夏学名
2023-12-01

平台 :RK3288

OS:Android7.1

kernel部分添加键值:

1.在dts中(kernel/arch/arm/boot/dts/rk3288-android.dtsi)添加键值属性,可以仿照power按键配置

wake-key {

gpios = ;

linux,code = <117>;

pinctrl-names = "default";

pinctrl-0 = ;

label = "wake";

gpio-key,wakeup;

};

因我们使用的键值操作是通过gpio触发的,则配置成gpio-key。

linux,code 键码可以查看内核自定义键码来选择。定义在kernel/include/uapi/linux/input-event-codes.h下。

/*

* Event types

*/

#define EV_SYN0x00

#define EV_KEY0x01

#define EV_REL0x02

#define EV_ABS0x03

#define EV_MSC0x04

#define EV_SW0x05

#define EV_LED0x11

#define EV_SND0x12

#define EV_REP0x14

#define EV_FF0x15

#define EV_PWR0x16

#define EV_FF_STATUS0x17

#define EV_MAX0x1f

#define EV_CNT(EV_MAX+1)

/*

* Keys and buttons

*

* Most of the keys/buttons are modeled after USB HUT 1.12

* (see http://www.usb.org/developers/hidpage).

* Abbreviations in the comments:

* AC - Application Control

* AL - Application Launch Button

* SC - System Control

*/

#define KEY_RIGHTALT100

#define KEY_LINEFEED101

#define KEY_HOME102

#define KEY_UP103

#define KEY_PAGEUP104

#define KEY_LEFT105

#define KEY_RIGHT106

#define KEY_END107

#define KEY_DOWN108

#define KEY_PAGEDOWN109

#define KEY_INSERT110

#define KEY_DELETE111

#define KEY_MACRO112

#define KEY_MUTE113

#define KEY_VOLUMEDOWN114

#define KEY_VOLUMEUP115

#define KEY_POWER116/* SC System Power Down */

#define KEY_KPEQUAL117

#define KEY_KPPLUSMINUS118

#define KEY_PAUSE119

#define KEY_SCALE120/* AL Compiz Scale (Expose) */

#define KEY_KPCOMMA121

#define KEY_HANGEUL122

#define KEY_HANGUELKEY_HANGEUL

#define KEY_HANJA123

#define KEY_YEN124

#define KEY_LEFTMETA125

#define KEY_RIGHTMETA126

#define KEY_COMPOSE127

#define KEY_STOP128/* AC Stop */

#define KEY_AGAIN129

#define KEY_PROPS130/* AC Properties */

#define KEY_UNDO131/* AC Undo */

#define KEY_FRONT132

#define KEY_COPY133/* AC Copy */

#define KEY_OPEN134/* AC Open */

#define KEY_PASTE135/* AC Paste */

#define KEY_FIND136/* AC Search */

#define KEY_CUT137/* AC Cut */

#define KEY_HELP138/* AL Integrated Help Center */

#define KEY_MENU139/* Menu (show menu) */

#define KEY_CALC140/* AL Calculator */

#define KEY_SETUP141

#define KEY_SLEEP142/* SC System Sleep */

#define KEY_WAKEUP143/* System Wake Up */

#define KEY_FILE144/* AL Local Machine Browser */

#define KEY_SENDFILE145

#define KEY_DELETEFILE146

#define KEY_XFER147

#define KEY_PROG1148

#define KEY_PROG2149

#define KEY_WWW150/* AL Internet Browser */

#define KEY_MSDOS151

#define KEY_COFFEE152/* AL Terminal Lock/Screensaver */

#define KEY_SCREENLOCKKEY_COFFEE

#define KEY_ROTATE_DISPLAY153/* Display orientation for e.g. tablets */

#define KEY_DIRECTIONKEY_ROTATE_DISPLAY

#define KEY_CYCLEWINDOWS154

#define KEY_MAIL155

#define KEY_BOOKMARKS156/* AC Bookmarks */

#define KEY_COMPUTER157

#define KEY_BACK158/* AC Back */

#define KEY_FORWARD159/* AC Forward */

#define KEY_CLOSECD160

#define KEY_EJECTCD161

#define KEY_EJECTCLOSECD162

#define KEY_NEXTSONG163

#define KEY_PLAYPAUSE164

#define KEY_PREVIOUSSONG165

#define KEY_STOPCD166

#define KEY_RECORD167

#define KEY_REWIND168

#define KEY_PHONE169/* Media Select Telephone */

#define KEY_ISO170

#define KEY_CONFIG171/* AL Consumer Control Configuration */

#define KEY_HOMEPAGE172/* AC Home */

#define KEY_REFRESH173/* AC Refresh */

#define KEY_EXIT174/* AC Exit */

因键值较多,就只列一部分出来,在定义键码的时候,注意不要与现正在使用的键码重复。如不确认哪些键码是已经使用的,可以在该文件中添加自定义键码。

在dts中添加键值属性后,需要在驱动(我的是在/kernel/drivers/input/keyboard/rk_reys.c)里,做dts解析:

/* parse info from dt */

ddata->nbuttons = key_num;

error = rk_keys_parse_dt(ddata, pdev);

if (error)

goto fail0;

如该按键需要以中断的方式触发,则可以为这个按键申请中断:

error =devm_request_irq(dev, irq, keys_isr1,

IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,

button->desc ? button->desc:"wake",button);

键值上报:

1.注册input事件:

通过input_register_device()函数来向内核注册input事件。

2.input事件上报:

input事件上报是通过input_event()或input_report_key()函数上报。

input_event()函数简介:

函数原型:

void input_event(struct input_dev *dev,

unsigned int type, unsigned int code, int value)

{

unsigned long flags;

if (is_event_supported(type, dev->evbit, EV_MAX))

{

spin_lock_irqsave(&dev->event_lock, flags);

add_input_randomness(type, code, value);

input_handle_event(dev, type, code, value);

spin_unlock_irqrestore(&dev->event_lock, flags);

}

}

EXPORT_SYMBOL(input_event);

参数介绍:

struct input_dev *dev:需要上报的事件

unsigned int type:上报的事件类型(在前面的input-event-codes.h文件中有定义)

unsigned int code:上报的键码

int value :上报的键值

使用实例:

static irqreturn_t keys_isr1(int irq, void *dev_id)

{

struct rk_keys_button *button = (struct rk_keys_button *)dev_id;

struct rk_keys_drvdata *pdata = dev_get_drvdata(button->dev);

struct input_dev *input = pdata->input;

int irq_status = gpio_get_value(14);

if (0==irq_status){ //插入就触发中断,,拔出来也触发中断。

input_event(input, EV_KEY, 118, 1);

input_sync(input);

udelay(50);

input_event(input, EV_KEY, 118, 0);

input_sync(input);

}

else if (1==irq_status){

input_event(input, EV_KEY, 117, 1);

input_sync(input);

udelay(50);

input_event(input, EV_KEY, 117, 0);

input_sync(input);

}

return IRQ_HANDLED;

}

注意:input_event()上报按键事件必须先上报1(意为按下),再上报0(意为弹起),不能单独上报1,或者上报0。

kernel部分添加完成后,可通过getevent命令来确认事件有无上报成功。

内核部分确认调试成功后,需要将键值上报至上层:

1.修改按键布局映射文件,都是以.kl结尾的文件,可通过

cat bus/input/devices 命令来查看我们系统目前正在使用的布局文件是哪个。

我使用的是/device/rockchip/common/rk29-keypad.kl布局文件

key 59 MENU

key 102 HOME

key 114 VOLUME_DOWN

key 115 VOLUME_UP

key 116 POWER

key 143 NOTIFICATION

key 158 BACK

key 212 CAMERA

key 217 SEARCH

在这后面添加key 117 F1 则表示内核上报的117键值映射到系统的键值为F1

系统的键值定义在frameworks/base/core/java/android/view/KeyEvent.java下。

添加完成后可以在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java里添加打印信息,查看键值是否上报成功。

public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {

final boolean keyguardOn = keyguardOn();

final int keyCode = event.getKeyCode();

final int repeatCount = event.getRepeatCount();

final int metaState = event.getMetaState();

final int flags = event.getFlags();

final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;

final boolean canceled = event.isCanceled();

if (DEBUG_INPUT) {

Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="

+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed

+ " canceled=" + canceled);

}

上层APK可通过调用frameworks/base/core/java/android/view/KeyEvent.java中的接口去拦截键值

public interface Callback {

boolean onKeyDown(int keyCode, KeyEvent event);

boolean onKeyLongPress(int keyCode, KeyEvent event);

boolean onKeyUp(int keyCode, KeyEvent event);

boolean onKeyMultiple(int keyCode, int count, KeyEvent event);

}

 类似资料: