Android Input (4) -- inputDispatcher到ViewRootImpl

Link:

Android Input (1) -- InputManagerService启动

Android Input (2) -- inputReader

Android Input (3) -- inputDispatcher

Android Input (4) -- inputDispatcher到ViewRootImpl

Android Input (5) -- ViewRootImpl 的事件分发(Activity ViewGroup View )

Android Input (6) -- PhoneWindowManager中Power,BACK等按键处理流程

Android Input (7) -- 模块的锁检测

Android Input (8) -- ANR input event原理


目录

1.1 publishKeyEvent后,向fd写入event触发回调

1.2 handleEvent回调处理

2.1 NativeInputEventReceiver ::consumeEvents

2.2 gInputEventReceiverClassInfo.dispatchInputEvent

2.3 ViewRootImpl.java dispatchInputEvent/enqueueInputEvent

2.4 finishIn

3.1 sendFinishedSignal

3.2 sendUnchainedFinishedSignal

4.1 handleReceiveCallback

4.2 InputPublisher.receiveFinishedSignal

4.3 finishDispatchCycleLocked

4.4 onDispatchCycleFinishedLocked

4.5 runCommandsLockedInterruptible

4.6 doDispatchCycleFinishedLockedInterruptible


 

流程图

 

 

1.1 publishKeyEvent后,向fd写入event触发回调

 

@frameworks/native/libs/input/InputTransport.cpp
status_t InputPublisher::publishKeyEvent(
    ...
    return mChannel->sendMessage(&msg);  //sendMessage
}

InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
        mChannel(channel) {
}

//写入mfd  
status_t InputChannel::sendMessage(const InputMessage* msg) {
    do {
        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
    } while (nWrite == -1 && errno == EINTR);
    return OK;
}

1.2 handleEvent回调处理

frameworks\base\core\java\android\view\ViewRootImpl.java

WindowInputEventReceiver 的父类为InputEventReceiver

 

 final class WindowInputEventReceiver extends InputEventReceiver {
        public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
            super(inputChannel, looper);
        }
 }
frameworks\base\core\java\android\view\InputEventReceiver.java

public InputEventReceiver(InputChannel inputChannel, Looper looper) {
        mInputChannel = inputChannel;
        mMessageQueue = looper.getQueue();
        mReceiverPtr = nativeInit(new WeakReference<InputEventReceiver>(this),
                inputChannel, mMessageQueue);

        mCloseGuard.open("dispose");
    }
frameworks\base\core\jni\android_view_InputEventReceiver.cpp

static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
        jobject inputChannelObj, jobject messageQueueObj) {
    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
            inputChannelObj);
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    //NativeInputEventReceiver 实现了 LooperCallback ,处理Looper的事件
    sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,
            receiverWeak, inputChannel, messageQueue);
    status_t status = receiver->initialize(); //初始化
    receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object
    return reinterpret_cast<jlong>(receiver.get());
}

frameworks\base\core\jni\android_view_InputEventReceiver.cpp

这里mInputConsumer将持有inputChannel

 

NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env,
        jobject receiverWeak, const sp<InputChannel>& inputChannel,
        const sp<MessageQueue>& messageQueue) :
        mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
        mInputConsumer(inputChannel), mMessageQueue(messageQueue),
        mBatchedInputEventPending(false), mFdEvents(0) {
}

frameworks\native\libs\input\InputTransport.cpp

InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
        mResampleTouch(isTouchResamplingEnabled()),
        mChannel(channel), mMsgDeferred(false) {
}
frameworks\base\core\jni\android_view_InputEventReceiver.cpp

status_t NativeInputEventReceiver::initialize() {
    setFdEvents(ALOOPER_EVENT_INPUT);
    return OK;
}

frameworks\base\core\jni\android_view_InputEventReceiver.cpp

