[Android 13]Input系列--InputReader事件处理

hongxi.zhu 2023-7-16
Android 13

回顾

从前面的InputFlinger的启动可知,InputReader线程启动后会循环执行loopOnce()方法,然后阻塞在getEvents等待事件的上报,这里就从loopOnce获取到事件被唤醒后来分析InputReader对事件的处理。

InputReader::loopOnce()

frameworks/native/services/inputflinger/reader/InputReader.cpp

void InputReader::loopOnce() {
    
    
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    
	...
	//从EventHub中读取事件
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);

    {
    
     // acquire lock
		...
        if (count) {
    
    
        	//处理事件
            processEventsLocked(mEventBuffer, count);
        }
		...
		
    } // release lock

    // Send out a message that the describes the changed input devices.
    //如果输入设备状态改变则通过回调通知java层
    if (inputDevicesChanged) {
    
    
        mPolicy->notifyInputDevicesChanged(inputDevices);
    }

    // Flush queued events out to the listener.
    mQueuedListener.flush();
}

一、处理事件

InputReader::processEventsLocked

void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    
    
    for (const RawEvent* rawEvent = rawEvents; count;) {
    
    
        int32_t type = rawEvent->type;
        size_t batchSize = 1;
        //除了设备添加、移除、结束扫描事件之外的普通事件采用批处理方式方式处理
        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
    
    
            int32_t deviceId = rawEvent->deviceId;
            while (batchSize < count) {
    
    
            	//如果出现不符合批处理的事件(一般上面的判断已经足够)则退出本次事件流程
                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
                    rawEvent[batchSize].deviceId != deviceId) {
    
    
                    break;
                }
                batchSize += 1;
            }
            //处理普通事件(批量处理)
            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
        } else {
    
    
            switch (rawEvent->type) {
    
    
            	//如果是设备添加事件
                case EventHubInterface::DEVICE_ADDED:
                	//添加设备主要就是创建设备对应的inputDevice
                	//通过设备的class类型创建对应的mapper
                	//将对应的mapper和EventHub、inputReader关联(InputDeviceContext)
                	//然后将对应的deviceId、mapper、InputDeviceContext加入inputDevice容器中
                    addDeviceLocked(rawEvent->when, rawEvent->deviceId);
                    break;
                //如果是设备移除事件
                case EventHubInterface::DEVICE_REMOVED:
                    removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
                    break;
                //如果是设备结束扫描事件
                case EventHubInterface::FINISHED_DEVICE_SCAN:
                    handleConfigurationChangedLocked(rawEvent->when);
                    break;
                default:
                    ALOG_ASSERT(false); // can't happen
                    break;
            }
        }
        count -= batchSize;
        rawEvent += batchSize;
    }
}

InputReader::processEventsForDeviceLocked

void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
                                               size_t count) {
    
    
    auto deviceIt = mDevices.find(eventHubId);  //通过device id找到事件对应的inputDevice对象
	...
    device->process(rawEvents, count);  //调用事件对应的inputDevice对象process处理当前事件
}

InputDevice::process

frameworks/native/services/inputflinger/reader/InputDevice.cpp

void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    
    
	//按顺序分发给对应的mapper处理,要求事件按照时间顺序处理
    for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
    
    

        if (mDropUntilNextSync) {
    
      //抛弃下一个SYN事件前的所有事件
			...
        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
    
    
			...
        } else {
    
      //正常走这里
        	//通过deviceId查询mDevices中对应的mapper(这个是在设备add事件时添加的)
            for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
    
    
                mapper.process(rawEvent);
            });
        }
        --count;
    }
}

for_each_mapper_in_subdevice

frameworks/native/services/inputflinger/reader/include/InputDevice.h

    // run a function against every mapper on a specific subdevice
    inline void for_each_mapper_in_subdevice(int32_t eventHubDevice,
                                             std::function<void(InputMapper&)> f) {
    
    
        auto deviceIt = mDevices.find(eventHubDevice);
        if (deviceIt != mDevices.end()) {
    
    
            auto& devicePair = deviceIt->second;
            auto& mappers = devicePair.second;
            for (auto& mapperPtr : mappers) {
    
    
                f(*mapperPtr);
            }
        }
    }

通过rawEvent->deviceId来查询这个事件对应的设备在设备add事件时添加的mapper,这个mapper是根据deviceclass类型来决定的

MultiTouchInputMapper::process

InputReader::addDeviceLocked中可以知道触摸现在走的是MultiTouchInputMapper
frameworks/native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp

void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
    
    
    TouchInputMapper::process(rawEvent);
	//处理常规触摸EV_ABS事件,包括多指情况(多个slot)
    mMultiTouchMotionAccumulator.process(rawEvent);
}

