Android应用程序键盘(Keyboard)消息处理机制分析(4)
16lz
2023-05-28
Step 18. EventHub.getEvent
这个函数定义在frameworks/base/libs/ui/EventHub.cpp文件中:
- boolEventHub::getEvent(RawEvent*outEvent)
- {
- outEvent->deviceId=0;
- outEvent->type=0;
- outEvent->scanCode=0;
- outEvent->keyCode=0;
- outEvent->flags=0;
- outEvent->value=0;
- outEvent->when=0;
- //NotethatweonlyallowonecallertogetEvent(),sodon'tneed
- //todolockinghere...onlywhenadding/removingdevices.
- if(!mOpened){
- mError=openPlatformInput()?NO_ERROR:UNKNOWN_ERROR;
- mOpened=true;
- mNeedToSendFinishedDeviceScan=true;
- }
- for(;;){
- //Reportanydevicesthathadlastbeenadded/removed.
- if(mClosingDevices!=NULL){
- device_t*device=mClosingDevices;
- LOGV("Reportingdeviceclosed: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);
- deletedevice;
- mNeedToSendFinishedDeviceScan=true;
- returntrue;
- }
- if(mOpeningDevices!=NULL){
- device_t*device=mOpeningDevices;
- LOGV("Reportingdeviceopened: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;
- returntrue;
- }
- if(mNeedToSendFinishedDeviceScan){
- mNeedToSendFinishedDeviceScan=false;
- outEvent->type=FINISHED_DEVICE_SCAN;
- outEvent->when=systemTime(SYSTEM_TIME_MONOTONIC);
- returntrue;
- }
- //Grabthenextinputevent.
- for(;;){
- //Consumebufferedinputevents,ifany.
- if(mInputBufferIndex<mInputBufferCount){
- conststructinput_event&iev=mInputBufferData[mInputBufferIndex++];
- constdevice_t*device=mDevices[mInputDeviceIndex];
- LOGV("%sgot: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;
- }else{
- outEvent->deviceId=device->id;
- }
- outEvent->type=iev.type;
- outEvent->scanCode=iev.code;
- if(iev.type==EV_KEY){
- status_terr=device->layoutMap->map(iev.code,
- &outEvent->keyCode,&outEvent->flags);
- LOGV("iev.code=%dkeyCode=%dflags=0x%08xerr=%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;
- //Useaneventtimestampinthesametimebaseas
- //java.lang.System.nanoTime()andandroid.os.SystemClock.uptimeMillis()
- //asexpectedbytherestofthesystem.
- outEvent->when=systemTime(SYSTEM_TIME_MONOTONIC);
- returntrue;
- }
- //Finishreadingalleventsfromdevicesidentifiedinpreviouspoll().
- //ThiscodeassumesthatmInputDeviceIndexisinitially0andthatthe
- //reventsmemberofpollfdisinitializedto0whenthedeviceisfirstadded.
- //SincemFDs[0]isusedforinotify,weprocessregulareventsstartingatindex1.
- mInputDeviceIndex+=1;
- if(mInputDeviceIndex>=mFDCount){
- break;
- }
- conststructpollfd&pfd=mFDs[mInputDeviceIndex];
- if(pfd.revents&POLLIN){
- int32_treadSize=read(pfd.fd,mInputBufferData,
- sizeof(structinput_event)*INPUT_BUFFER_SIZE);
- if(readSize<0){
- if(errno!=EAGAIN&&errno!=EINTR){
- LOGW("couldnotgetevent(errno=%d)",errno);
- }
- }elseif((readSize%sizeof(structinput_event))!=0){
- LOGE("couldnotgetevent(wrongsize:%d)",readSize);
- }else{
- mInputBufferCount=readSize/sizeof(structinput_event);
- mInputBufferIndex=0;
- }
- }
- }
- ......
- mInputDeviceIndex=0;
- //Pollforevents.Mindthewakelockdance!
- //Weholdawakelockatalltimesexceptduringpoll().Thisworksduetosome
- //subtlechoreography.Whenadevicedriverhaspending(unread)events,itacquires
- //akernelwakelock.However,oncethelastpendingeventhasbeenread,thedevice
- //driverwillreleasethekernelwakelock.Topreventthesystemfromgoingtosleep
- //whenthishappens,theEventHubholdsontoitsownuserwakelockwhiletheclient
- //isprocessingevents.Thusthesystemcanonlysleepiftherearenoevents
- //pendingorcurrentlybeingprocessed.
- release_wake_lock(WAKE_LOCK_ID);
- intpollResult=poll(mFDs,mFDCount,-1);
- acquire_wake_lock(PARTIAL_WAKE_LOCK,WAKE_LOCK_ID);
- if(pollResult<=0){
- if(errno!=EINTR){
- LOGW("pollfailed(errno=%d)\n",errno);
- usleep(100000);
- }
- }
- }
- }
这个函数比较长,我们一步一步来分析。
首先,如果是第一次进入到这个函数中时,成员变量mOpened的值为false,于是就会调用openPlatformInput函数来打开系统输入设备,在本文中,我们主要讨论的输入设备就是键盘了。打开了这些输入设备文件后,就可以对这些输入设备进行是监控了。如果不是第一次进入到这个函数,那么就会分析当前有没有输入事件发生,如果有,就返回这个事件,否则就会进入等待状态,等待下一次输入事件的发生。在我们这个场景中,就是等待下一次键盘事件的发生了。
我们先分析openPlatformInput函数的实现,然后回过头来分析这个getEvent函数的具体的实现。
更多相关文章
- 箭头函数的基础使用
- Python技巧匿名函数、回调函数和高阶函数
- 浅析android通过jni控制service服务程序的简易流程
- Android(安卓)bluetooth介绍(四): a2dp connect流程分析
- 第17天android:《android从零开始》视频(1-5)
- Android(安卓)EditView
- Android架构分析之使用自定义硬件抽象层(HAL)模块
- [android]在上下文菜单的选中事件中获取列表选中的元素
- android 多点触控