void NativeInputEventReceiver::setFdEvents(int events) {
    if (mFdEvents != events) {
        mFdEvents = events;
        int fd = mInputConsumer.getChannel()->getFd(); //获取通道文件描述符
        if (events) {
            //往消息循环加事件, this 参数 表示消息处理由本接收器处理 handEvent
            mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL);
        } else {
            mMessageQueue->getLooper()->removeFd(fd);
        }
    }
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
    if (events & ALOOPER_EVENT_INPUT) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL);    //consumeEvents 消耗事件
        return status == OK || status == NO_MEMORY ? 1 : 0;
    }

    if (events & ALOOPER_EVENT_OUTPUT) {
        for (size_t i = 0; i < mFinishQueue.size(); i++) {
            const Finish& finish = mFinishQueue.itemAt(i);
            status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled);   //2 sendFinishedSignal向inputDispatcher finish signal
            if (status) {
                mFinishQueue.removeItemsAt(0, i);
                ...
                }
            }
        }
    }
}

2.1 NativeInputEventReceiver ::consumeEvents

 

status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
        bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
    bool skipCallbacks = false;
    for (;;) {
        status_t status = mInputConsumer.consume(&mInputEventFactory,
                consumeBatches, frameTime, &seq, &inputEvent, &displayId,
                &motionEventType, &touchMoveNum, &flag);

           env->CallVoidMethod(receiverObj.get(),
               gInputEventReceiverClassInfo.dispatchMotionEventInfo, motionEventType, touchMoveNum);

            env->CallVoidMethod(receiverObj.get(),
                    gInputEventReceiverClassInfo.dispatchBatchedInputEventPending);

         if (inputEventObj) {
            env->CallVoidMethod(receiverObj.get(),
                    gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj,   //gInputEventReceiverClassInfo.dispatchInputEvent
                    displayId);
            if (env->ExceptionCheck()) {
                ALOGE("Exception dispatching input event.");
                skipCallbacks = true;
            }
            env->DeleteLocalRef(inputEventObj);
        }
    }
}

2.2 gInputEventReceiverClassInfo.dispatchInputEvent

 

@/frameworks/base/core/java/android/view/InputEventReceiver.java
    @SuppressWarnings("unused")
    private void dispatchMotionEventInfo(int motionEventType, int touchMoveNum) {
        try {
            if (mChoreographer == null)
                mChoreographer = Choreographer.getInstance();

            if (mChoreographer != null)
                mChoreographer.setMotionEventInfo(motionEventType, touchMoveNum);
        } catch (Exception e) {
            Log.e(TAG, "cannot invoke setMotionEventInfo.");
        }
    }

private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
    mSeqMap.put(event.getSequenceNumber(), seq);
    onInputEvent(event, displayId);
}

2.3 ViewRootImpl.java dispatchInputEvent/enqueueInputEvent

还记得上面InputEventReceiver初始化时的流程吗?是通过setView--->new WindowInputEventReceiver--->new InputEventReceiver--->new NativeInputEventReceiver这样一步一步创建的。

通过上述的JNI调用,会调用到WindowInputEventReceiver的dispatchInputEvent方法,不过由于WindowInputEventReceiver并没有自己实现这个方法,因此会调用父类InputEventReceiver::dispatchInputEvent,内部会真正调用到WindowInputEventReceiver::onInputEvent

@frameworks/base/core/java/android/view/ViewRootImpl.java
final class WindowInputEventReceiver extends InputEventReceiver {
    public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
        super(inputChannel, looper);
    }

    @Override
    public void onInputEvent(InputEvent event, int displayId) {
        enqueueInputEvent(event, this, 0, true);
    }

void enqueueInputEvent(InputEvent event,
        InputEventReceiver receiver, int flags, boolean processImmediately) {

    QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
    QueuedInputEvent last = mPendingInputEventTail;
    if (processImmediately) {
        doProcessInputEvents();
    } else {
        scheduleProcessInputEvents();
    }
}

