android学习笔记6 eventhub

Android6.0输入系统之EventHub源码分析 上篇文章《Android6.0输入系统之InputManagerService构成分析》 完成了IMS的创建,接着就沿着输入系统这条路继续往下走。 在EventHub的构造函数中,它通过INotify与Epoll机制建立起对设备点增删事件及可读状态的监听。INotify是Linux内核所提供的一种文件系统变化通知机制。它可以为应用程序监控文件系统的变化,如文件的新建、删除、读写等等。它有两个基本... 阅读详情

Eventhub是在Native 的inputmanager创建的时候被创建的,inputreadthread就通过eventhub的getevent方法来源源不断的获取driver上报的input事件。

 

 

bool EventHub::getEvent(RawEvent* outEvent)

{

 

   if (!mOpened) {

       mError = openPlatformInput() ? NO_ERROR :UNKNOWN_ERROR;

       mOpened = true;

       mNeedToSendFinishedDeviceScan = true;

}

//省略

}

如果是第一次进入getevent,则会去调用openplatforminput来获取input设备,加载对应的kl,将device加入eventhub的特定的结构体中。

 

bool EventHub::openPlatformInput(void)

{

 

 //省略

   res = scanDir(device_path);

   if(res < 0) {

       LOGE("scan dir failed for %s\n", device_path);

    }

 

   return true;

}

直接调用scandir来处理/dev/input/文件夹

int EventHub::scanDir(const char *dirname)

{   char devname[PATH_MAX];

   char *filename;

   DIR *dir;

   struct dirent *de;

   dir = opendir(dirname);

   if(dir == NULL)

       return -1;

   strcpy(devname, dirname);

   filename = devname + strlen(devname);

   *filename++ = '/';

   while((de = readdir(dir))) {

       if(de->d_name[0] == '.' &&

          (de->d_name[1] == '\0' ||

           (de->d_name[1] == '.' && de->d_name[2] == '\0')))

           continue;

       strcpy(filename, de->d_name);

       openDevice(devname);

    }

   closedir(dir);

   return 0;

}

通过readdir来得到子文件的名字,拼成完整的设备路径后调用opendevice来打开他,如/dev/input/event0 (可以在adb shell进入手机后cd到/dev/input下ls下,就可以看到了)

 

int EventHub::openDevice(const char*deviceName) {

 //省略,主要是将新发现的设备增加到mDevicesById和mFDs数组中。

//接下来是对设备类型的判断,我们以键盘为例:

   LOGV("Getting keys...");

   if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >=0) {

       //LOGI("MAP\n");

       //for (int i = 0; i < sizeof(key_bitmask); i++) {

       //    LOGI("%d:0x%02x\n", i, key_bitmask[i]);

       //}

 

       // See if this is a keyboard.  Ignoreeverything in the button range except for

       // gamepads which are also considered keyboards.

       if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))

                ||containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_GAMEPAD),

                       sizeof_bit_array(BTN_DIGI))

                ||containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),

                       sizeof_bit_array(KEY_MAX + 1))) {

           device->classes |=INPUT_DEVICE_CLASS_KEYBOARD;

 

            device->keyBitmask = newuint8_t[sizeof(key_bitmask)];

           if (device->keyBitmask != NULL) {

                memcpy(device->keyBitmask,key_bitmask, sizeof(key_bitmask));

           } else {

                delete device;

                LOGE("out of memory allocating keybitmask");

                return -1;

           }

       }

    }

//具体的ioctl还没搞明白,从字面意思上看,就是判断当前设备是否是键盘,如果是则将其类型或上INPUT_DEVICE_CLASS_KEYBOARD

//其他的设备的处理也很类似,接下来是加载kl:

 

 

if((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {

//如果是键盘

       char tmpfn[sizeof(name)];

       char keylayoutFilename[300];

 

       // a more descriptive name

       device->name = name;

 

       // replace all the spaces with underscores

       strcpy(tmpfn, name);

       for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ''))

           *p = '_';

 

       // find the .kl file we need for this device

       const char* root = getenv("ANDROID_ROOT");

      //此处的root即是/system/

       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;

       }

       status_t status = device->layoutMap->load(keylayoutFilename);

       if (status) {

           LOGE("Error %d loading key layout.", status);

       }

   device->next = mOpeningDevices;

