上文描述了InputChannel的创建过程,在WmS的addWindow中,创建InputChannel后紧接着的是注册InputChannel:
if (outInputChannel != null) {
String name = win.makeInputChannelName();
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
win.mInputChannel = inputChannels[0];
inputChannels[1].transferToBinderOutParameter(outInputChannel);
mInputManager.registerInputChannel(win.mInputChannel);
}
// InputManager.java
/**
* Registers an input channel so that it can be used as an input event target.
* @param inputChannel The input channel to register.
*/
public void registerInputChannel(InputChannel inputChannel) {
if (inputChannel == null) {
throw new IllegalArgumentException("inputChannel must not be null.");
}
nativeRegisterInputChannel(inputChannel, false);
}
// com_android_server_InputChannel.cpp
status_t NativeInputManager::registerInputChannel(JNIEnv* env,
const sp& inputChannel, jobject inputChannelObj, bool monitor) {
jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
if (! inputChannelObjWeak) {
LOGE("Could not create weak reference for input channel.");
LOGE_EX(env);
return NO_MEMORY;
}
status_t status;
{
AutoMutex _l(mInputChannelRegistryLock);
ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
if (index >= 0) {
LOGE("Input channel object '%s' has already been registered",
inputChannel->getName().string());
status = INVALID_OPERATION;
goto DeleteWeakRef;
}
mInputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
}
status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
if (! status) {
// Success.
return OK;
}
// Failed!
{
AutoMutex _l(mInputChannelRegistryLock);
mInputChannelObjWeakTable.removeItem(inputChannel.get());
}
DeleteWeakRef:
env->DeleteWeakGlobalRef(inputChannelObjWeak);
return status;
}
status_t InputDispatcher::registerInputChannel(const sp& inputChannel, bool monitor) {
#if DEBUG_REGISTRATION
LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
toString(monitor));
#endif
{ // acquire lock
AutoMutex _l(mLock);
if (getConnectionIndexLocked(inputChannel) >= 0) {
LOGW("Attempted to register already registered input channel '%s'",
inputChannel->getName().string());
return BAD_VALUE;
}
sp connection = new Connection(inputChannel);
status_t status = connection->initialize();
if (status) {
LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
inputChannel->getName().string(), status);
return status;
}
int32_t receiveFd = inputChannel->getReceivePipeFd();
mConnectionsByReceiveFd.add(receiveFd, connection);
if (monitor) {
mMonitoringChannels.push(inputChannel);
}
mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
runCommandsLockedInterruptible();
} // release lock
return OK;
}
(1) 创建一个Connection对象,把创建的InputChannel给Connection的内部对象,并初始化Connection;
(2) 获得该InputChannel的receivePipeFd,代码定义在frameworks/base/included/ui/InputTransport.h中:
inline int32_t getReceivePipeFd() const { return mReceivePipeFd; }
receivePipeFd对应的是reverse[0]描述符。
(4) 调用mLooper.addFd()把receiverFd添加到Looper内部的接收描述符列表中。
native环境中的Looper类可以监控管道文件描述符,当该管道收到数据时会提到一个通知,所以无论是InputReader线程发往InputDispatcher的消息,还是客户窗口发送到InputDispatcher的消息,Looper类都可以监控到,从而InputReader可以接收到消息。