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) {
sp inputChannel = 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());
}
nativeInit()中取得native层的InputChannel和messageQueue,然后作为参数创建
native层的NativeInputEventReceiver,NativeInputEventReceiver中创建了一个mInputConsumer
接着调用initialize初始化,initialize会把InputChannel的fd挂到looper中去监听
给looper设置的回调为this,会调用NativeInputEventReceiver::handleEvent
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) {
sp sender =
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) {
sp inputChannel = 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) {
ScopedLocalRef senderObj(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传递过程分析完毕!