06.输入系统:第10课第7节_输入系统_Reader线程_简单处理

在前面的小节中,我们对Reader线程做了总结,任务他会做三件事件。

1.获取事件
2.简单处理
3.传送给Dispather线程。

我们已经分析1.Reader线程怎么获取事件,这小节我们来讲解他是如何处理这些事件的,在Reader线程中,他只是做了简单的处理,复杂的处理是在Dispather线程中完成的。

我们先来猜测一下Reader线程会做哪些事情,会获取哪些输入事件。通过前面小节的讲解,知道Reader线程从驱动获取事件之后,会转换为RawEvent,提供给android系统使用。
在这里插入图片描述
其中type:有DEVICE_ADDED(插入设备),DEVICE_REMOVE(拔出设备),以及具体的输入事件,如按下按键,移动鼠标,触摸屏幕等等。可以看出,他们后续的处理中,都是根据type不同,进行不同的处理,简单分支图如下:
在这里插入图片描述

我们打开文件,inputReader.cpp搜索processEventsLocked,看看该函数在哪里被调用:

    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);

    { // acquire lock
        AutoMutex _l(mLock);
        mReaderIsAliveCondition.broadcast();

        if (count) {
            processEventsLocked(mEventBuffer, count);
        }

可以看到,在调用mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE)之后,接着就调用了processEventsLocked(mEventBuffer, count),他们处于InputReader::loopOnce() 这个主循环之中。进入processEventsLocked方法。

InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    for (const RawEvent* rawEvent = rawEvents; count;) {//对于每一个RawEvent都进行相应的处理。
    	if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {//根据type进行具体事件处理


		else //对设备的插入,拔出做出处理
			case EventHubInterface::DEVICE_ADDED: //如果为增加设备
				addDeviceLocked(rawEvent->when, rawEvent->deviceId);
					InputDevice* device = createDeviceLocked() //根据插入的设备类型,创建相应的InputDevice
						......
						if (keyboardSource != 0) {
       						 device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
       					......
       				mDevices.add(deviceId, device);//添加到KeyedVector<int32_t, InputDevice*> mDevices中进行监测,用于管理多个输入设备
    }
			case EventHubInterface::DEVICE_REMOVED:
			case EventHubInterface::FINISHED_DEVICE_SCAN:	
    	

大家可能觉得奇怪,在前面EventHub中InputReader::loopOnce() 分析以及对设备进行了添加,为什么这里还要在InputDevice调用mDevices.add(deviceId, device;再添加一次?这里是利用了分层的思想:

首先回顾一下EventHub中的mDevices,其中包含呢多个Device,关系与成员框图如下:
在这里插入图片描述
在InputReader中同样存在mDevices,mDevices中有多个InputDevice,每个InputDevice中都存在:
成员int32_t mId:在后续,根据每个InputDevice中的int32_t mId就能找到在EventHub.mDevices中的Device,
成员Vector<InputMapper*> mMappers:对上报的事件,用mMappers进行处理(稍后讲解)。

总结框图如下:
在这里插入图片描述
从图可以看出在InputReader层次的InputDevice负责处理事件,不用去关心fd,identifer等等,而EvenHub中的Device负责读取事件,这样分工与层次都比较明显。

我们回过头mMappers中包含了那些东西,假如我们的是键盘:

InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
	device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
		 device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
		 	mMappers.add(mapper);

对于键盘。存在一个KeyboardInputMapper对象,当输入事件是添加设备时,对其的分析就结束了。移除设备也是类似的原理。现在我们看看,真正的输入事件是如何处理的。把执行函数调用过程,复制一部分,添加相关调用过程:

InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    for (const RawEvent* rawEvent = rawEvents; count;) {//对于每一个RawEvent都进行相应的处理。
    	if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {//根据type进行具体事件处理
    		processEventsForDeviceLocked(deviceId, rawEvent, batchSize)//处理设备产生的输入事件,那么当然是真正的输入事件了
    			device->process(rawEvents, count);//此处的device为之前构造的InputDevice
    			for (size_t i = 0; i < numMappers; i++) {	
    				InputMapper* mapper = mMappers[i];
              		mapper->process(rawEvent);//该处对于键盘,执行的是KeyboardInputMapper.process(rawEvent)。
              			case EV_KEY: {
              				processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);//根据kl或者kcm文件把驱动获得的按键码转换为android的按键码
              					/*根据是否按下shfit,按下的时间是否相同构建一个args*/
              					NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState,downTime);
              					/*通知一个Listener对args进行处理*/
              					getListener()->notifyKey(&args);					

到了最后可以看到,调用getListener()->notifyKey(&args); 通知监测者处理按下的按键,那么这个监听者就是Reader_Dispatche线程(下一小节的内容)

从这里我们可以看出,Reader线程,对输入事件的处理是十分简单的,他仅仅是把从驱动获取的输入事件的scancode转化为android事件的code。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南才尽,年少无知!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值