void TouchInputMapper::process(const RawEvent* rawEvent) {
    
    
    mCursorButtonAccumulator.process(rawEvent);  //如果是光标按键事件,一般不是
    mCursorScrollAccumulator.process(rawEvent);  //如果是光标滚动事件,一般不是
    mTouchButtonAccumulator.process(rawEvent);   //如果是触摸按键事件,(手写笔有时有)

	//只有当收到一次EV_SYN事件上上报本次触摸的事件集
    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
    
    
        sync(rawEvent->when, rawEvent->readTime);
    }
}

void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
    
    
    if (rawEvent->type == EV_ABS) {
    
    
        bool newSlot = false;
        if (mUsingSlotsProtocol) {
    
      //如果支持多指触摸协议
            if (rawEvent->code == ABS_MT_SLOT) {
    
    
                mCurrentSlot = rawEvent->value;
                newSlot = true;
            }
        } else if (mCurrentSlot < 0) {
    
    
            mCurrentSlot = 0;
        }

        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
    
    
			...
        } else {
    
    
            Slot* slot = &mSlots[mCurrentSlot];
            // If mUsingSlotsProtocol is true, it means the raw pointer has axis info of
            // ABS_MT_TRACKING_ID and ABS_MT_SLOT, so driver should send a valid trackingId while
            // updating the slot.
            //如果支持多指触摸协议,那么驱动就需要上报有效的trackingId来给上层区分
            if (!mUsingSlotsProtocol) {
    
    
                slot->mInUse = true;
            }
			//根据事件的code来更新slot的信息
            switch (rawEvent->code) {
    
    
                case ABS_MT_POSITION_X:
                    slot->mAbsMTPositionX = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                case ABS_MT_POSITION_Y:
                    slot->mAbsMTPositionY = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                case ABS_MT_TOUCH_MAJOR:
                    slot->mAbsMTTouchMajor = rawEvent->value;
                    break;
                case ABS_MT_TOUCH_MINOR:
                    slot->mAbsMTTouchMinor = rawEvent->value;
                    slot->mHaveAbsMTTouchMinor = true;
                    break;
                case ABS_MT_WIDTH_MAJOR:
                    slot->mAbsMTWidthMajor = rawEvent->value;
                    break;
                case ABS_MT_WIDTH_MINOR:
                    slot->mAbsMTWidthMinor = rawEvent->value;
                    slot->mHaveAbsMTWidthMinor = true;
                    break;
                case ABS_MT_ORIENTATION:
                    slot->mAbsMTOrientation = rawEvent->value;
                    break;
                case ABS_MT_TRACKING_ID:
                    if (mUsingSlotsProtocol && rawEvent->value < 0) {
    
    
                        // The slot is no longer in use but it retains its previous contents,
                        // which may be reused for subsequent touches.
                        slot->mInUse = false;
                    } else {
    
    
                        slot->mInUse = true;
                        slot->mAbsMTTrackingId = rawEvent->value;
                    }
                    break;
                case ABS_MT_PRESSURE:
                    slot->mAbsMTPressure = rawEvent->value;
                    break;
                case ABS_MT_DISTANCE:
                    slot->mAbsMTDistance = rawEvent->value;
                    break;
                case ABS_MT_TOOL_TYPE:
                    slot->mAbsMTToolType = rawEvent->value;
                    slot->mHaveAbsMTToolType = true;
                    break;
            }
        }
    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
    
    
        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
        mCurrentSlot += 1;
    }
}

TouchInputMapper::sync

void TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
    
    
	//创建一个RawState并加入mRawStatesPending列表
    // Push a new state.
    mRawStatesPending.emplace_back();
	//初始化上面的RawState, 将相关的各个mapper.process()中记录的事件的属性写入(sync)
    RawState& next = mRawStatesPending.back();
    next.clear();
    next.when = when;
    next.readTime = readTime;
	...
    // Sync touch
    //同步触摸的状态,这里是调用子类MultiTouchInputMapper的实现,将子类的process中赋值的多指触摸相关属性赋值给next
    syncTouch(when, &next);

    // The last RawState is the actually second to last, since we just added a new state
    const RawState& last =
            mRawStatesPending.size() == 1 ? mCurrentRawState : mRawStatesPending.rbegin()[1];

	...

    processRawTouches(false /*timeout*/);
}

TouchInputMapper::processRawTouches

frameworks/native/services/inputflinger/reader/mapper/TouchInputMapper.cpp

