ActivityThread调用handleLaunchActivity > handleResumeActivity
r.window = r.activity.getWindow(); View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; wm.addView(decor, l); }wm对应WindowManagerGlobal.java,在调用wm.addView时, 会new一个ViewRootImpl,并调用ViewRootImpl的setView wm.addView()
root = new ViewRootImpl(view.getContext(), display); ... root.setView(view, wparams, panelParentView);
setView()会通过aidl调用WindowManagerService窗口管理服务
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mInputChannel); ...... if (mInputChannel != null) { if (mInputQueueCallback != null) { mInputQueue = new InputQueue(); mInputQueueCallback.onInputQueueCreated(mInputQueue); } mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, Looper.myLooper()); }
mWindowSession.addToDisplay最终会调用到addWindow函数
它会在WindowManagerService服务端创建一个socket pair,封装到InputChannel中
并将读端Fd返回给app端,app端会将这个Fd挂到looper中去监听
frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, InputChannel outInputChannel) { ...... if (outInputChannel != null && (attrs.inputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) { String name = win.makeInputChannelName(); InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); win.setInputChannel(inputChannels[0]); inputChannels[1].transferTo(outInputChannel); mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle); }
frameworks/base/core/java/android/view/InputChannel.java
public static InputChannel[] openInputChannelPair(String name) { if (name == null) { throw new IllegalArgumentException("name must not be null"); } if (DEBUG) { Slog.d(TAG, "Opening input channel pair '" + name + "'"); } return nativeOpenInputChannelPair(name); }
frameworks/base/core/jni/android_view_InputChannel.cpp
static jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env, jclass clazz, jstring nameObj) { const char* nameChars = env->GetStringUTFChars(nameObj, NULL); String8 name(nameChars); env->ReleaseStringUTFChars(nameObj, nameChars); sp<InputChannel> serverChannel; sp<InputChannel> clientChannel; status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel); if (result) { String8 message; message.appendFormat("Could not open input channel pair. status=%d", result); jniThrowRuntimeException(env, message.string()); return NULL; } jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL); if (env->ExceptionCheck()) { return NULL; } jobject serverChannelObj = android_view_InputChannel_createInputChannel(env, new NativeInputChannel(serverChannel)); if (env->ExceptionCheck()) { return NULL; } jobject clientChannelObj = android_view_InputChannel_createInputChannel(env, new NativeInputChannel(clientChannel)); if (env->ExceptionCheck()) { return NULL; } env->SetObjectArrayElement(channelPair, 0, serverChannelObj); env->SetObjectArrayElement(channelPair, 1, clientChannelObj); return channelPair; }
在android 4.4中是通过socket pair实现全双工通信的
之前的版本实现方式是建立两个pipe和一个共享内存区,socket的方式更简洁方便
frameworks/native/libs/input/InputTransport.cpp
status_t InputChannel::openInputChannelPair(const String8& name, sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) { int sockets[2]; if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) { status_t result = -errno; ALOGE("channel '%s' ~ Could not create socket pair. errno=%d", name.string(), errno); outServerChannel.clear(); outClientChannel.clear(); return result; } int bufferSize = SOCKET_BUFFER_SIZE; setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); String8 serverChannelName = name; serverChannelName.append(" (server)"); outServerChannel = new InputChannel(serverChannelName, sockets[0]); String8 clientChannelName = name; clientChannelName.append(" (client)"); outClientChannel = new InputChannel(clientChannelName, sockets[1]); return OK; }
frameworks/base/core/java/android/view/InputChannel.java
public void transferTo(InputChannel outParameter) { if (outParameter == null) { throw new IllegalArgumentException("outParameter must not be null"); } nativeTransferTo(outParameter); }
frameworks/base/core/jni/android_view_InputChannel.cpp
static void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj, jobject otherObj) { if (android_view_InputChannel_getNativeInputChannel(env, otherObj) != NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Other object already has a native input channel."); return; } NativeInputChannel* nativeInputChannel = android_view_InputChannel_getNativeInputChannel(env, obj); android_view_InputChannel_setNativeInputChannel(env, otherObj, nativeInputChannel); android_view_InputChannel_setNativeInputChannel(env, obj, NULL); }
接下来看看app端的InputEvent接受者WindowInputEventReceiver
new WindowInputEventReceiver时调用super构造函数:
public InputEventReceiver(InputChannel inputChannel, Looper looper) { if (inputChannel == null) { throw new IllegalArgumentException("inputChannel must not be null"); } if (looper == null) { throw new IllegalArgumentException("looper must not be null"); } mInputChannel = inputChannel; mMessageQueue = looper.getQueue(); mReceiverPtr = nativeInit(new WeakReference(this), inputChannel, mMessageQueue); mCloseGuard.open("dispose"); }
nativeInit调用到native层的nativeInit,参数中的InputChannel在
frameworks/native/include/input/InputTransport.h中定义
还定义了InputPublisher, InputConsumer,
它们的实现在frameworks/native/libs/input/InputTransport.cpp
frameworks/base/core/jni/android_view_InputEventReceiver.cpp
static jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject inputChannelObj, jobject messageQueueObj) { spnativeInit()中取得native层的InputChannel和messageQueue,然后作为参数创建 native层的NativeInputEventReceiver,NativeInputEventReceiver中创建了一个mInputConsumer 接着调用initialize初始化,initialize会把InputChannel的fd挂到looper中去监听 给looper设置的回调为this,会调用NativeInputEventReceiver::handleEventinputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); if (inputChannel == NULL) { jniThrowRuntimeException(env, "InputChannel is not initialized."); return 0; } sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } sp receiver = new NativeInputEventReceiver(env, receiverWeak, inputChannel, messageQueue); status_t status = receiver->initialize(); if (status) { String8 message; message.appendFormat("Failed to initialize input event receiver. status=%d", status); jniThrowRuntimeException(env, message.string()); return 0; } receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object return reinterpret_cast (receiver.get()); }
NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env, jobject receiverWeak, const sp& inputChannel, const sp & messageQueue) : mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mInputConsumer(inputChannel), mMessageQueue(messageQueue), mBatchedInputEventPending(false), mFdEvents(0) { } status_t NativeInputEventReceiver::initialize() { setFdEvents(ALOOPER_EVENT_INPUT); return OK; } void NativeInputEventReceiver::setFdEvents(int events) { if (mFdEvents != events) { mFdEvents = events; int fd = mInputConsumer.getChannel()->getFd(); if (events) { 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_ERROR | ALOOPER_EVENT_HANGUP)) { return 0; // remove the callback } if (events & ALOOPER_EVENT_INPUT) { JNIEnv* env = AndroidRuntime::getJNIEnv(); status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL); mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); return status == OK || status == NO_MEMORY ? 1 : 0; } if (events & ALOOPER_EVENT_OUTPUT) { ...... } return 1; }
consumeEvents通过mInputConsumer.consume获得InputEvent,
然后调用Java层的InputEventReceiver的dispatchInputEvent
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) { ...... InputEvent* inputEvent; status_t status = mInputConsumer.consume(&mInputEventFactory, consumeBatches, frameTime, &seq, &inputEvent); ...... jobject inputEventObj; switch (inputEvent->getType()) { case AINPUT_EVENT_TYPE_KEY: inputEventObj = android_view_KeyEvent_fromNative(env, static_cast(inputEvent)); break; ...... if (inputEventObj) { env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEvent); }
consume会先调用mChannel->receiveMessage取出InputMessage消息,
然后从该消息创建一个keyEvent(initializeKeyEvent)
status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) { *outSeq = 0; *outEvent = NULL; while (!*outEvent) { if (mMsgDeferred) { // mMsg contains a valid input message from the previous call to consume // that has not yet been processed. mMsgDeferred = false; } else { // Receive a fresh message. status_t result = mChannel->receiveMessage(&mMsg); ...... } switch (mMsg.header.type) { case InputMessage::TYPE_KEY: { KeyEvent* keyEvent = factory->createKeyEvent(); if (!keyEvent) return NO_MEMORY; initializeKeyEvent(keyEvent, &mMsg); *outSeq = mMsg.body.key.seq; *outEvent = keyEvent; break; } case AINPUT_EVENT_TYPE_MOTION: { .... }
recv会从前面创建的mFd这个socket中去读数据
status_t InputChannel::receiveMessage(InputMessage* msg) { ssize_t nRead; do { nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT); } while (nRead == -1 && errno == EINTR); ...... }
与receiveMessage对应的是publishKeyEvent:
status_t InputPublisher::publishKeyEvent( uint32_t seq, int32_t deviceId, int32_t source, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount, nsecs_t downTime, nsecs_t eventTime) { InputMessage msg; msg.header.type = InputMessage::TYPE_KEY; msg.body.key.seq = seq; msg.body.key.deviceId = deviceId; msg.body.key.source = source; msg.body.key.action = action; msg.body.key.flags = flags; msg.body.key.keyCode = keyCode; msg.body.key.scanCode = scanCode; msg.body.key.metaState = metaState; msg.body.key.repeatCount = repeatCount; msg.body.key.downTime = downTime; msg.body.key.eventTime = eventTime; return mChannel->sendMessage(&msg); } status_t InputChannel::sendMessage(const InputMessage* msg) { size_t msgLength = msg->size(); ssize_t nWrite; do { nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); } while (nWrite == -1 && errno == EINTR); .... }
NativeInputEventReceiver::consumeEvents接着会调用dispatchInputEvent,
dispatchInputEvent调用到前面ViewRootImpl中的WindowInputEventReceiver的dispatchInputEvent,
进而调用onInputEvent:
@Override public void onInputEvent(InputEvent event) { enqueueInputEvent(event, this, 0, true); }
通过加断点调试,可以看到WindowInputEventReceiver.dispatchInputEvent之后的调用堆栈列表
【WindowInputEventReceiver.dispatchInputEvent调用堆栈】
InputMethodManager$ImeInputEventSender(InputEventSender).sendInputEvent(int, InputEvent) line: 131 InputMethodManager.sendInputEventOnMainLooperLocked(InputMethodManager$PendingEvent) line: 1658 InputMethodManager.dispatchInputEvent(InputEvent, Object, InputMethodManager$FinishedInputEventCallback, Handler) line: 1621 ViewRootImpl$ImeInputStage.onProcess(ViewRootImpl$QueuedInputEvent) line: 3698 ViewRootImpl$ImeInputStage(ViewRootImpl$InputStage).deliver(ViewRootImpl$QueuedInputEvent) line: 3399 ViewRootImpl$ViewPreImeInputStage(ViewRootImpl$InputStage).onDeliverToNext(ViewRootImpl$QueuedInputEvent) line: 3449 ViewRootImpl$ViewPreImeInputStage(ViewRootImpl$InputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3418 ViewRootImpl$ViewPreImeInputStage(ViewRootImpl$InputStage).apply(ViewRootImpl$QueuedInputEvent, int) line: 3426 ViewRootImpl$ViewPreImeInputStage(ViewRootImpl$InputStage).deliver(ViewRootImpl$QueuedInputEvent) line: 3399 ViewRootImpl$NativePreImeInputStage(ViewRootImpl$InputStage).onDeliverToNext(ViewRootImpl$QueuedInputEvent) line: 3449 ViewRootImpl$NativePreImeInputStage(ViewRootImpl$InputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3418 ViewRootImpl$NativePreImeInputStage(ViewRootImpl$AsyncInputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3525 ViewRootImpl$NativePreImeInputStage(ViewRootImpl$InputStage).apply(ViewRootImpl$QueuedInputEvent, int) line: 3426 ViewRootImpl$NativePreImeInputStage(ViewRootImpl$AsyncInputStage).apply(ViewRootImpl$QueuedInputEvent, int) line: 3582 ViewRootImpl$NativePreImeInputStage(ViewRootImpl$InputStage).deliver(ViewRootImpl$QueuedInputEvent) line: 3399 ViewRootImpl.deliverInputEvent(ViewRootImpl$QueuedInputEvent) line: 5602 ViewRootImpl.doProcessInputEvents() line: 5582 ViewRootImpl.enqueueInputEvent(InputEvent, InputEventReceiver, int, boolean) line: 5553 ViewRootImpl$WindowInputEventReceiver.onInputEvent(InputEvent) line: 5682 ViewRootImpl$WindowInputEventReceiver(InputEventReceiver).dispatchInputEvent(int, InputEvent) line: 185 MessageQueue.nativePollOnce(int, int) line: not available [native method] MessageQueue.next() line: 138 Looper.loop() line: 123 ActivityThread.main(String[]) line: 5017 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 515 ZygoteInit$MethodAndArgsCaller.run() line: 779 ZygoteInit.main(String[]) line: 595 NativeStart.main(String[]) line: not available [native method]
ImeInputEventSender->sendInputEvent会给输入法发送input event,然后将该event defer起来
等输入法处理完后,输入法会再给ViewRootImpl的looper写数据
looper回调ImeInputEventSender的dispatchInputEventFinished
最终将input event分发到用户的activity中
【ImeInputEventSender的dispatchInputEventFinished调用堆栈】
MainActivity.dispatchKeyEvent(KeyEvent) line: 23 PhoneWindow$DecorView.dispatchKeyEvent(KeyEvent) line: 1962 ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl$QueuedInputEvent) line: 3852 ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl$QueuedInputEvent) line: 3826 ViewRootImpl$ViewPostImeInputStage(ViewRootImpl$InputStage).deliver(ViewRootImpl$QueuedInputEvent) line: 3399 ViewRootImpl$NativePostImeInputStage(ViewRootImpl$InputStage).onDeliverToNext(ViewRootImpl$QueuedInputEvent) line: 3449 ViewRootImpl$NativePostImeInputStage(ViewRootImpl$InputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3418 ViewRootImpl$NativePostImeInputStage(ViewRootImpl$AsyncInputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3525 ViewRootImpl$NativePostImeInputStage(ViewRootImpl$InputStage).apply(ViewRootImpl$QueuedInputEvent, int) line: 3426 ViewRootImpl$NativePostImeInputStage(ViewRootImpl$AsyncInputStage).apply(ViewRootImpl$QueuedInputEvent, int) line: 3582 ViewRootImpl$NativePostImeInputStage(ViewRootImpl$InputStage).deliver(ViewRootImpl$QueuedInputEvent) line: 3399 ViewRootImpl$EarlyPostImeInputStage(ViewRootImpl$InputStage).onDeliverToNext(ViewRootImpl$QueuedInputEvent) line: 3449 ViewRootImpl$EarlyPostImeInputStage(ViewRootImpl$InputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3418 ViewRootImpl$EarlyPostImeInputStage(ViewRootImpl$InputStage).apply(ViewRootImpl$QueuedInputEvent, int) line: 3426 ViewRootImpl$EarlyPostImeInputStage(ViewRootImpl$InputStage).deliver(ViewRootImpl$QueuedInputEvent) line: 3399 ViewRootImpl$ImeInputStage(ViewRootImpl$InputStage).onDeliverToNext(ViewRootImpl$QueuedInputEvent) line: 3449 ViewRootImpl$ImeInputStage(ViewRootImpl$InputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3418 ViewRootImpl$ImeInputStage(ViewRootImpl$AsyncInputStage).forward(ViewRootImpl$QueuedInputEvent) line: 3558 ViewRootImpl$ImeInputStage.onFinishedInputEvent(Object, boolean) line: 3718 InputMethodManager$PendingEvent.run() line: 2010 InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager$PendingEvent, boolean) line: 1704 InputMethodManager.finishedInputEvent(int, boolean, boolean) line: 1695 InputMethodManager$ImeInputEventSender.onInputEventFinished(int, boolean) line: 1987 InputMethodManager$ImeInputEventSender(InputEventSender).dispatchInputEventFinished(int, boolean) line: 141 MessageQueue.nativePollOnce(int, int) line: not available [native method] MessageQueue.next() line: 138 Looper.loop() line: 123 ActivityThread.main(String[]) line: 5017 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 515 ZygoteInit$MethodAndArgsCaller.run() line: 779 ZygoteInit.main(String[]) line: 595 NativeStart.main(String[]) line: not available [native method]
下面看看详细过程
ImeInputStage:onProcess->dispatchInputEvent->sendInputEventOnMainLooperLocked
通过ImeInputEventSender->sendInputEvent给输入法发送数据
int sendInputEventOnMainLooperLocked(PendingEvent p) { if (mCurChannel != null) { if (mCurSender == null) { mCurSender = new ImeInputEventSender(mCurChannel, mH.getLooper()); } final InputEvent event = p.mEvent; final int seq = event.getSequenceNumber(); if (mCurSender.sendInputEvent(seq, event)) { mPendingEvents.put(seq, p); Trace.traceCounter(Trace.TRACE_TAG_INPUT, PENDING_EVENT_COUNTER, mPendingEvents.size()); Message msg = mH.obtainMessage(MSG_TIMEOUT_INPUT_EVENT, p); msg.setAsynchronous(true); mH.sendMessageDelayed(msg, INPUT_METHOD_NOT_RESPONDING_TIMEOUT); return DISPATCH_IN_PROGRESS; } Log.w(TAG, "Unable to send input event to IME: " + mCurId + " dropping: " + event); } return DISPATCH_NOT_HANDLED; }
ImeInputEventSender构造时传入的mCurChannel, mH.getLooper()都是InputMethodManager的成员
InputMethodManager在ViewRootImpl的构造函数中初始化:
mWindowSession = WindowManagerGlobal.getWindowSession();
InputMethodManager的mMainLooper就是activity的主UI Looper,
mCurChannel是activity的onWindowFocusChanged调用之后设置的
ViewRootImpl的ViewRootHandler处理MSG_WINDOW_FOCUS_CHANGED时
imm.onWindowFocus > startInputInner > mService.windowGainedFocus返回输入法服务的channel
if (hasWindowFocus) { if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) { imm.onWindowFocus(mView, mView.findFocus(), mWindowAttributes.softInputMode, !mHasHadWindowFocus, mWindowAttributes.flags); } // Clear the forward bit. We can just do this directly, since // the window manager doesn't care about it. mWindowAttributes.softInputMode &= ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; ((WindowManager.LayoutParams)mView.getLayoutParams()) .softInputMode &= ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; mHasHadWindowFocus = true; }
res = mService.windowGainedFocus(mClient, windowGainingFocus, controlFlags, softInputMode, windowFlags, tba, servedContext); .... setInputChannelLocked(res.channel);
具体发送过程:
sendInputEvent->nativeSendKeyEvent
frameworks/base/core/jni/android_view_InputEventSender.cpp
static jboolean nativeSendKeyEvent(JNIEnv* env, jclass clazz, jint senderPtr, jint seq, jobject eventObj) { spsender = reinterpret_cast (senderPtr); KeyEvent event; android_view_KeyEvent_toNative(env, eventObj, &event); status_t status = sender->sendKeyEvent(seq, &event); return !status; }
sender->sendKeyEvent:
status_t NativeInputEventSender::sendKeyEvent(uint32_t seq, const KeyEvent* event) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Sending key event, seq=%u.", getInputChannelName(), seq); #endif uint32_t publishedSeq = mNextPublishedSeq++; status_t status = mInputPublisher.publishKeyEvent(publishedSeq, event->getDeviceId(), event->getSource(), event->getAction(), event->getFlags(), event->getKeyCode(), event->getScanCode(), event->getMetaState(), event->getRepeatCount(), event->getDownTime(), event->getEventTime()); if (status) { ALOGW("Failed to send key event on channel '%s'. status=%d", getInputChannelName(), status); return status; } mPublishedSeqMap.add(publishedSeq, seq); return OK; }mInputPublisher.publishKeyEvent对应前面提到的InputPublisher::publishKeyEvent 回到前面ImeInputEventSender的构造: frameworks/base/core/java/android/view/InputEventSender.java
public InputEventSender(InputChannel inputChannel, Looper looper) { if (inputChannel == null) { throw new IllegalArgumentException("inputChannel must not be null"); } if (looper == null) { throw new IllegalArgumentException("looper must not be null"); } mInputChannel = inputChannel; mMessageQueue = looper.getQueue(); mSenderPtr = nativeInit(new WeakReference(this), inputChannel, mMessageQueue); mCloseGuard.open("dispose"); }
nativeInit取得native层的inputChannel、messageQueue,
创建NativeInputEventSender并调用initialize初始化
frameworks/base/core/jni/android_view_InputEventSender.cpp
static jint nativeInit(JNIEnv* env, jclass clazz, jobject senderWeak, jobject inputChannelObj, jobject messageQueueObj) { spinputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); if (inputChannel == NULL) { jniThrowRuntimeException(env, "InputChannel is not initialized."); return 0; } sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } sp sender = new NativeInputEventSender(env, senderWeak, inputChannel, messageQueue); status_t status = sender->initialize(); if (status) { String8 message; message.appendFormat("Failed to initialize input event sender. status=%d", status); jniThrowRuntimeException(env, message.string()); return 0; } sender->incStrong(gInputEventSenderClassInfo.clazz); // retain a reference for the object return reinterpret_cast (sender.get()); } status_t NativeInputEventSender::initialize() { int receiveFd = mInputPublisher.getChannel()->getFd(); mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL); return OK; }
initialize过程与NativeInputEventReceiver的initialize类似
都是将读端Fd挂到looper上去监听,回调为this,指向NativeInputEventSender
int NativeInputEventSender::handleEvent(int receiveFd, int events, void* data) { if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { return 0; // remove the callback } if (!(events & ALOOPER_EVENT_INPUT)) { ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " "events=0x%x", getInputChannelName(), events); return 1; } JNIEnv* env = AndroidRuntime::getJNIEnv(); status_t status = receiveFinishedSignals(env); mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); return status == OK || status == NO_MEMORY ? 1 : 0; }
当输入法处理完event唤醒这里的looper时,handleEvent被调用
receiveFinishedSignals:
status_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) { ScopedLocalRefsenderObj(env, NULL); bool skipCallbacks = false; for (;;) { uint32_t publishedSeq; bool handled; status_t status = mInputPublisher.receiveFinishedSignal(&publishedSeq, &handled); if (status) { if (status == WOULD_BLOCK) { return OK; } return status; } ssize_t index = mPublishedSeqMap.indexOfKey(publishedSeq); if (index >= 0) { uint32_t seq = mPublishedSeqMap.valueAt(index); mPublishedSeqMap.removeItemsAt(index); if (!skipCallbacks) { if (!senderObj.get()) { senderObj.reset(jniGetReferent(env, mSenderWeakGlobal)); if (!senderObj.get()) { ALOGW("channel '%s' ~ Sender object was finalized " "without being disposed.", getInputChannelName()); return DEAD_OBJECT; } } env->CallVoidMethod(senderObj.get(), gInputEventSenderClassInfo.dispatchInputEventFinished, jint(seq), jboolean(handled)); if (env->ExceptionCheck()) { ALOGE("Exception dispatching finished signal."); skipCallbacks = true; } } } } }
mInputPublisher.receiveFinishedSignal与mInputConsumer.consume类似,
receiveFinishedSignal接收处理完成信号
调用java层的dispatchInputEventFinished进一步处理
这就回到了前面的【ImeInputEventSender的dispatchInputEventFinished调用堆栈】
也就是应用自己的MainActivity.dispatchKeyEvent会被调用
至此,app端的InputEvent传递过程分析完毕!