void doProcessInputEvents() {
    while (mPendingInputEventHead != null) {
        QueuedInputEvent q = mPendingInputEventHead;
        mPendingInputEventHead = q.mNext;
        q.mNext = null;

        deliverInputEvent(q);
    }
}

//处理完事件后就会finishInputEvent来完成事件分发操作
private void deliverInputEvent(QueuedInputEvent q) {
    if (mInputEventConsistencyVerifier != null) {
        mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
    }
    InputStage stage;
    if (stage != null) {
        stage.deliver(q);
    } else {
        finishInputEvent(q);
    }
}

2.4 finishIn

 private void finishInputEvent(QueuedInputEvent q) {
        if (q.mReceiver != null) {
            boolean handled = (q.mFlags & QueuedInputEvent.FLAG_FINISHED_HANDLED) != 0;
            q.mReceiver.finishInputEvent(q.mEvent, handled);
        } else {
            q.mEvent.recycleIfNeededAfterDispatch();
        }
        recycleQueuedInputEvent(q);
    }



 mReceiver.finishInputEvent
 
public final void finishInputEvent(InputEvent event, boolean handled) {
    if (mReceiverPtr == 0) {
        ...
    } else {
        int index = mSeqMap.indexOfKey(event.getSequenceNumber());
        if (index < 0) {
            ...
        } else {
            int seq = mSeqMap.valueAt(index);
            mSeqMap.removeAt(index);
            //经过层层调用,
            nativeFinishInputEvent(mReceiverPtr, seq, handled);
        }
    }
    event.recycleIfNeededAfterDispatch();
}

3.1 sendFinishedSignal

[-> InputTransport.cpp ::InputConsumer]

 

 

status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
    ...

    size_t seqChainCount = mSeqChains.size();
    if (seqChainCount) {
        uint32_t currentSeq = seq;
        uint32_t chainSeqs[seqChainCount];
        size_t chainIndex = 0;
        for (size_t i = seqChainCount; i-- > 0; ) {
             const SeqChain& seqChain = mSeqChains.itemAt(i);
             if (seqChain.seq == currentSeq) {
                 currentSeq = seqChain.chain;
                 chainSeqs[chainIndex++] = currentSeq;
                 mSeqChains.removeAt(i);
             }
        }
        status_t status = OK;
        while (!status && chainIndex-- > 0) {
            //[见小节3.5.1]
            status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
        }
        if (status) {
            // An error occurred so at least one signal was not sent, reconstruct the chain.
            do {
                SeqChain seqChain;
                seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
                seqChain.chain = chainSeqs[chainIndex];
                mSeqChains.push(seqChain);
            } while (chainIndex-- > 0);
            return status;
        }
    }

    return sendUnchainedFinishedSignal(seq, handled);
}

3.2 sendUnchainedFinishedSignal

[-> InputTransport.cpp ::InputConsumer]

 

status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
    InputMessage msg;
    msg.header.type = InputMessage::TYPE_FINISHED;
    msg.body.finished.seq = seq;
    msg.body.finished.handled = handled;
    return mChannel->sendMessage(&msg);
}

通过InputChannel->sendMessage,将TYPE_FINISHED类型的消息,发送回InputDispatcher线程。

 

4.1 handleReceiveCallback

InputDispatcher接收finish signal处理,并移除waitQueue

[-> InputDispatcher]

 

int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
    InputDispatcher* d = static_cast<InputDispatcher*>(data);
    {
        AutoMutex _l(d->mLock);
        ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);

        bool notify;
        sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
        if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
            ...
            nsecs_t currentTime = now();
            bool gotOne = false;
            status_t status;
            for (;;) {
                uint32_t seq;
                bool handled;
                //【见小节4.4】
                status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
                if (status) {
                    break;
                }
                //【见小节4.5】
                d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
                gotOne = true;
            }
            if (gotOne) {
                d->runCommandsLockedInterruptible(); //执行命令【见小节4.6】
                if (status == WOULD_BLOCK) {
                    return 1;
                }
            }
            notify = status != DEAD_OBJECT || !connection->monitor;
        } else {
            ...
             //input channel被关闭或者发生错误
        }

        //取消注册channel
        d->unregisterInputChannelLocked(connection->inputChannel, notify);
        return 0;
    }
}