void TouchInputMapper::processRawTouches(bool timeout) {
    
    
	//如果当前事件的设备被禁用,则中断这个触摸事件集的传递
    if (mDeviceMode == DeviceMode::DISABLED) {
    
    
        // Drop all input if the device is disabled.
        cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime);
        mCurrentCookedState.clear();
        updateTouchSpots();
        return;
    }

    // Drain any pending touch states. The invariant here is that the mCurrentRawState is always
    // valid and must go through the full cook and dispatch cycle. This ensures that anything
    // touching the current state will only observe the events that have been dispatched to the
    // rest of the pipeline.
    const size_t N = mRawStatesPending.size();
    size_t count;
    for (count = 0; count < N; count++) {
    
    
        const RawState& next = mRawStatesPending[count];

        // A failure to assign the stylus id means that we're waiting on stylus data
        // and so should defer the rest of the pipeline.
        //检测手写笔id是否可以获取到,如果无法获取就中断本次触摸批事件处理
        if (assignExternalStylusId(next, timeout)) {
    
    
            break;
        }

        // All ready to go.
        clearStylusDataPendingFlags();  //移除手写笔状态相关变量
        mCurrentRawState.copyFrom(next);  //将next赋给mCurrentRawState
		...
        cookAndDispatch(mCurrentRawState.when, mCurrentRawState.readTime);
    }
    if (count != 0) {
    
    
    	//从mRawStatesPending移除本次已处理的RawState,一个RawState对应一次SYNC包含的触摸事件集
        mRawStatesPending.erase(mRawStatesPending.begin(), mRawStatesPending.begin() + count);
    }
	...
}

TouchInputMapper::cookAndDispatch

void TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t readTime) {
    
    
    // Always start with a clean state.
    mCurrentCookedState.clear();

    // Apply stylus buttons to current raw state.
    applyExternalStylusButtonState(when);  //处理手写笔按键状态

    // Handle policy on initial down or hover events.
    bool initialDown = mLastRawState.rawPointerData.pointerCount == 0 &&
            mCurrentRawState.rawPointerData.pointerCount != 0;

    uint32_t policyFlags = 0;
    bool buttonsPressed = mCurrentRawState.buttonState & ~mLastRawState.buttonState;
    if (initialDown || buttonsPressed) {
    
    
        // If this is a touch screen, hide the pointer on an initial down.
        if (mDeviceMode == DeviceMode::DIRECT) {
    
    
            getContext()->fadePointer();
        }

        if (mParameters.wake) {
    
    
            policyFlags |= POLICY_FLAG_WAKE;
        }
    }

    // Consume raw off-screen touches before cooking pointer data.
    // If touches are consumed, subsequent code will not receive any pointer data.
    //处理一些非屏幕区域的触摸行为,比如屏幕外的虚拟按键等,
    //如果本次触摸是虚拟按键,那么本次触摸事件将会被虚拟按键逻辑消费,不在往下处理
    if (consumeRawTouches(when, readTime, policyFlags)) {
    
    
        mCurrentRawState.rawPointerData.clear();
    }

    // Cook pointer data.  This call populates the mCurrentCookedState.cookedPointerData structure
    // with cooked pointer data that has the same ids and indices as the raw data.
    // The following code can use either the raw or cooked data, as needed.
    //这里就是将触摸设备(TP)的坐标范围映射到实际屏幕的坐标范围等(常识:TP的坐标不一定和屏幕的坐标对应,所以需要转化)
    cookPointerData();

    // Apply stylus pressure to current cooked state.
    applyExternalStylusTouchState(when);  处理手写笔触摸状态

    // Synthesize key down from raw buttons if needed.
    // 如果上面有处理触摸按键相关的事件,在这里会进行按键事件的分发,走按键分发逻辑(notifyKey)
    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, readTime, getDeviceId(),
                         mSource, mViewport.displayId, policyFlags, mLastCookedState.buttonState,
                         mCurrentCookedState.buttonState);

    // Dispatch the touches either directly or by translation through a pointer on screen.
    if (mDeviceMode == DeviceMode::POINTER) {
    
      //pointer光标
		...
    } else {
    
      //触摸 DeviceMode::DIRECT touchscreen
        if (!mCurrentMotionAborted) {
    
    
            updateTouchSpots();  //更新触摸点相关
            dispatchButtonRelease(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
            dispatchHoverExit(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
            dispatchTouches(when, readTime, policyFlags);  // 分发触摸事件,主要是这里
            dispatchHoverEnterAndMove(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
            dispatchButtonPress(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
        }

        if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
    
    
            mCurrentMotionAborted = false;
        }
    }

    // Synthesize key up from raw buttons if needed.
    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, readTime, getDeviceId(), mSource,
                         mViewport.displayId, policyFlags, mLastCookedState.buttonState,
                         mCurrentCookedState.buttonState);

    // Clear some transient state.
    mCurrentRawState.rawVScroll = 0;
    mCurrentRawState.rawHScroll = 0;

    // Copy current touch to last touch in preparation for the next cycle.
    mLastRawState.copyFrom(mCurrentRawState);
    mLastCookedState.copyFrom(mCurrentCookedState);
}

TouchInputMapper::cookPointerData

void TouchInputMapper::cookPointerData() {
    
    
    uint32_t currentPointerCount = mCurrentRawState.rawPointerData.pointerCount;
	
    mCurrentCookedState.cookedPointerData.clear();
    mCurrentCookedState.cookedPointerData.pointerCount = currentPointerCount;
    mCurrentCookedState.cookedPointerData.hoveringIdBits =
            mCurrentRawState.rawPointerData.hoveringIdBits;
    mCurrentCookedState.cookedPointerData.touchingIdBits =
            mCurrentRawState.rawPointerData.touchingIdBits;
    mCurrentCookedState.cookedPointerData.canceledIdBits =
            mCurrentRawState.rawPointerData.canceledIdBits;

    if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
    
    
        mCurrentCookedState.buttonState = 0;
    } else {
    
    
        mCurrentCookedState.buttonState = mCurrentRawState.buttonState;
    }


    // Walk through the the active pointers and map device coordinates onto
    // display coordinates and adjust for display orientation.
    // 遍历活动指针并将设备坐标映射到显示坐标并调整显示方向。
    // 并将相关的转化值写入mCurrentCookedState.cookedPointerData
    for (uint32_t i = 0; i < currentPointerCount; i++) {
    
    
        const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i];

        // Size
        // 长短轴大小校准
        float touchMajor, touchMinor, toolMajor, toolMinor, size;
        switch (mCalibration.sizeCalibration) {
    
    
            case Calibration::SizeCalibration::GEOMETRIC:  //几何类型
            case Calibration::SizeCalibration::DIAMETER:  //直径类型
            case Calibration::SizeCalibration::BOX:  // 方型?
            case Calibration::SizeCalibration::AREA:  //面积类型?
                if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
    
    
                    touchMajor = in.touchMajor;
                    touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
                    toolMajor = in.toolMajor;
                    toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
                    size = mRawPointerAxes.touchMinor.valid ? avg(in.touchMajor, in.touchMinor)
                                                            : in.touchMajor;
                } else if (mRawPointerAxes.touchMajor.valid) {
    
    
                    toolMajor = touchMajor = in.touchMajor;
                    toolMinor = touchMinor =
                            mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
                    size = mRawPointerAxes.touchMinor.valid ? avg(in.touchMajor, in.touchMinor)
                                                            : in.touchMajor;
                } else if (mRawPointerAxes.toolMajor.valid) {
    
    
                    touchMajor = toolMajor = in.toolMajor;
                    touchMinor = toolMinor =
                            mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
                    size = mRawPointerAxes.toolMinor.valid ? avg(in.toolMajor, in.toolMinor)
                                                           : in.toolMajor;
                } else {
    
    
					...
                }

                if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
    
    
                    uint32_t touchingCount = mCurrentRawState.rawPointerData.touchingIdBits.count();
                    if (touchingCount > 1) {
    
    
                        touchMajor /= touchingCount;
                        touchMinor /= touchingCount;
                        toolMajor /= touchingCount;
                        toolMinor /= touchingCount;
                        size /= touchingCount;
                    }
                }

                if (mCalibration.sizeCalibration == Calibration::SizeCalibration::GEOMETRIC) {
    
    
                    touchMajor *= mGeometricScale;
                    touchMinor *= mGeometricScale;
                    toolMajor *= mGeometricScale;
                    toolMinor *= mGeometricScale;
                } else if (mCalibration.sizeCalibration == Calibration::SizeCalibration::AREA) {
    
    
                    touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
                    touchMinor = touchMajor;
                    toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
                    toolMinor = toolMajor;
                } else if (mCalibration.sizeCalibration == Calibration::SizeCalibration::DIAMETER) {
    
    
                    touchMinor = touchMajor;
                    toolMinor = toolMajor;
                }

                mCalibration.applySizeScaleAndBias(&touchMajor);
                mCalibration.applySizeScaleAndBias(&touchMinor);
                mCalibration.applySizeScaleAndBias(&toolMajor);
                mCalibration.applySizeScaleAndBias(&toolMinor);
                size *= mSizeScale;
                break;
            default:
                touchMajor = 0;
                touchMinor = 0;
                toolMajor = 0;
                toolMinor = 0;
                size = 0;
                break;
        }

        // Pressure
        //压感校准
        float pressure;
        switch (mCalibration.pressureCalibration) {
    
    
            case Calibration::PressureCalibration::PHYSICAL:
            case Calibration::PressureCalibration::AMPLITUDE:
                pressure = in.pressure * mPressureScale;
                break;
            default:
                pressure = in.isHovering ? 0 : 1;
                break;
        }

        // Tilt and Orientation
        //倾斜角度和方向
        float tilt;
        float orientation;
        if (mHaveTilt) {
    
    
            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
        } else {
    
    
            tilt = 0;

            switch (mCalibration.orientationCalibration) {
    
    
                case Calibration::OrientationCalibration::INTERPOLATED:
                    orientation = in.orientation * mOrientationScale;
                    break;
                case Calibration::OrientationCalibration::VECTOR: {
    
    
                    int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
                    int32_t c2 = signExtendNybble(in.orientation & 0x0f);
                    if (c1 != 0 || c2 != 0) {
    
    
                        orientation = atan2f(c1, c2) * 0.5f;
                        float confidence = hypotf(c1, c2);
                        float scale = 1.0f + confidence / 16.0f;
                        touchMajor *= scale;
                        touchMinor /= scale;
                        toolMajor *= scale;
                        toolMinor /= scale;
                    } else {
    
    
                        orientation = 0;
                    }
                    break;
                }
                default:
                    orientation = 0;
            }
        }

        // Distance
        //距离校准
        float distance;
        switch (mCalibration.distanceCalibration) {
    
    
            case Calibration::DistanceCalibration::SCALED:
                distance = in.distance * mDistanceScale;
                break;
            default:
                distance = 0;
        }

        // Coverage
        // 覆盖校准?
        int32_t rawLeft, rawTop, rawRight, rawBottom;
        switch (mCalibration.coverageCalibration) {
    
    
            case Calibration::CoverageCalibration::BOX:
                rawLeft = (in.toolMinor & 0xffff0000) >> 16;
                rawRight = in.toolMinor & 0x0000ffff;
                rawBottom = in.toolMajor & 0x0000ffff;
                rawTop = (in.toolMajor & 0xffff0000) >> 16;
                break;
            default:
                rawLeft = rawTop = rawRight = rawBottom = 0;
                break;
        }

        // Adjust X,Y coords for device calibration
        // TODO: Adjust coverage coords?
        float xTransformed = in.x, yTransformed = in.y;
        mAffineTransform.applyTo(xTransformed, yTransformed);
        rotateAndScale(xTransformed, yTransformed);

        // Adjust X, Y, and coverage coords for input device orientation.
        float left, top, right, bottom;
		// 转换触摸设备坐标到实际的屏幕方向上的坐标
        switch (mInputDeviceOrientation) {
    
    
            case DISPLAY_ORIENTATION_90:
                left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale;
                right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale;
                bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                orientation -= M_PI_2;
                if (mOrientedRanges.haveOrientation &&
                    orientation < mOrientedRanges.orientation.min) {
    
    
                    orientation +=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            case DISPLAY_ORIENTATION_180:
                left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                orientation -= M_PI;
                if (mOrientedRanges.haveOrientation &&
                    orientation < mOrientedRanges.orientation.min) {
    
    
                    orientation +=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            case DISPLAY_ORIENTATION_270:
                left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale;
                top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale;
                orientation += M_PI_2;
                if (mOrientedRanges.haveOrientation &&
                    orientation > mOrientedRanges.orientation.max) {
    
    
                    orientation -=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            default:
                left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale;
                right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale;
                bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale;
                top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale;
                break;
        }

        // Write output coords.
        PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
        out.clear();
        out.setAxisValue(AMOTION_EVENT_AXIS_X, xTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_Y, yTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
        if (mCalibration.coverageCalibration == Calibration::CoverageCalibration::BOX) {
    
    
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
        } else {
    
    
            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
        }

        // Write output relative fields if applicable.
        uint32_t id = in.id;
        if (mSource == AINPUT_SOURCE_TOUCHPAD &&
            mLastCookedState.cookedPointerData.hasPointerCoordsForId(id)) {
    
    
            const PointerCoords& p = mLastCookedState.cookedPointerData.pointerCoordsForId(id);
            float dx = xTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_X);
            float dy = yTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_Y);
            out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, dx);
            out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, dy);
        }

        // Write output properties.
        PointerProperties& properties = mCurrentCookedState.cookedPointerData.pointerProperties[i];
        properties.clear();
        properties.id = id;
        properties.toolType = in.toolType;

        // Write id index and mark id as valid.
        mCurrentCookedState.cookedPointerData.idToIndex[id] = i;
        mCurrentCookedState.cookedPointerData.validIdBits.markBit(id);
    }
}