mOpeningDevices = device;

    mDevices[mFDCount] = device

    mFDCount++;

      //首先尝试去查找是否存在特定的keylayoutfile,如我们的键盘对应的kl应该是:

       /system/usr/keylayout/sprd-keypad.kl

      如果kl不存在,则尝试去打开默认的kl,即qwerty.kl,然后加载对应的kl。

//如果加载成功,则通知大家设备名(将hw.keyboards.0.devname赋值为对应的设备名,如sprd-keypad),并将其声明为mOpeningDevices到这里,一个input设备就打开成功可以为eventhub所用了。

}

接下来我们看下keylayoutMap的Load函数来了解下kl文件的解析。

Kl文件也比较简单,截取一部分:

Key  116     POWER             WAKE

Key是起始标志, 116是硬件扫描码,POWER是对应的KEYCODE,WAKE是按键对应的FLAG。

 

KeyLayoutMap::load(const char* filename){

//省略无关。

 

 

enum { BEGIN,SCANCODE, KEYCODE, FLAG } state = BEGIN;

//state初始为BEGIN

   while (true) {

       String8 token = next_token(&p, &line);

       if (*p == '\0') {

           break;

       }

       switch (state)

       {

           case BEGIN:

                if (token == "key") {

                    state = SCANCODE;

                   //如果读取到key,状态置为SCANCODE

                } else {

                    LOGE("%s:%d: expectedkey, got '%s'\n", filename, line,

                            token.string());

                    err = BAD_VALUE;

                    goto done;

                }

                break;

           case SCANCODE:

                scancode = strtol(token.string(),&end, 0);

                if (*end != '\0') {

                    LOGE("%s:%d: expectedscancode (a number), got '%s'\n",

                            filename, line,token.string());

                    goto done;

                }

                //LOGI("%s:%d: gotscancode %d\n", filename, line, scancode );

//

                state = KEYCODE;

                //读取扫描码成功后继续读取keycode

                break;

           case KEYCODE:

                keycode =token_to_value(token.string(), KEYCODES);

                //通过在KEYCODES中查找得到对应的按键码,如POWER:

               staticconst KeycodeLabel KEYCODES[] = {

    {"SOFT_LEFT", 1 },

    {"SOFT_RIGHT", 2 },

    {"HOME", 3 },

{"BACK", 4 },

    { "POWER", 26 },

}对应的是KEYCODE_POWER

此处的keycode就是上层的使用的keycode。通过kl,就将硬件扫描码转换成了keycode。

                //LOGI("%s:%d: got keycode%d for %s\n", filename, line, keycode, token.string() );

                if (keycode == 0) {

                    LOGE("%s:%d: expectedkeycode, got '%s'\n",

                            filename, line,token.string());

                    goto done;

                }

                state = FLAG;

                break;

           case FLAG:

                if (token == "key") {

                    if (scancode != -1) {

                        //LOGI("got keydecl scancode=%d keycode=%d"

                        //       " flags=0x%08x\n", scancode,keycode, flags);

                        Key k = { keycode,flags };

                        m_keys.add(scancode,k);

                        state = SCANCODE;

                        scancode = -1;

                        keycode = -1;

                        flags = 0;

                        break;

                    }

                }

                tmp = token_to_value(token.string(),FLAGS);

                  //类似的,查FLAGS数组,找到对应的FLAGS:

static const KeycodeLabel FLAGS[] = {

{"WAKE", 0x00000001 },

WAKE,就是0x00000001,对应的是    POLICY_FLAG_WAKE =0x00000001,在input.h

                //LOGI("%s:%d: got flags%x for %s\n", filename, line, tmp, token.string() );

                if (tmp == 0) {

                    LOGE("%s:%d: expectedflag, got '%s'\n",

                            filename, line,token.string());

                    goto done;

                }

               flags |= tmp;

                break;

       }

    }

   if (state == FLAG && scancode != -1 ) {

       //LOGI("got key decl scancode=%d keycode=%d"

       //       "flags=0x%08x\n", scancode, keycode, flags);

       Key k = { keycode, flags };

        m_keys.add(scancode, k);

}

done:

    free(buf);

    close(fd);

 

    m_status = err;

    return err;

}

这样,对应的keycode scancode,flag,都保存在了m_keys中。

接下来继续看getevent:这个神一样的函数

boolEventHub::getEvent(RawEvent* outEvent)

{  

 

    if (!mOpened) {

        mError = openPlatformInput() ? NO_ERROR: UNKNOWN_ERROR;

        mOpened = true;

        mNeedToSendFinishedDeviceScan = true;

     //如果发现了新设备,mNeedToSendFinishedDeviceScan被置为true,在下面会用到

    }

 for (;;) {

        // Report any devices that had lastbeen added/removed.

        if (mClosingDevices != NULL) {

        //在closeDevice函数中被赋值,如果有设备需要关闭,则会走进来,返回一个DEVICE_REMOVED事件。

            device_t* device = mClosingDevices;

            LOGV("Reporting device closed:id=0x%x, name=%s\n",

                 device->id, device->path.string());

            mClosingDevices = device->next;

            if (device->id ==mFirstKeyboardId) {

                outEvent->deviceId = 0;

            } else {

                outEvent->deviceId =device->id;

            }

            outEvent->type = DEVICE_REMOVED;

            outEvent->when =systemTime(SYSTEM_TIME_MONOTONIC);

            delete device;

            mNeedToSendFinishedDeviceScan =true;

            return true;

        }

       if (mOpeningDevices != NULL) {

 // 在上文中的opendevice中的末尾,会将其置为对应的device,也就是说如果发现了新设备,会返回一个DEVICE_ADDED的事件。在inputreader中会处理

            device_t* device = mOpeningDevices;

            LOGV("Reporting device opened:id=0x%x, name=%s\n",

                 device->id,device->path.string());

            mOpeningDevices = device->next;

            if (device->id ==mFirstKeyboardId) {

                outEvent->deviceId = 0;

            } else {

                outEvent->deviceId =device->id;

            }

            outEvent->type = DEVICE_ADDED;

            outEvent->when =systemTime(SYSTEM_TIME_MONOTONIC);

            mNeedToSendFinishedDeviceScan =true;

            return true;

        }

        if (mNeedToSendFinishedDeviceScan) {

//在ADD完成设备后,会发出一个FINISHD_DEVICE_SCAN,标志着所有的input设备都已经SCAN完成。

            mNeedToSendFinishedDeviceScan =false;

            outEvent->type =FINISHED_DEVICE_SCAN;

            outEvent->when =systemTime(SYSTEM_TIME_MONOTONIC);

            return true;

        }

//接下来就是对按键的捕获处理

       // Grab the next input event.

        for (;;) {

            // Consume buffered input events,if any.

            if (mInputBufferIndex <mInputBufferCount) {

               //如果当前存在需要处理的按键事件,则通过map返回对应的outevent

                const struct input_event&iev = mInputBufferData[mInputBufferIndex++];

                const device_t* device =mDevices[mInputDeviceIndex];

 

                LOGV("%s got: t0=%d,t1=%d, type=%d, code=%d, v=%d", device->path.string(),

                     (int) iev.time.tv_sec,(int) iev.time.tv_usec, iev.type, iev.code, iev.value);

                if (device->id ==mFirstKeyboardId) {

                    outEvent->deviceId = 0;

                   //keypad的设备id为0

                } else {

                    outEvent->deviceId =device->id;

                }

                outEvent->type = iev.type;

                outEvent->scanCode =iev.code;

                if (iev.type == EV_KEY) {

                    status_t err = device->layoutMap->map(iev.code,

                            &outEvent->keyCode, & outEvent->flags);

                    //将扫描码转换成按键码,并给出按键的flag位

                    通过对应device的layoutMap中的m_keys中存储的信息(上文中的load中可以看到),返回对应的按键码,FLAG。

                    LOGV("iev.code=%dkeyCode=%d flags=0x%08x err=%d\n",

                        iev.code, outEvent->keyCode,outEvent->flags, err);

                    if (err != 0) {

                        outEvent->keyCode =AKEYCODE_UNKNOWN;

                        outEvent->flags = 0;

                    }

               } else {

                    outEvent->keyCode =iev.code;

                }

                outEvent->value = iev.value;

 

                // Use an event timestamp inthe same timebase as

                // java.lang.System.nanoTime()and android.os.SystemClock.uptimeMillis()

                // as expected by the rest of the system.

                outEvent->when =systemTime(SYSTEM_TIME_MONOTONIC);

                return true;

            }

// 如果读取完了所有存在buffer里的按键事件,或者因为设备刚初始化,不存在等待读取的按键事件,则去读。

            mInputDeviceIndex += 1;

            if (mInputDeviceIndex >= mFDCount) {

                break;

            }

 

            const struct pollfd& pfd =mFDs[mInputDeviceIndex];

            if (pfd.revents & POLLIN) {

                int32_t readSize = read(pfd.fd, mInputBufferData,

                        sizeof(structinput_event) * INPUT_BUFFER_SIZE);

                if (readSize < 0) {

                    if (errno != EAGAIN&& errno != EINTR) {

                        LOGW("could notget event (errno=%d)", errno);

                    }

                } else if ((readSize %sizeof(struct input_event)) != 0) {

                    LOGE("could not getevent (wrong size: %d)", readSize);

                } else {

                    mInputBufferCount= readSize / sizeof(struct input_event);

                 //将input事件存到buffer中,并计算出count,且将index赋值为0

                    mInputBufferIndex = 0;

                }

            }

这样,inputreadthread不停的调用getevent,不停的可以获取到当前的input事件,并上报处理。

Eventhub的部分就看到这里,下一篇看kernel和上层是怎么对应上的。

【Android休眠】之Android对PowerKey事件的处理(2)EventHub EventHub是Android中Input事件的处理中心,完成kernel上报事件的读取、初步处理、传递。 (1)读取:Input设备一旦产生动作,将通过事件(Event)的方式通知user空间;user空间通过读取/dev/input目录下各个文件,获取事件及事件所属的Input设备信息。 (2)初步处理:kernel是以struct input_event的格式上报数据,这里只是根据读取的该结构体做一个简单的封装,成RawEvent形式的数据。 (3)传递:RawEvent形式的数据传递给Inpu 阅读详情

相关推荐

Android Input子系统 - EventHub

前面其实也有提到EventHub的构造函数,里面就是创建epoll实例,然后把一些事件触发的文件描述符加入到epoll里面统一管理。监控/dev/input/目录的iNotify文件mINotifyFd接收Kernel驱动事件(/dev/input/eventX)的文件描述符用来唤醒InputReader线程的管道读文件EventHub是服务于InputReader线程的,前面在InputRead的构造函数里面有创建EventHub的实例。InputReader线程。

Jimmy的专栏 738

Android Input之EventHub

当发生设备增删时,addDeviceLocked()与closeDeviceLocked()函数会将相应的设备放入mOpeningDevices和mClosingDe-vices链表中getEvents()函数会根据mOpeningDevices和mClosingDevices两个链表生成对应的DEVICE_ADDED和DEVICE_REMOVED事件,其中后者的优先级高于前者。

探索未知,成就非凡 821

【安卓13 源码】Input子系统(3) - EventHub增加设备的流程

由前面的分析知道,在创建inputreader 线程的时候,会去循环执行 looponce 方法。

mike_jun的博客 1270

EventHub代码原理详解

一、EventHub简述Android系统基于Linux系统,由多个子系统组合而成,各子系统分工合作,在各自功能域中扮演关键角色。其中一个比较重要的子系统是Input子系统,正如其名地,挂...

内核工匠 4984

Android input 原理分析(二) _ EventHub

《原理分析(一)》中简单分析了IMS 的启动过程,大致如下: 通过IMS的构造,创建InputManager 实例,并保存到新建的实例NativeInputManager 中。InputManager实例时分别创建InputDispatcher 和InputReader; 将IMS 的实例传入WSM 中; 将WSM 中input 相关的callback 注册到IMS,方便后面交互; 开启IMS 的启动流程,分别创建Dispatch thread 和read thread。 在分析input 的分发原

私房菜 1581

mcgs数据导出到U盘

mcgs触摸屏在工业中应用还是很多的,尤其他的脚本功能策略功能等将开放性放到了最大,让用户可以根据实际需求进行自由创作,正因为这样,对一些初学者就不是很友好,初学者想要简单操作就能实现功能,但是mcgs不可能两者兼备,在做工业设备,一些数据的采集保存就比较常见,但是mcgs没有相关按钮能够直接实现将数据导出到U盘的功能。这里我给大家讲解关于mcgs将报警历史记录、日志记录、历史数据记录导出到U盘的方法。

qq_24866535的博客 6233

Android输入系统之EventHub(AndroidV)

input EventHub

gary_qing的博客 904

VCS 2018 环境下,手把手教你用 UVMC 搞定 SystemC 和 SystemVerilog 混合仿真(附完整代码)

本文详细介绍了在VCS 2018环境下使用UVMC实现SystemC和SystemVerilog混合仿真的完整指南。从环境配置、工具链设置到UVMC通信机制解析,提供了实战案例和高级调试技巧,帮助开发者高效搭建复杂验证环境。特别适合需要处理跨语言仿真的芯片验证工程师。

weixin_30952535的博客 285

Android 输入系统(二)EventHub

接着上一篇的InputManagerService,这里主要介绍一下EventHub。EventHub主要是访问/dev/input下端所有设备节点,并将输入事件、设备节点端增删返给InputReader。 EventHub初始化 由上一篇可知,EventHub对象是在NativeInputManager构造函数中创建的。先看一下EventHub构造函数中都做了些什么 EventHub:

奋斗的菜鸟ing 1万+

FP7195升降压恒流驱动IC:从AC/DC 12~24V输入到稳定输出的高效电源设计实战

本文详细解析FP7195升降压恒流驱动IC的工作原理与应用实战。该芯片支持4.5V-32V宽输入范围,能自动切换升降压模式并保持输出恒定,特别适用于车载LED照明、工业电源等电压波动场景。通过实际案例分享PCB布局、元件选型及调试技巧,帮助工程师实现高效稳定的电源设计。

vodka的博客 954

simulink中无迹卡尔曼(UKF)模块使用

simulink的UKF模块简单说明

qq_41059950的博客 2820

android 管道模式,Android 输入系统(二)EventHub

接着上一篇的InputManagerService,这里主要介绍一下EventHub。EventHub主要是访问/dev/input下的所有设备节点,并将输入事件、设备节点的增删返给InputReader。1 EventHub初始化由上一篇可知,EventHub对象是在NativeInputManager构造函数中创建的。先看一下EventHub构造函数中都做了些什么EventHub::Event...

weixin_29923451的博客 767

地平线Matrix-Client实战:3分钟搞定摄像头调试与3D视图配置(附避坑指南)

本文详细介绍了地平线Matrix-Client在摄像头调试与3D视图配置中的实战技巧,包括环境准备、核心功能快速上手、高阶调试与性能优化等。通过3分钟快速配置指南和避坑建议,帮助开发者高效完成智能视觉系统开发,特别适用于自动驾驶和机器人视觉领域。

w7x8y9z的博客 267

android学习笔记6 eventhub

Eventhub是在Native 的inputmanager创建的时候被创建的,inputreadthread就通过eventhub的getevent方法来源源不断的获取driver上报的input事件。     bool EventHub::getEvent(RawEvent* outEvent) {      if (!mOpened) {

Peter的专栏 1001

J1939协议实用指南与J1939数据记录方案

“没错,这是一份SAE J1939简单、实用指南。”—虹科 **开篇:**在这篇介绍中,我们介绍了J1939协议的基本知识,其中包括PGN和SPN。因为这是一篇偏向应用的简介,所以您还将会学习到如何通过DBC文件解码J1939数据、如何记录J1939、典型的应用案例和实用技巧。下面,来了解下这份简单易懂的J1939介绍吧~ 什么是J1939? 简而言之,SAE J1939其实是一套标准,重型车辆ECU间就是按照这套标准在CAN总线上进行通信的。当今大多数车辆都通过CAN(Controller Area Ne

1万+

二、租用AutoDL服务器与连接教程

点击右上角控制台,选择【租用新的实例】;,我这里使用的是xshell和xftp工具(自行下载)。打开本地目录和服务器目录,直接拖动文件。

zzf021122的博客 1326

Android7 Input(三)EventHub

在Android Input框架中,EventHub主要作用就是读取输入设备上报的event事件, 并将收集的事件提交给InputReader进行处理。本文主要描述了EventHub如何管理系统中的输入设备以及系统上报输入事件的处理流程。本文并没有细节展开描述每一个EventHub类的实现方法和输入事件处理的代码细节,感兴趣的同学可以去分析一下Linux系统中input事件的获取和Linux input事件的组成等。1、本文主要描述了EventHub输入设备的管理和事件获取流程描述,并没有细节上去描述;

yanl1229的博客 1026

已解决“TimeouEror [WinEror 10060由于连接方在一段时间后没有正确答复 或连接的主机没有反应,连接尝试失败“,亲测有效!!!

已解决"TimeouEror [WinEror 10060由于连接方在一段时间后没有正确答复 或连接的主机没有反应,连接尝试失败",亲测有效!!!

wbajsjhhhhh的博客 1万+

Android Input子系统 -- EventHub

前言前面其实也有提到EventHub的构造函数,里面就是创建epoll实例,然后把一些事件触发的文件描述符加入到epoll里面统一管理。 监控/dev/input/目录的iNotify文件mINotifyFd 接收Kernel驱动事件(/dev/input/eventX)的文件描述符 用来唤醒InputReader线程的管道读文件 EventHub是服务于...

zhangjie201412的专栏 1249

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Android Input Framework(二)---EventHub

1 EventHub获取输入设备数据 EventHub可以看成是输入消息的集散地,因为android支持多种输入设备,而各种设备的消息类型可能不一样,为了统一管理这些输入消息,Android提出了EventHub的概念,所有的输入事件都会通过EventHub收集,并通过EventHub传递给InputReader,这样对上层来说,就不需要关注底层设备的多样性,减少了上层使用的复杂性。EventH

fe学习之旅 2014

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

EventHub分析(二)

2, EventHub 一台移动设备中能产生输入消息的部件很多,比如键盘,触摸屏以及按键等等,EventHub主要是将这些设备产生的消息打包成一种格式,再发往上层进行处理. 首先看看EventHub的构造函数, EventHub::EventHub(void) : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId

Jack的博客 4026

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android输入事件流程中的EventHub分析及源码演示

Android2.3的输入事件流程与以前版本有了较大的不同,这里做一下详细的分析,最后我把自己分析时用的演示代码放在了这里:下面的分析都是基于这些源码的,大家可以下载下来一边看源码一边看文档。源码里只要关注FlyingEvent这个类就可以了。如果只想看一下演示结果,可以直接把包里的flying放到机器的/system/bin目录执行,打开logcat后就可以看到演示输出。运行程序时,机器屏幕会有异象产生,很正常,因为这个程序原本是用于显示SurfaceFlinger的,这次为了演示EventHub稍微改了

农场老马的专栏 2万+

Android Input子系统 HDMI外设触发触摸屏分辨率异常:1个EventHub.cpp补丁

本文分析了Android Input子系统中HDMI外设触发触摸屏分辨率异常的案例,提供了两种解决方案:修改EventHub.cpp源码或通过IDC文件配置。文章详细解释了问题根因、补丁实现及验证方案,帮助开发者快速解决类似输入设备识别问题。

weixin_34007886的博客 320

android raw event,Android Eventhub处理流程

Eventhub是在Native 的inputmanager创建的时候被创建的,inputreadthread就通过eventhub的getevent方法来源源不断的获取driver上报的input事件。bool EventHub::getEvent(RawEvent* outEvent){if (!mOpened) {mError =openPlatformInput() ? NO_ERROR...

weixin_42520277的博客 599

Android 7系统输入(二)EventHub — 原始事件的采集者

摘要: EventHub是Android输入系统的底层事件采集器,负责监听输入设备(如触摸屏、键盘)并通过epoll和inotify机制从/dev/input/eventX读取原始事件。其核心包括: 数据结构:Device记录设备信息(如fd、路径、类型掩码),RawEvent封装内核事件(含时间戳、设备ID等)。 初始化:创建epoll实例监控设备文件描述符,通过inotify监听设备增减,并扫描已有设备(如/dev/input/event*)。 事件循环:getEvents()使用epoll_wait阻

AfinalStone的专栏 246

input子系统 Android6.0输入系统之EventHub源码分析

上篇文章《Android6.0输入系统之InputManagerService构成分析》 完成了IMS的创建,接着就沿着输入系统这条路继续往下走。 在EventHub的构造函数中,它通过INotify与Epoll机制建立起对设备点增删事件及可读状态的监听。INotify是Linux内核所提供的一种文件系统变化通知机制。它可以为应用程序监控文件系统的变化,如文件的新建、删除、读写等等。它有两个基本...

sdkdlwk的博客 494
上一篇: android学习笔记5 android按键事件处理代码走读[framework]
下一篇: android学习笔记7 android简略开机流程(从u-boot 到Idle)
有梦想的胖子
博客等级 码龄16年 51粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值