4.2 InputPublisher.receiveFinishedSignal

[-> InputTransport.cpp]

 

status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {

    InputMessage msg;
    //接收消息
    status_t result = mChannel->receiveMessage(&msg);
    if (result) {
        *outSeq = 0;
        *outHandled = false;
        return result;
    }
    if (msg.header.type != InputMessage::TYPE_FINISHED) {
        return UNKNOWN_ERROR; //发生错误
    }
    *outSeq = msg.body.finished.seq;
    *outHandled = msg.body.finished.handled;
    return OK;
}

4.3 finishDispatchCycleLocked

[-> InputDispatcher.cpp]

void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
        const sp<Connection>& connection, uint32_t seq, bool handled) {

    connection->inputPublisherBlocked = false;

    if (connection->status == Connection::STATUS_BROKEN
            || connection->status == Connection::STATUS_ZOMBIE) {
        return;
    }

    //通知系统准备启动下一次分发流程【见小节4.5.1】
    onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
}

 

4.4 onDispatchCycleFinishedLocked

[-> InputDispatcher.cpp]

 

void InputDispatcher::onDispatchCycleFinishedLocked(
        nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
    //向mCommandQueue添加命令
    CommandEntry* commandEntry = postCommandLocked(
            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
    commandEntry->connection = connection;
    commandEntry->eventTime = currentTime;
    commandEntry->seq = seq;
    commandEntry->handled = handled;
}

4.5 runCommandsLockedInterruptible

[-> InputDispatcher.cpp]

bool InputDispatcher::runCommandsLockedInterruptible() {
    if (mCommandQueue.isEmpty()) {
        return false;
    }

    do {
        //从mCommandQueue队列的头部取出第一个元素【见小节4.6.1】
        CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();

        Command command = commandEntry->command;
        //此处调用的命令隐式地包含'LockedInterruptible'
        (this->*command)(commandEntry);

        commandEntry->connection.clear();
        delete commandEntry;
    } while (! mCommandQueue.isEmpty());
    return true;
}

 

可以队列中的元素至少有doDispatchCycleFinishedLockedInterruptible。

4.6 doDispatchCycleFinishedLockedInterruptible

[-> InputDispatcher.cpp]

将dispatchEntry事件从等待队列(waitQueue)中移除

 

void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
        CommandEntry* commandEntry) {
    sp<Connection> connection = commandEntry->connection;
    nsecs_t finishTime = commandEntry->eventTime;
    uint32_t seq = commandEntry->seq;
    bool handled = commandEntry->handled;

    //获取分发事件
    DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
    if (dispatchEntry) {
        nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
        //打印出所有分发时间超过2s的事件
        if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
            String8 msg;
            msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
                    connection->getWindowName(), eventDuration * 0.000001f);
            dispatchEntry->eventEntry->appendDescription(msg);
            ALOGI("%s", msg.string());
        }

        bool restartEvent;
        if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
            KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
            restartEvent = afterKeyEventLockedInterruptible(connection,
                    dispatchEntry, keyEntry, handled);
        } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
            ...
        } else {
            ...
        }

        if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
            //将dispatchEntry事件从等待队列(waitQueue)中移除
            connection->waitQueue.dequeue(dispatchEntry);
            if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
                connection->outboundQueue.enqueueAtHead(dispatchEntry);
            } else {
                releaseDispatchEntryLocked(dispatchEntry);
            }
        }

        //启动下一个事件处理循环。
        startDispatchCycleLocked(now(), connection);
    }
}

 

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值