Android系统级深入开发--转
来源:互联网 发布:健康大数据研究中心 编辑:程序博客网 时间:2024/05/16 05:37
form:http://www.eefocus.com/chongzi865458/blog/11-06/225120_23131.html
- 驱动程序:在/dev/input目录中,通常是Event类型的驱动程序
- EventHub:本地框架层的EventHub是libui中的一部分,它实现了对驱动程序的控制,并从中获得信息
- KeyLayout(按键布局)和KeyCharacterMap(按键字符映射)文件。同时,libui中有相应的代码对其操作。定义按键布局和按键字符映射需要运行时配置文件的支持,它们的后缀名分别为kl和kcm
- Java框架层的处理:在Java框架层具有KeyInputDevice等类用于处理由EventHub传送上来的信息,通常信息由数据结构RawInputEvent和KeyEvent来表示。通常情况下,对于按键事件,则直接使用KeyEvent来传送给应用程序层,对于触摸屏和轨迹球等事件,则由RawInputEvent经过转换后,形成MotionEvent时间传送给应用程序层
- 在Android的应用程序层中,通过重新实现onTouchEvent和onTrackballEvent等函数来接收运动事件(MotionEvent),通过重新实现&111nKeyDown和&111nKeyUp等函数来接收按键事件(KeyEvent)。这些类包含在android.view包中
- 输入(input)驱动程序
- 用户空间中动态配置的kl和kcm文件
- joystick游戏杆:0~31
- mouse鼠标:32~62
- mice鼠标:63
- 事件(Event)设备:64~95
- struct input_dev {
- const char *name; // 设备名称
- const char *phys; // 设备在系统的物理路径
- const char *uniq; // 统一的ID
- struct input_id id; // 设备ID
- unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; // 事件
- unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; // 按键
- unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; // 相对设备
- unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; // 绝对设备
- unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; // 杂项设备
- unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; // LED
- unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; // 声音设备
- unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; // 强制反馈备
- unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; // 开关设备
- unsigned int keycodemax; // 按键码的最大值
- unsigned int keycodesize; // 按键码的大小
- void *keycode; // 按键码
- int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
- int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
- struct ff_device *ff;
- unsigned int repeat_key;
- struct timer_list timer;
- int sync;
- int abs[ABS_MAX + 1];
- int rep[REP_MAX + 1];
- unsigned long key[BITS_TO_LONGS(KEY_CNT)];
- unsigned long led[BITS_TO_LONGS(LED_CNT)];
- unsigned long snd[BITS_TO_LONGS(SND_CNT)];
- unsigned long sw[BITS_TO_LONGS(SW_CNT)];
- int absmax[ABS_MAX + 1]; // 绝对设备相关内容
- int absmin[ABS_MAX + 1];
- int absfuzz[ABS_MAX + 1];
- int absflat[ABS_MAX + 1]; // 设备相关的操作
- int (*open)(struct input_dev *dev);
- void (*close)(struct input_dev *dev);
- int (*flush)(struct input_dev *dev, struct file *file);
- int (*event)(struct input_dev *dev, unsigned int type,
- unsigned int code, int value);
- struct input_handle *grab;
- spinlock_t event_lock;
- struct mutex mutex;
- unsigned int users;
- int going_away;
- struct device dev;
- struct list_head h_list;
- struct list_head node;
- };
- void input_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int value);
- void input_inject_event(struct input_handle *handle,
- unsigned int type, unsigned int code, int value);
- static inline void input_report_key(struct input_dev *dev,
- unsigned int code, int value)
- { input_event(dev, EV_KEY, code, !!value); }
- static inline void input_report_rel(struct input_dev *dev,
- unsigned int code, int value)
- { input_event(dev, EV_REL, code, value); }
- static inline void input_report_abs(struct input_dev *dev,
- unsigned int code, int value)
- { input_event(dev, EV_ABS, code, value); }
- static inline void input_report_ff_status(struct input_dev *dev,
- unsigned int code, int value)
- { input_event(dev, EV_FF_STATUS, code, value); }
- static inline void input_report_switch(struct input_dev *dev,
- unsigned int code, int value)
- { input_event(dev, EV_SW, code, !!value); }
- static inline void input_sync(struct input_dev *dev)
- { input_event(dev, EV_SYN, SYN_REPORT, 0); }
- #define KEY_RESERVED 0
- #define KEY_ESC 1
- #define KEY_1 2
- #define KEY_2 3
- #define KEY_3 4
- #define KEY_4 5
- #define KEY_5 6
- #define KEY_6 7
- #define KEY_7 8
- #define KEY_8 9
- #define KEY_9 10
- #define KEY_0 11
- #define KEY_MINUS 12
- #define KEY_EQUAL 13
- #define KEY_BACKSPACE 14
- #define KEY_TAB 15
- #define KEY_Q 16
- #define KEY_W 17
- #define KEY_E 18
- #define KEY_R 19
- #define KEY_T 20
- # getevent
- add device 1: /dev/input/event0
- name: "qwerty2"
- could not get driver version for /dev/input/mouse0, Not a typewriter
- could not get driver version for /dev/input/mice, Not a typewriter
- /dev/input/event0: 0001 0002 00000001
- /dev/input/event0: 0001 0002 00000000
- typedef enum KeyCode {
- kKeyCodeUnknown = 0,
- kKeyCodeSoftLeft = 1,
- kKeyCodeSoftRight = 2,
- kKeyCodeHome = 3,
- kKeyCodeBack = 4,
- // ...... 省略中间按键码
- } KeyCode;
- static const KeycodeLabel KEYCODES[] = { // {字符串,整数}
- { "SOFT_LEFT", 1 },
- { "SOFT_RIGHT", 2 },
- { "HOME", 3 },
- { "BACK", 4 },
- { "CALL", 5 },
- { "ENDCALL", 6 },
- { "0", 7 }, // ...... 数字按键
- { "1", 8 },
- { "2", 9 },
- { "3", 10 },
- { "4", 11 },
- { "5", 12 },
- { "6", 13 },
- { "7", 14 },
- { "8", 15 },
- { "9", 16 },
- { "STAR", 17 },
- // ...... 省略中间按键映射
- { "MENU", 82 },
- // ...... 省略中间按键映射
- { NULL, 0 }
- };
- static const KeycodeLabel FLAGS[] = {
- { "WAKE", 0x00000001 }, // 可以唤醒睡眠,并通知应用层
- { "WAKE_DROPPED", 0x00000002 }, // 可以唤醒睡眠,不通知应用层
- { "SHIFT", 0x00000004 }, // 自动附加SHIFT
- { "CAPS_LOCK", 0x00000008 }, // 自动附加CAPS_LOCK
- { "ALT", 0x00000010 }, // 自动附加ALT
- { "ALT_GR", 0x00000020 },
- { "MENU", 0x00000040 },
- { "LAUNCHER", 0x00000080 },
- { NULL, 0 }
- };
- class KeyCharacterMap
- {
- public:
- ~KeyCharacterMap();
- unsigned short get(int keycode, int meta);
- unsigned short getNumber(int keycode);
- unsigned short getMatch(int keycode, const unsigned short* chars,
- int charsize, uint32_t modifiers);
- unsigned short getDisplayLabel(int keycode);
- bool getKeyData(int keycode, unsigned short *displayLabel,
- unsigned short *number, unsigned short* results);
- inline unsigned int getKeyboardType() { return m_type; }
- bool getEvents(uint16_t* chars, size_t len,
- Vector* keys, Vector* modifiers);
- static KeyCharacterMap* load(int id);
- enum {
- NUMERIC = 1,
- Q14 = 2,
- QWERTY = 3 // or AZERTY or whatever
- };
- }
- KL(Keycode Layout):后缀名为kl的配置文件
- KCM(KeyCharacterMap):后缀名为kcm的配置文件
- key 399 GRAVE
- key 2 1
- key 3 2
- key 4 3
- key 5 4
- key 6 5
- key 7 6
- key 8 7
- key 10 9
- key 11 0
- key 158 BACK WAKE_DROPPED
- key 230 SOFT_RIGHT WAKE
- key 60 SOFT_RIGHT WAKE
- key 107 ENDCALL WAKE_DROPPED
- key 62 ENDCALL WAKE_DROPPED
- key 229 MENU WAKE_DROPPED
- # 省略部分按键的对应内容
- key 16 Q
- key 17 W
- key 18 E
- key 19 R
- key 20 T
- key 115 VOLUME_UP
- key 114 VOLUME_DOWN
- [type=QWERTY]
- # keycode display number base caps fn caps_fn
- A 'A' '2' 'a' 'A' '#' 0x00
- B 'B' '2' 'b' 'B' '<' 0x00
- C 'C' '2' 'c' 'C' '9' 0x00E7
- D 'D' '3' 'd' 'D' '5' 0x00
- E 'E' '3' 'e' 'E' '2' 0x0301
- F 'F' '3' 'f' 'F' '6' 0x00A5
- G 'G' '4' 'g' 'G' '-' '_'
- H 'H' '4' 'h' 'H' '[' '{'
- I 'I' '4' 'i' 'I' '$' 0x0302
- J 'J' '5' 'j' 'J' ']' '}'
- K 'K' '5' 'k' 'K' '"' '~'
- L 'L' '5' 'l' 'L' ''' '`'
- M 'M' '6' 'm' 'M' '!' 0x00
- N 'N' '6' 'n' 'N' '>' 0x0303
- static const char *device_path = "/dev/input"; // 输入设备的目录
- bool EventHub::openPlatformInput(void)
- {
- // ...... 省略其他部分的内容
- res = scan_dir(device_path);
- return true;
- }
- bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
- int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
- int32_t* outValue, nsecs_t* outWhen)
- {
- while(1) {
- // ...... 省略部分内容
- pollres = poll(mFDs, mFDCount, -1); // 使用poll处理设备节点,进行阻塞
- // ...... 省略部分内容
- for(i = 1; i < mFDCount; i++) {
- if(mFDs[i].revents) {
- if(mFDs[i].revents & POLLIN) {
- res = read(mFDs[i].fd, &iev, sizeof(iev)); // 读取信息
- // ...... 省略部分内容
- }
- }
- }
- }
- int EventHub::open_device(const char *deviceName) {
- // ...... 省略部分内容
- const char* root = getenv("ANDROID_ROOT");
- snprintf(keylayoutFilename, sizeof(keylayoutFilename),
- "%s/usr/keylayout/%s.kl", root, tmpfn);
- bool defaultKeymap = false;
- if (access(keylayoutFilename, R_OK)) {
- snprintf(keylayoutFilename, sizeof(keylayoutFilename),
- "%s/usr/keylayout/%s", root, "qwerty.kl");
- defaultKeymap = true;
- }
- // ...... 省略部分内容
- }
- frameworks/base/include/ui/KeycodeLabels.h:中的KeyCode枚举数值和KeycodeLabel 类型Code数组(以NULL为结尾)
- frameworks/base/core/Java/android/view/KeyEvent.Java:定义整数值,作为平台的API供Java应用程序使用
- frameworks/base/core/res/res/values/attrs.xml:表示属性的资源文件,需要修改其中的name="keycode"的attr。
- static irqreturn_t events_interrupt(int irq, void *dev_id)
- {
- struct event_dev *edev = dev_id;
- unsigned type, code, value;
- type = __raw_readl(edev->addr + REG_READ); // 类型
- code = __raw_readl(edev->addr + REG_READ); // 码
- value = __raw_readl(edev->addr + REG_READ); // 数值
- input_event(edev->input, type, code, value);
- return IRQ_HANDLED;
- }
- /dev/input/event4:几个按键
- /dev/input/event2:触摸屏
- /dev/input/event5:轨迹球
- static struct gpio_event_info *mahimahi_input_info[] = {
- &mahimahi_keypad_matrix_info.info, // 键盘矩阵
- &mahimahi_keypad_key_info.info, // 键盘信息
- &jogball_x_axis.info.info, // 轨迹球X方向信息
- &jogball_y_axis.info.info, // 轨迹球Y方向信息
- };
- static struct gpio_event_platform_data mahimahi_input_data = {
- .names = {
- "mahimahi-keypad", // 按键设备
- "mahimahi-nav", // 轨迹球设备
- NULL,
- },
- .info = mahimahi_input_info,
- .info_count = ARRAY_SIZE(mahimahi_input_info),
- .power = jogball_power,
- };
- static struct platform_device mahimahi_input_device = {
- .name = GPIO_EVENT_DEV_NAME,
- .id = 0,
- .dev = {
- .platform_data = &mahimahi_input_data,
- },
- };
- static unsigned int mahimahi_col_gpios[] = { 33, 32, 31 };
- static unsigned int mahimahi_row_gpios[] = { 42, 41, 40 };
- #define KEYMAP_INDEX(col, row) ((col)*ARRAY_SIZE(mahimahi_row_gpios) + (row))
- #define KEYMAP_SIZE (ARRAY_SIZE(mahimahi_col_gpios) * \
- ARRAY_SIZE(mahimahi_row_gpios))
- static const unsigned short mahimahi_keymap[KEYMAP_SIZE] = { // 按键映射关系
- [KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP, /* 115 */
- [KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN, /* 114 */
- [KEYMAP_INDEX(1, 1)] = MATRIX_KEY(1, BTN_MOUSE),
- };
- static struct gpio_event_matrix_info mahimahi_keypad_matrix_info = {
- .info.func = gpio_event_matrix_func, // 关键函数实现
- .keymap = mahimahi_keymap,
- .output_gpios = mahimahi_col_gpios,
- .input_gpios = mahimahi_row_gpios,
- .noutputs = ARRAY_SIZE(mahimahi_col_gpios),
- .ninputs = ARRAY_SIZE(mahimahi_row_gpios),
- .settle_time.tv.nsec = 40 * NSEC_PER_USEC,
- .poll_time.tv.nsec = 20 * NSEC_PER_MSEC,
- .flags = (GPIOKPF_LEVEL_TRIGGERED_IRQ |
- GPIOKPF_REMOVE_PHANTOM_KEYS |
- GPIOKPF_PRINT_UNMAPPED_KEYS),
- };
- static struct gpio_event_direct_entry mahimahi_keypad_key_map[] = { // Power按键
- {
- .gpio = MAHIMAHI_GPIO_POWER_KEY,
- .code = KEY_POWER,
- },
- };
- static struct gpio_event_input_info mahimahi_keypad_key_info = {
- .info.func = gpio_event_input_func, // 关键函数实现
- .info.no_suspend = true,
- .flags = 0,
- .type = EV_KEY,
- .keymap = mahimahi_keypad_key_map,
- .keymap_size = ARRAY_SIZE(mahimahi_keypad_key_map)
- };
- static uint32_t jogball_x_gpios[] = {
- MAHIMAHI_GPIO_BALL_LEFT, MAHIMAHI_GPIO_BALL_RIGHT,
- };
- static uint32_t jogball_y_gpios[] = {
- MAHIMAHI_GPIO_BALL_UP, MAHIMAHI_GPIO_BALL_DOWN,
- };
- static struct jog_axis_info jogball_x_axis = { // X轴的内容
- .info = {
- .info.func = gpio_event_axis_func, // 关键函数实现
- .count = ARRAY_SIZE(jogball_x_gpios),
- .dev = 1,
- .type = EV_REL,
- .code = REL_X,
- .decoded_size = 1U << ARRAY_SIZE(jogball_x_gpios),
- .map = jogball_axis_map,
- .gpio = jogball_x_gpios,
- .flags = GPIOEAF_PRINT_UNKNOWN_DIRECTION,
- }
- };
- static struct jog_axis_info jogball_y_axis = { // Y轴的内容
- .info = {
- .info.func = gpio_event_axis_func, // 关键函数实现
- .count = ARRAY_SIZE(jogball_y_gpios)
- .dev = 1,
- .type = EV_REL,
- .code = REL_Y,
- .decoded_size = 1U << ARRAY_SIZE(jogball_y_gpios),
- .map = jogball_axis_map,
- .gpio = jogball_y_gpios,
- .flags = GPIOEAF_PRINT_UNKNOWN_DIRECTION,
- }
- };
- static irqreturn_t do_kp_irq(int irq, void *_kp)
- {
- struct twl4030_keypad *kp = _kp;
- u8 reg;
- int ret;
- ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); // 调用twl4030_i2c_read
- if ((ret >= 0) && (reg & KEYP_IMR1_KP))
- twl4030_kp_scan(kp, 0); // 非释放所有的处理
- else
- twl4030_kp_scan(kp, 1); // 释放所有的处理
- return IRQ_HANDLED;
- }
- static void twl4030_kp_scan(struct twl4030_keypad *kp, int release_all)
- {
- u16 new_state[MAX_ROWS];
- int col, row;
- // ...... 省略部分内容
- for (row = 0; row < kp->n_rows; row++) {
- int changed = new_state[row] ^ kp->kp_state[row];
- // ...... 省略部分内容
- for (col = 0; col < kp->n_cols; col++) {
- int key;
- key = twl4030_find_key(kp, col, row);
- // ...... 省略部分内容
- input_report_key(kp->input, key, // 上报按键消息
- new_state[row] & (1 << col));
- }
- kp->kp_state[row] = new_state[row];
- }
- input_sync(kp->input);
- }
- static int twl4030_find_key(struct twl4030_keypad *kp, int col, int row)
- {
- int i, rc;
- rc = KEY(col, row, 0);
- for (i = 0; i < kp->keymapsize; i++)
- if ((kp->keymap[i] & ROWCOL_MASK) == rc)
- return kp->keymap[i] & (KEYNUM_MASK | KEY_PERSISTENT);
- return -EINVAL;
- }
- static int zoom2_twl4030_keymap[] = {
- KEY(0, 0, KEY_E),
- KEY(1, 0, KEY_R),
- KEY(2, 0, KEY_T),
- KEY(3, 0, KEY_HOME),
- KEY(6, 0, KEY_I),
- KEY(7, 0, KEY_LEFTSHIFT),
- // ……省略部分内容
- KEY(7, 7, KEY_DOWN),
- KEY(0, 7, KEY_PROG1),
- KEY(1, 7, KEY_PROG2),
- KEY(2, 7, KEY_PROG3),
- KEY(3, 7, KEY_PROG4),
- 0
- };
- Android系统级深入开发--转
- Android系统级深入开发输入系统
- android系统深入开发
- Android系统级深入开发——移植与调试
- Android系统级深入开发之OpenMax系统结构和移植内容
- Android开发之深入理解Android 6.0、7.0系统权限
- Android开发之深入理解Android 7.0系统权限
- 《Android系统级深入开发—移植与调试 》china-pub新书上架
- 【备忘】Android系统级深入开发—移植与调试 PDF 下载
- 深入剖析Android系统
- 深入剖析Android系统
- android系统深入研究
- 从零开始--系统深入学习android(理论--开发前准备--开发入门--DDMS调试)
- 嵌入式系统开发学习如何起步、如何深入?(转)
- Android开发之深入理解Android 7.0系统权限更改相关文档
- Android开发之深入理解Android 7.0系统权限更改相关文档
- Android开发之深入理解Android 7.0系统权限更改相关文档
- Android开发之深入理解Android 7.0系统权限更改相关文档
- windows各组的权限问题
- putty 连接 redhat 9.0 中文乱码解决方法
- 详细解析Java中抽象类和接口的区别
- RMQ的ST写法和线段树写法两种姿势
- springMVC上传文件例子
- Android系统级深入开发--转
- oracle11g迁移表空间
- Android开发学习之三——第一个Android程序
- php学习之数学函数 数字运算 随机数 数组
- Centos 配置eth0 提示Device does not seem to be present
- PYTHON中的静态方法和类方法
- 输出反序数
- lightoj 1098 - A New Function 因子和
- Python的学习(二十一)----Python的静态变量