TouchInputMapper::dispatchTouches

void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) {
    
    
    BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
    BitSet32 lastIdBits = mLastCookedState.cookedPointerData.touchingIdBits;
    int32_t metaState = getContext()->getGlobalMetaState();
    int32_t buttonState = mCurrentCookedState.buttonState;

    if (currentIdBits == lastIdBits) {
    
      //pointer id 没有改变
        if (!currentIdBits.isEmpty()) {
    
    
            // No pointer id changes so this is a move event.
            // The listener takes care of batching moves so we don't have to deal with that here.
            // 如果pointer id 没有改变,说明是个move事件,这里不进行处理,直接分发到listener
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
                           metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, -1,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }
    } else {
    
    
        // There may be pointers going up and pointers going down and pointers moving
        // all at the same time.
        // 获取并更新四个方向pointers的值,判断本次是down、up、move的哪一种
        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
        BitSet32 dispatchedIdBits(lastIdBits.value);  //用于记录上一次分发的事件

        // Update last coordinates of pointers that have moved so that we observe the new
        // pointer positions at the same time as other pointers that have just gone up.
        //更新最后一个pointers的坐标
        bool moveNeeded =
                updateMovedPointers(mCurrentCookedState.cookedPointerData.pointerProperties,
                                    mCurrentCookedState.cookedPointerData.pointerCoords,
                                    mCurrentCookedState.cookedPointerData.idToIndex,
                                    mLastCookedState.cookedPointerData.pointerProperties,
                                    mLastCookedState.cookedPointerData.pointerCoords,
                                    mLastCookedState.cookedPointerData.idToIndex, moveIdBits);
        if (buttonState != mLastCookedState.buttonState) {
    
    
            moveNeeded = true;
        }

        // Dispatch pointer up events.
        //分发up事件
        while (!upIdBits.isEmpty()) {
    
    
            uint32_t upId = upIdBits.clearFirstMarkedBit();  //这个id应该和downId相同(看上面的更新四个方向BitSet32可知)
            bool isCanceled = mCurrentCookedState.cookedPointerData.canceledIdBits.hasBit(uplastIdBitsId);
            if (isCanceled) {
    
    
                ALOGI("Canceling pointer %d for the palm event was detected.", upId);
            }
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_UP, 0,
                           isCanceled ? AMOTION_EVENT_FLAG_CANCELED : 0, metaState, buttonState, 0,
                           mLastCookedState.cookedPointerData.pointerProperties,
                           mLastCookedState.cookedPointerData.pointerCoords,
                           mLastCookedState.cookedPointerData.idToIndex, dispatchedIdBits, upId,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
            dispatchedIdBits.clearBit(upId);  //up事件分发后,重置dispatchedIdBits
            mCurrentCookedState.cookedPointerData.canceledIdBits.clearBit(upId);
        }

        // Dispatch move events if any of the remaining pointers moved from their old locations.
        // Although applications receive new locations as part of individual pointer up
        // events, they do not generally handle them except when presented in a move event.
        //分发move事件
        if (moveNeeded && !moveIdBits.isEmpty()) {
    
    
            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
                           metaState, buttonState, 0,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits, -1,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }

        // Dispatch pointer down events using the new pointer locations.
        //分发down事件
        while (!downIdBits.isEmpty()) {
    
    
            uint32_t downId = downIdBits.clearFirstMarkedBit();
            dispatchedIdBits.markBit(downId); //记录分发的down事件

            if (dispatchedIdBits.count() == 1) {
    
    
                // First pointer is going down.  Set down time.
                mDownTime = when;
            }

            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_DOWN,
                           0, 0, metaState, buttonState, 0,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits,
                           downId, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }
    }
}

