前几天补习了一下Linux下的c编程,今天重新理一下RIL.java与rild之间的通信。
在RIL.java的RILReceiver类中,有一个LocalSocket,这个就是传输的套接字。
外部调用的函数应该是send,然后跟到RILSender类的EVENT_SEND,有个LocalSocket对象,但发送的方式是s.getOutputStream.write(dataLength);和s.getOutputStream().write(data);这马上让我联想到应该是用了文件描述符。
现在,先找到对应的文件描述符。
自然的,在LocalSocket类中找到方法getOutputStream(),发现其执行的是implCreateIfNeeded();和impl.getOutputStream();
细看
implCreateIfNeeded() -> impl.create(true);
private LocalSocketImpl impl;
查看LocalSocketImpl类中的create方法和getOutputStream方法。
create -> fd = create_native(stream);
getOutputStream -> return fos = new SocketOutputStream();
最终查看SocketOutputStream的write方法
FileDescriptor myFd = fd;
writeba_native(b, off, len, myFd);
好,到目前为止,我们都在java代码上,现在应该看看native代码了,
查看frameworks/base/core/jni/android_net_LocalSocketImpl.cpp中create_native和writeba_native对应的函数
static jobject socket_create(JNIEnv *env, jobject object, jboolean stream){
ret = socket(PF_LOCAL, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
return jniCreateFileDescriptor(env, ret);
}
static void socket_writeba(JNIEnv *env, jobject object, jbyteArray buffer, jint off, jint len, jobject fileDescriptor){
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
err = socket_write_all(env, object, fd, byteBuffer + off, len); -----------> sendmsg(fd, &msg, MSG_NOSIGNAL);
}
注意上面加红加粗的代码socket,即RIL层传输的方式就是socket。
man sendmsg:
send a message on a socket