InputDispatcher接收InputReader读取到的事件,分发给对应窗口,InputDispatcher属于system_server进程和各个应用不在同一进程,它们之间的联系靠的就是InputChannel。
直接从ActivityThread的handleResumeActivity开始,Activity的DecorView会被添加到Window
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
......
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
......
a.onWindowAttributesChanged(l);
}
}
......
}
/frameworks/base/core/java/android/view/WindowManagerImpl.java
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
/frameworks/base/core/java/android/view/WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
......
root = new ViewRootImpl(view.getContext(), display);
......
root.setView(view, wparams, panelParentView);
......
}
/frameworks/base/core/java/android/view/ViewRootImpl.java
创建mInputChannel,并传递给WMS
/**
* We have one child
*/
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
......
if ((mWindowAttributes.inputFeatures
& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
mInputChannel = new InputChannel();
}
res = mWindowSession.addToDisplay(mWindow, mSeq,mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame,mAttachInfo.mContentInsets,
mAttachInfo.mStableInsets,mAttachInfo.mOutsets,
mAttachInfo.mDisplayCutout, mInputChannel,
mTempInsets);
......
}
/frameworks/base/services/core/java/com/android/server/wm/Session.java
@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
Rect outStableInsets, Rect outOutsets,
DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
InsetsState outInsetsState) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel,
outInsetsState);
}
/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq,
LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
InsetsState outInsetsState) {
......
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, session.mUid,
session.mCanAddInternalSystemWindow);
final boolean openInputChannels = (outInputChannel != null
&& (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
if (openInputChannels) {
win.openInputChannel(outInputChannel);
}
......
}
void openInputChannel(InputChannel outInputChannel) {
if (mInputChannel != null) {
throw new IllegalStateException("Window already has an input channel.");
}
String name = getName();
//创建InputChannelPair
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
//服务端InputChannel
mInputChannel = inputChannels[0];
//客户端InputChannel
mClientChannel = inputChannels[1];
mInputWindowHandle.token = mClient.asBinder();
if (outInputChannel != null) {
//将客户端InputChannel发送回ViewRootImpl
mClientChannel.transferTo(outInputChannel);
mClientChannel.dispose();
mClientChannel = null;
} else {
// If the window died visible, we setup a dummy input channel, so that taps
// can still detected by input monitor channel, and we can relaunch the app.
// Create dummy event receiver that simply reports all events as handled.
mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);
}
//将服务端InputChannel注册到InputDispatcher
mWmService.mInputManager.registerInputChannel(mInputChannel, mClient.asBinder());
}
/**
* Creates a new input channel pair. One channel should be provided to the input
* dispatcher and the other to the application's input queue.
* @param name The descriptive (non-unique) name of the channel pair.
* @return A pair of input channels. The first channel is designated as the
* server channel and should be used to publish input events. The second channel
* is designated as the client channel and should be used to consume input events.
*/
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) {
ScopedUtfChars nameChars(env, nameObj);
std::string name = nameChars.c_str();
sp<InputChannel> serverChannel;
sp<InputChannel> clientChannel;
//创建Native层serverChannel和clientChannel
status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
.......
//创建java层数组,用在后面存放java层InputChannel,并返回
jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL);
......
//创建java层的server端的InputChannel对象
jobject serverChannelObj = android_view_InputChannel_createInputChannel(env,
std::make_unique<NativeInputChannel>(serverChannel));
......
//创建java层的clien端的InputChannel对象
jobject clientChannelObj = android_view_InputChannel_createInputChannel(env,
std::make_unique<NativeInputChannel>(clientChannel));
......
env->SetObjectArrayElement(channelPair, 0, serverChannelObj);
env->SetObjectArrayElement(channelPair, 1, clientChannelObj);
return channelPair;
}
此方法中创建了一对NativeInputChannel和一对socket,在InputChannel构造函数中通过setFd将两个InputChanne和两个socket一一关联上,后去可以通过getFd拿到对于InputChannel的socket连接
/frameworks/native/libs/input/InputTransport.cpp
status_t InputChannel::openInputChannelPair(const std::string& name,
sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
//一对socket数组
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.c_str(), errno);
outServerChannel.clear();
outClientChannel.clear();
return result;
}
int bufferSize = SOCKET_BUFFER_SIZE;
//对两个socker分别设置
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));
std::string serverChannelName = name;
//创建ServerChannel,后缀名+server
serverChannelName += " (server)";
//通过setFd将sockets[0]和ServerChannel关联上
outServerChannel = new InputChannel(serverChannelName, sockets[0]);
std::string clientChannelName = name;
//创建ClientChannel,后缀名+client
clientChannelName += " (client)";
//通过setFd将sockets[1]和ClientChannel关联上
outClientChannel = new InputChannel(clientChannelName, sockets[1]);
return OK;
}
InputChannel::InputChannel(const std::string& name, int fd) :
mName(name) {
......
setFd(fd);
}
此方法会创建一个java数组,一对java层InputChannel,并将一对NativeInputChannel赋值给java层InputChannel的mPtr属性,并将server端InputChannel赋值给数组0,将client端InputChannel赋值给数组1,最后将数组返回给java层
//指向java层InputChannel的mPtr属性
gInputChannelClassInfo.mPtr = GetFieldIDOrDie(env, gInputChannelClassInfo.clazz, "mPtr", "J");
static jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env,
jclass clazz, jstring nameObj) {
//创建一个java数组,大小为2,类型为InputChannel
jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL);
......
//将server端的NativeInputChannel赋值给java层的server端的InputChannel
jobject serverChannelObj = android_view_InputChannel_createInputChannel(env,
std::make_unique<NativeInputChannel>(serverChannel));
......
//将client端的NativeInputChannel赋值给java层的client端的InputChannel
jobject clientChannelObj = android_view_InputChannel_createInputChannel(env,
std::make_unique<NativeInputChannel>(clientChannel));
......
static jobject android_view_InputChannel_createInputChannel(JNIEnv* env,
std::unique_ptr<NativeInputChannel> nativeInputChannel) {
//创建java层inputChannel对象
jobject inputChannelObj = env->NewObject(gInputChannelClassInfo.clazz,
gInputChannelClassInfo.ctor);
//当inputChannel不为空
if (inputChannelObj) {
//给InputChannel的mPtr属性赋值为NativeInputChannel
android_view_InputChannel_setNativeInputChannel(env, inputChannelObj,
nativeInputChannel.release());
}
return inputChannelObj;
}
static void android_view_InputChannel_setNativeInputChannel(JNIEnv* env, jobject inputChannelObj,
NativeInputChannel* nativeInputChannel) {
//jni方法,给inputChannelObj对象的gInputChannelClassInfo.mPtr属性赋值为reinterpret_cast(nativeInputChannel)
env->SetLongField(inputChannelObj, gInputChannelClassInfo.mPtr,
reinterpret_cast<jlong>(nativeInputChannel));
}
//将server端InputChannel赋值给数组0的位置
env->SetObjectArrayElement(channelPair, 0, serverChannelObj);
//将client端InputChannel赋值给数组0的位置
env->SetObjectArrayElement(channelPair, 1, clientChannelObj);
//将InputChannel数组返回给java层
return channelPair;
}
通过openInputChannelPair方法已经获取得到了InputChannel数组,并且数组0的位置是server端的InputChannel,数组1的位置是client端的InputChannel
/frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void openInputChannel(InputChannel outInputChannel) {
if (mInputChannel != null) {
throw new IllegalStateException("Window already has an input channel.");
}
String name = getName();
//native层返回的InputChannel数组,server端和cilent端
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
//server端InputChannel
mInputChannel = inputChannels[0];
//client端InputChannel
mClientChannel = inputChannels[1];
mInputWindowHandle.token = mClient.asBinder();
if (outInputChannel != null) {
//将client端InputChannel传回到ViewRootImpl
mClientChannel.transferTo(outInputChannel);
mClientChannel.dispose();
mClientChannel = null;
} else {
// If the window died visible, we setup a dummy input channel, so that taps
// can still detected by input monitor channel, and we can relaunch the app.
// Create dummy event receiver that simply reports all events as handled.
mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);
}
//server端InputChannel注册到native层InputDispatcher
mWmService.mInputManager.registerInputChannel(mInputChannel, mClient.asBinder());
}
/frameworks/base/core/java/android/view/InputChannel.java
/**
* Transfers ownership of the internal state of the input channel to another
* instance and invalidates this instance. This is used to pass an input channel
* as an out parameter in a binder call.
* @param other The other input channel instance.
*/
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
/*
mClientChannel.transferTo(outInputChannel);
*/
//注意该方法参数中的otherObj和obj,otherObj代表传递下来的参数outInputChannel,obj代表调用此方法的对象mClientChannel
static void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj,
jobject otherObj) {
//当java层的outInputChannel的mPtr已经指向了一个NativeInputChannel时抛一个异常返回
if (android_view_InputChannel_getNativeInputChannel(env, otherObj) != NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Other object already has a native input channel.");
return;
}
//获取java层mClientChannel的mPtr属性,mPtr属性会指向一个NativeInputChannel对象,根据前面分析此时mClientChannel的mPtr指向client端的NativeInputChannel
NativeInputChannel* nativeInputChannel =
android_view_InputChannel_getNativeInputChannel(env, obj);
android_view_InputChannel_setNativeInputChannel(env, otherObj, nativeInputChannel);
android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
}
static NativeInputChannel* android_view_InputChannel_getNativeInputChannel(JNIEnv* env,
jobject inputChannelObj) {
//jni方法,获取inputChannelObj对象的gInputChannelClassInfo.mPtr属性
jlong longPtr = env->GetLongField(inputChannelObj, gInputChannelClassInfo.mPtr);
return reinterpret_cast<NativeInputChannel*>(longPtr);
}
static void android_view_InputChannel_setNativeInputChannel(JNIEnv* env, jobject inputChannelObj,
NativeInputChannel* nativeInputChannel) {
//jni方法,将inputChannelObj的gInputChannelClassInfo.mPtr属性赋值为nativeInputChannel
env->SetLongField(inputChannelObj, gInputChannelClassInfo.mPtr,
reinterpret_cast<jlong>(nativeInputChannel));
}
总结:上面的方法主要作用就是将mClientChannel的mPtr属性赋值给outInputChannel,并将mClientChannel的mPtr赋值为NULL,这样就实现了将mClientChannel与outInputChannel互换,outInputChannel是ViewRootImpl的传递过来的mInputChannel,达到了将mClientChannel传递个应用客户端的目的。
/frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void openInputChannel(InputChannel outInputChannel) {
if (mInputChannel != null) {
throw new IllegalStateException("Window already has an input channel.");
}
String name = getName();
//native层返回的InputChannel数组,server端和cilent端
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
//server端InputChannel
mInputChannel = inputChannels[0];
//client端InputChannel
mClientChannel = inputChannels[1];
mInputWindowHandle.token = mClient.asBinder();
if (outInputChannel != null) {
//将client端InputChannel传回到ViewRootImpl
mClientChannel.transferTo(outInputChannel);
mClientChannel.dispose();
mClientChannel = null;
} else {
// If the window died visible, we setup a dummy input channel, so that taps
// can still detected by input monitor channel, and we can relaunch the app.
// Create dummy event receiver that simply reports all events as handled.
mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);
}
//server端InputChannel注册到native层InputDispatcher
mWmService.mInputManager.registerInputChannel(mInputChannel, mClient.asBinder());
}
client端的InputChannel已经传递回了ViewRootImpl,接着看server端的InputChannel如何注册到InputDispatcher的
//server端InputChannel注册到native层InputDispatcher
mWmService.mInputManager.registerInputChannel(mInputChannel, mClient.asBinder());
/frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
/**
* Registers an input channel so that it can be used as an input event target.
* @param inputChannel The input channel to register.
* @param inputWindowHandle The handle of the input window associated with the
* input channel, or null if none.
*/
public void registerInputChannel(InputChannel inputChannel, IBinder token) {
if (inputChannel == null) {
throw new IllegalArgumentException("inputChannel must not be null.");
}
if (token == null) {
token = new Binder();
}
inputChannel.setToken(token);
//native方法
nativeRegisterInputChannel(mPtr, inputChannel, Display.INVALID_DISPLAY);
}
/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobject inputChannelObj, jint displayId) {
//ptr是java层InputManagerService中的mPtr属性,在InputManagerService初始化时指向了NativeInputManager
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
//通过java层传下来的inputChannels[0]获取到Native层的server端InputChannel
sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
inputChannelObj);
if (inputChannel == nullptr) {
throwInputChannelNotInitialized(env);
return;
}
//注册inputChannel
status_t status = im->registerInputChannel(env, inputChannel, displayId);
if (status) {
std::string message;
message += StringPrintf("Failed to register input channel. status=%d", status);
jniThrowRuntimeException(env, message.c_str());
return;
}
//设置handleInputChannelDisposed回调
android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
handleInputChannelDisposed, im);
}
/frameworks/base/core/jni/android_view_InputChannel.cpp
sp<InputChannel> android_view_InputChannel_getInputChannel(JNIEnv* env, jobject inputChannelObj) {
NativeInputChannel* nativeInputChannel =
android_view_InputChannel_getNativeInputChannel(env, inputChannelObj);
//inline sp getInputChannel() { return mInputChannel; },返回server端的Nativa层的InputChannel
return nativeInputChannel != NULL ? nativeInputChannel->getInputChannel() : NULL;
}
/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
status_t NativeInputManager::registerInputChannel(JNIEnv* /* env */,
const sp<InputChannel>& inputChannel, int32_t displayId) {
ATRACE_CALL();
return mInputManager->getDispatcher()->registerInputChannel(
inputChannel, displayId);
}
调到InputDispatcher的registerInputChannel方法,
1.此方法会创建Connection,将server端InputChannel作为参数传进去,
2.获取之前InputChannel的Fd即socket[0],将fd和connection关联,后续InputDispatch通过fd可以获取对应connection,通过connection获取server InputChannel和client InputChannel通信从而将事件分发到对应的应用窗口
3.将fd添加到Looper线程进行监听
//InputDispatcher.h
// All registered connections mapped by channel file descriptor.
KeyedVector<int, sp<Connection> > mConnectionsByFd GUARDED_BY(mLock);
status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
int32_t displayId) {
{ // acquire lock
......
//创建Connection对象
sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
//获取之前通过setFd存入的socket[0]
int fd = inputChannel->getFd();
//将fd和connection关联,后续InputDispatch通过fd可以获取对应connection,通过connection获取server InputChannel和client InputChannel通信从而将事件分发到对应的应用窗口
mConnectionsByFd.add(fd, connection);
mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
//将fd添加到Looper线程进行监听,在收到对端相应事件之后回调handleReceiveCallback
mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
} // release lock
// Wake the looper because some connections have changed.
mLooper->wake();
return OK;
}
在创建Connection时将server端的inputChannel同步传给InputPublisher的mChannel
/frameworks/native/services/inputflinger/InputDispatcher.cpp
// --- InputDispatcher::Connection ---
InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
status(STATUS_NORMAL), inputChannel(inputChannel),
monitor(monitor),
inputPublisher(inputChannel), inputPublisherBlocked(false) {
}
/frameworks/native/libs/input/InputTransport.cpp
InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
mChannel(channel) {
}
好了,从java层传下来的inputChannels[0]就已经注册到了InputDispatcher并且将对应的Fd添加到了InputDispatcher的Loop进行监听,并且传进去了一个回调handleReceiveCallback,应用端窗口处理完输入事件之后回调此方法
接着需要看inputChannels[1]的Fd是如何添加到应用端进行监听的
在上面流程addToDisplay方法执行完之后ViewRootImpl中的mInputChannel已经变成了client端的InputChannel即inputChannels[1]
/frameworks/base/core/java/android/view/ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
......
mInputChannel = new InputChannel();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel,
mTempInsets);
......
if (mInputChannel != null) {
if (mInputQueueCallback != null) {
mInputQueue = new InputQueue();
mInputQueueCallback.onInputQueueCreated(mInputQueue);
}
mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
Looper.myLooper());
}
......
}
final class WindowInputEventReceiver extends InputEventReceiver {
public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
//client端InputChannel,UI线程的looper
super(inputChannel, looper);
}
调父类InputEventReceiver构造函数
/**
* Creates an input event receiver bound to the specified input channel.
*
* @param inputChannel The input channel.
* @param looper The looper to use when invoking callbacks.
*/
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;
//UI线程的messagequeue
mMessageQueue = looper.getQueue();
//native方法,将自己,client端的InputChannel和UI线程的messagequeue传进去
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) {
//见过很多次了该方法,通过传下来的cilent端的InputChannel获取对应的native层InputChannel
sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
inputChannelObj);
if (inputChannel == NULL) {
jniThrowRuntimeException(env, "InputChannel is not initialized.");
return 0;
}
//通过传下来的messagequeue获取对于native层的messagequeue
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
//创建NativeInputEventReceiver
sp<NativeInputEventReceiver> 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<jlong>(receiver.get());
}
/frameworks/base/core/jni/android_view_InputEventReceiver.cpp
//给NativeInputEventReceiver成员变量赋值
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/base/core/jni/android_view_InputEventReceiver.cpp
status_t NativeInputEventReceiver::initialize() {
setFdEvents(ALOOPER_EVENT_INPUT);
return OK;
}
void NativeInputEventReceiver::setFdEvents(int events) {
if (mFdEvents != events) {
mFdEvents = events;
//获取client端InputChannel的Fd即socket[1]
int fd = mInputConsumer.getChannel()->getFd();
if (events) {
//将fd添加到UI线程进行监听,回调传的this
mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL);
} else {
mMessageQueue->getLooper()->removeFd(fd);
}
}
}
到此client端的Fd也已经传递到了UI线程进行监听,InputDispatch与ViewRootImpl的socket连接已经建立
当应用窗口添加到WMS会创建一个WindowState描述此窗口,接着创建一对java层InputChannel对应创建一对socket,对应创建一对native层InputChannel,还有一个server端的connection,connection,inputChannel,socket创建完成后通道就已经建立,InputDispatcher就可以将事件发送给对应窗口了
它们的联系如下:
server端:
1.java层的server端InputChannel的mPtr属性指向native层的server端InputChannel
2.native层的server端InputChannel创建时会创建server端socket,并在自己的构造方法中通过setFd将此socket存在mFd变量
3.将server端InputChannel向InputDispatch注册时会创建一个connection对象,并通过getFd方法获取到socket,以fd为key,connection为值放入一个类似map的数据结构mConnectionsByFd
client端和server一样只是少了创建connection