TouchInputMapper::dispatchMotion

void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t policyFlags,
                                      uint32_t source, int32_t action, int32_t actionButton,
                                      int32_t flags, int32_t metaState, int32_t buttonState,
                                      int32_t edgeFlags, const PointerProperties* properties,
                                      const PointerCoords* coords, const uint32_t* idToIndex,
                                      BitSet32 idBits, int32_t changedId, float xPrecision,
                                      float yPrecision, nsecs_t downTime) {
    
    
    PointerCoords pointerCoords[MAX_POINTERS];
    PointerProperties pointerProperties[MAX_POINTERS];
    uint32_t pointerCount = 0;
    while (!idBits.isEmpty()) {
    
    
        uint32_t id = idBits.clearFirstMarkedBit();
        uint32_t index = idToIndex[id];
        pointerProperties[pointerCount].copyFrom(properties[index]);
        pointerCoords[pointerCount].copyFrom(coords[index]);

        if (changedId >= 0 && id == uint32_t(changedId)) {
    
    
            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        }

        pointerCount += 1;
    }

    ALOG_ASSERT(pointerCount != 0);

    if (changedId >= 0 && pointerCount == 1) {
    
    
        // Replace initial down and final up action.
        // We can compare the action without masking off the changed pointer index
        // because we know the index is 0.
        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
    
    
            action = AMOTION_EVENT_ACTION_DOWN;
        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
    
    
            if ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) {
    
    
                action = AMOTION_EVENT_ACTION_CANCEL;
            } else {
    
    
                action = AMOTION_EVENT_ACTION_UP;
            }
        } else {
    
    
            // Can't happen.
            ALOG_ASSERT(false);
        }
    }
    float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    if (mDeviceMode == DeviceMode::POINTER) {
    
      //是否是pointer模式,触摸是DIRECT模式,所以一般不设置这个
        mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
    }
    //获取当前物理屏幕的id(有些设备有多个屏幕)
    //获取displayId主要从DisplayViewport中,而DisplayViewport主要来自:
    // 1. inputDevice中通过configure中指定。
  	// 2. WindowManagerService指定。
  	// 3.通过idc文件中的唯一id或显示类型获取匹配的Viewport
    const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
    const int32_t deviceId = getDeviceId();
    std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();  //有关视频触摸事件的,一般不是
    std::for_each(frames.begin(), frames.end(),
                  [this](TouchVideoFrame& frame) {
    
     frame.rotate(this->mInputDeviceOrientation); });
    //创建NotifyMotionArgs对象
    NotifyMotionArgs args(getContext()->getNextId(), when, readTime, deviceId, source, displayId,
                          policyFlags, action, actionButton, flags, metaState, buttonState,
                          MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
                          pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
                          downTime, std::move(frames));
     // 调用mapper创建时关联的context持有的QueuedInputListener对象的notifyMotion
     // 这里是getListener是UnwantedInteractionBlocker
    getListener().notifyMotion(&args);
}

