Androidはキー値を追加し、ドライブから上位レベルに報告します.

31425 ワード

プラットフォーム:RK 3288
OS:Android7.1
kernelセクションでキー値を追加するには、次の手順に従います.
1.dts(kernel/arch/arm/boot/dts/rk 3288-android.dtsi)にキー値属性を追加し、powerキー構成に倣う
wake-key {
			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
			linux,code = <117>;
			pinctrl-names = "default";
			pinctrl-0 = <&pmic_int>;
			label = "wake";
			gpio-key,wakeup;
};

我々が使用するキー値操作はgpioによってトリガされるので、gpio-keyに構成される.linux、codeキーコードはカーネルカスタムキーコードを表示して選択できます.kernel/include/uapi/linux/input-event-codesに定義する.h下.
/*
 * Event types
 */
 
#define EV_SYN			0x00
#define EV_KEY			0x01
#define EV_REL			0x02
#define EV_ABS			0x03
#define EV_MSC			0x04
#define EV_SW			0x05
#define EV_LED			0x11
#define EV_SND			0x12
#define EV_REP			0x14
#define EV_FF			0x15
#define EV_PWR			0x16
#define EV_FF_STATUS		0x17
#define EV_MAX			0x1f
#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_RIGHTALT		100
#define KEY_LINEFEED		101
#define KEY_HOME		102
#define KEY_UP			103
#define KEY_PAGEUP		104
#define KEY_LEFT		105
#define KEY_RIGHT		106
#define KEY_END			107
#define KEY_DOWN		108
#define KEY_PAGEDOWN		109
#define KEY_INSERT		110
#define KEY_DELETE		111
#define KEY_MACRO		112
#define KEY_MUTE		113
#define KEY_VOLUMEDOWN		114
#define KEY_VOLUMEUP		115
#define KEY_POWER		116	/* SC System Power Down */
#define KEY_KPEQUAL		117
#define KEY_KPPLUSMINUS		118
#define KEY_PAUSE		119
#define KEY_SCALE		120	/* AL Compiz Scale (Expose) */

#define KEY_KPCOMMA		121
#define KEY_HANGEUL		122
#define KEY_HANGUEL		KEY_HANGEUL
#define KEY_HANJA		123
#define KEY_YEN			124
#define KEY_LEFTMETA		125
#define KEY_RIGHTMETA		126
#define KEY_COMPOSE		127

#define KEY_STOP		128	/* AC Stop */
#define KEY_AGAIN		129
#define KEY_PROPS		130	/* AC Properties */
#define KEY_UNDO		131	/* AC Undo */
#define KEY_FRONT		132
#define KEY_COPY		133	/* AC Copy */
#define KEY_OPEN		134	/* AC Open */
#define KEY_PASTE		135	/* AC Paste */
#define KEY_FIND		136	/* AC Search */
#define KEY_CUT			137	/* AC Cut */
#define KEY_HELP		138	/* AL Integrated Help Center */
#define KEY_MENU		139	/* Menu (show menu) */
#define KEY_CALC		140	/* AL Calculator */
#define KEY_SETUP		141
#define KEY_SLEEP		142	/* SC System Sleep */
#define KEY_WAKEUP		143	/* System Wake Up */
#define KEY_FILE		144	/* AL Local Machine Browser */
#define KEY_SENDFILE		145
#define KEY_DELETEFILE		146
#define KEY_XFER		147
#define KEY_PROG1		148
#define KEY_PROG2		149
#define KEY_WWW			150	/* AL Internet Browser */
#define KEY_MSDOS		151
#define KEY_COFFEE		152	/* AL Terminal Lock/Screensaver */
#define KEY_SCREENLOCK		KEY_COFFEE
#define KEY_ROTATE_DISPLAY	153	/* Display orientation for e.g. tablets */
#define KEY_DIRECTION		KEY_ROTATE_DISPLAY
#define KEY_CYCLEWINDOWS	154
#define KEY_MAIL		155
#define KEY_BOOKMARKS		156	/* AC Bookmarks */
#define KEY_COMPUTER		157
#define KEY_BACK		158	/* AC Back */
#define KEY_FORWARD		159	/* AC Forward */
#define KEY_CLOSECD		160
#define KEY_EJECTCD		161
#define KEY_EJECTCLOSECD	162
#define KEY_NEXTSONG		163
#define KEY_PLAYPAUSE		164
#define KEY_PREVIOUSSONG	165
#define KEY_STOPCD		166
#define KEY_RECORD		167
#define KEY_REWIND		168
#define KEY_PHONE		169	/* Media Select Telephone */
#define KEY_ISO			170
#define KEY_CONFIG		171	/* AL Consumer Control Configuration */
#define KEY_HOMEPAGE		172	/* AC Home */
#define KEY_REFRESH		173	/* AC Refresh */
#define KEY_EXIT		174	/* 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イベントをinput_register_device()関数でカーネルに登録します.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 /proc/bus/input/devicesコマンドで私たちのシステムのinputデバイス情報を表示することができます.システムはvendor id product idまたはdevice nameでレイアウトファイルに一致します.dumpsys inputで現在使用されているレイアウトファイルを取得することもできます.私が使っているのは/device/rockchip/common/rk 29-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のキー値がシステムにマッピングするキー値がF 1システムのキー値であるframeworks/base/core/java/android/view/KeyEventで定義.JAvaの下です.
追加が完了したらframeworks/base/services/core/java/com/android/server/policy/iPhone WindowManager.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);
}