QueuedInputListener::notifyMotion

void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
    
    
    ALOGD("hongxi.zhu: QueuedInputListener::notifyMotion() -> mArgsQueue.emplace_back(NotifyMotionArgs)");
    traceEvent(__func__, args->id);
    mArgsQueue.emplace_back(std::make_unique<NotifyMotionArgs>(*args));
}

QueuedInputListener::notifyMotion只是将NotifyMotionArgs加入当前listener对象的mArgsQueue列表, 到这里我们InputReader::processEventsLocked方法就执行结束,回到loopOnce()中继续往下执行到mQueuedListener.flush(),开始事件的传递。

二、mQueuedListener.flush()事件传递

接着上面,在InputReader::loopOnce()中往下执行到mQueuedListener.flush()

QueuedInputListener::flush()

frameworks/native/services/inputflinger/InputListener.cpp

void QueuedInputListener::flush() {
    
    
    for (const std::unique_ptr<NotifyArgs>& args : mArgsQueue) {
    
    
        args->notify(mInnerListener);  //args这里是前面传进来的NotifyMotionArgs
    }
    mArgsQueue.clear();
}

NotifyMotionArgs::notify

frameworks/native/services/inputflinger/InputListener.cpp

void NotifyMotionArgs::notify(InputListenerInterface& listener) const {
    
    
    listener.notifyMotion(this);
}

这个listener是一个InputListenerInterface子类对象,到底是哪个呢?回顾下InputManager的构造方法,
frameworks/native/services/inputflinger/InputManager.cpp

InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    
    
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    mClassifier = std::make_unique<InputClassifier>(*mDispatcher);
    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier);
    mReader = createInputReader(readerPolicy, *mBlocker);
}

mDispatchermClassifiermBlocker都是InputListenerInterface的子类,从构造方法的传参得出事件传递的过程:
InputReader->UnwantedInteractionBlocker->InputClassifier->InputDispatcher
结合类继承关系,可知上面InputReader::loopOnce()中的mQueuedListenerUnwantedInteractionBlocker,调用它的flush方法(这几个子类都没有实现flush方法,所以执行的是QueuedInputListenerflush方法),QueuedInputListener中的mInnerListenerUnwantedInteractionBlocker,那么listener.notifyMotion(this)实际就是:UnwantedInteractionBlocker::notifyMotion(NotifyMotionArgs)

UnwantedInteractionBlocker::notifyMotion

frameworks/native/services/inputflinger/UnwantedInteractionBlocker.cpp

void UnwantedInteractionBlocker::notifyMotion(const NotifyMotionArgs* args) {
    
    
    {
    
     // acquire lock
        std::scoped_lock lock(mLock);
        const std::vector<NotifyMotionArgs> processedArgs =
                mPreferStylusOverTouchBlocker.processMotion(*args);
        for (const NotifyMotionArgs& loopArgs : processedArgs) {
    
    
            notifyMotionLocked(&loopArgs);
        }
    } // release lock

    // Call out to the next stage without holding the lock
    mQueuedListener.flush();
}

UnwantedInteractionBlocker::notifyMotionLocked

void UnwantedInteractionBlocker::notifyMotionLocked(const NotifyMotionArgs* args) {
    
    
    auto it = mPalmRejectors.find(args->deviceId);
    const bool sendToPalmRejector = it != mPalmRejectors.end() && isFromTouchscreen(args->source);
    if (!sendToPalmRejector) {
    
      //如果不支持手掌误触处理,走这里,一般走这里
    	//调用UnwantedInteractionBlocker中持有的QueuedListener对象的notifyMotion
    	//mQueuedListener这里是
        mQueuedListener.notifyMotion(args);  //一般走这里, 按照前面
        return;
    }
	//如果支持手掌误触
    std::vector<NotifyMotionArgs> processedArgs = it->second.processMotion(*args);
processedArgs.size());
    for (const NotifyMotionArgs& loopArgs : processedArgs) {
    
    
        mQueuedListener.notifyMotion(&loopArgs);  //同理这里的mQueuedListener是InputClassifier
    }
}

然后又是同样的走法notifyMotion->flush->notifyMotion, mInnerListenerInputClassifier

QueuedInputListener::notifyMotion

void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
    
    
    traceEvent(__func__, args->id);
    mArgsQueue.emplace_back(std::make_unique<NotifyMotionArgs>(*args));
}

void QueuedInputListener::flush() {
    
    
    for (const std::unique_ptr<NotifyArgs>& args : mArgsQueue) {
    
    
   	    //args这里是前面传进来的NotifyMotionArgs,mInnerListener是InputClassifier
        args->notify(mInnerListener);
    }
    mArgsQueue.clear();
}

void NotifyMotionArgs::notify(InputListenerInterface& listener) const {
    
    
    listener.notifyMotion(this);
}

InputClassifier::notifyMotion

void InputClassifier::notifyMotion(const NotifyMotionArgs* args) {
    
    
    {
    
     // acquire lock
        std::scoped_lock lock(mLock);
        // MotionClassifier is only used for touch events, for now
        const bool sendToMotionClassifier = mMotionClassifier && isTouchEvent(*args);
        if (!sendToMotionClassifier) {
    
      //目前模拟器走这里,真机不清楚
            mQueuedListener.notifyMotion(args);
        } else {
    
    
            NotifyMotionArgs newArgs(*args);
            newArgs.classification = mMotionClassifier->classify(newArgs);
            mQueuedListener.notifyMotion(&newArgs);
        }
    } // release lock
    mQueuedListener.flush();
}

然后又是同样的走法notifyMotion->flush->notifyMotion, mInnerListenerInputDispatcher

QueuedInputListener::notifyMotion

void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
    
    
    traceEvent(__func__, args->id);
    mArgsQueue.emplace_back(std::make_unique<NotifyMotionArgs>(*args));
}

void QueuedInputListener::flush() {
    
    
    for (const std::unique_ptr<NotifyArgs>& args : mArgsQueue) {
    
    
   	    //args这里是前面传进来的NotifyMotionArgs,mInnerListener是InputClassifier
        args->notify(mInnerListener);
    }
    mArgsQueue.clear();
}

InputDispatcher::notifyMotion

void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
    
    
	...
    uint32_t policyFlags = args->policyFlags;
    policyFlags |= POLICY_FLAG_TRUSTED;

    android::base::Timer t;
    //回调wms中的interceptMotionBeforeQueueingNonInteractive方法
    mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);

    bool needWake = false;
    {
    
     // acquire lock
        mLock.lock();
		...

        // Just enqueue a new motion event.
        //创建一个MotionEntry对象,将NotifyMotionArgs转化为MotionEntry
        std::unique_ptr<MotionEntry> newEntry =
                std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
                                              args->source, args->displayId, policyFlags,
                                              args->action, args->actionButton, args->flags,
                                              args->metaState, args->buttonState,
                                              args->classification, args->edgeFlags,
                                              args->xPrecision, args->yPrecision,
                                              args->xCursorPosition, args->yCursorPosition,
                                              args->downTime, args->pointerCount,
                                              args->pointerProperties, args->pointerCoords);
		...
		//将MotionEntry加入InboundQueue
        needWake = enqueueInboundEventLocked(std::move(newEntry)); 
        mLock.unlock();
    } // release lock

    if (needWake) {
    
    
        mLooper->wake();  //唤醒InputDispatcher线程,处理InboundQueue中的MotionEntry
    }
}

InputDispatcher::enqueueInboundEventLocked

bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
    
    
    bool needWake = mInboundQueue.empty();
    mInboundQueue.push_back(std::move(newEntry));
    EventEntry& entry = *(mInboundQueue.back());
    traceInboundQueueLengthLocked();

    switch (entry.type) {
    
    
        case EventEntry::Type::KEY: {
    
    
      		...
            break;
        }

        case EventEntry::Type::MOTION: {
    
    
            LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
                                "Unexpected untrusted event.");
            if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
    
    
                mNextUnblockedEvent = mInboundQueue.back();
                needWake = true;
            }
            break;
			...
    }

    return needWake;
}

到此,InputReader线程就将事件传递到InputDispatcher线程,InputDispatcher线程被唤醒开始处理触摸事件,而InputReader线程继续循环执行loopOnce()方法,再次阻塞在getEvents方法中等待事件的上报。

猜你喜欢

转载自blog.csdn.net/qq_40731414/article/details/131753029
今日推荐