android /system/vold源码分析(5)
2016-06-10 22:43
513 查看
CommandListener
继承关系:
SocketListener ---> FrameworkListener ---> CommandListener
对比NetlinkHandle的继承关系:
SocketListener ---> NetlinkListener ---> NetlinkHandler
nm->start()执行流程
(1)nm->start() 即 NetlinkManager::start()
(2)调用NetlinkHandler::start()
(3)调用SocketListener::startListener()
CommandListener:: startListener ()
当执行CommandListener:: startListener ()时,它的调用即是调用SocketListener::startListener()。但二者使用的socket不同,NetlinkHandler在调用前创建了一个socket,但CommandListener在SocketListener::startListener()中通过调用android_get_control_socket(mSocketName)获得socket,相关代码如下:
int SocketListener::startListener() {
if (!mSocketName && mSock == -1) {
SLOGE("Failed to start unbound listener");
errno = EINVAL;
return -1;
} else if (mSocketName) {
if ((mSock = android_get_control_socket(mSocketName)) < 0) {
SLOGE("Obtaining file descriptor socket '%s' failed: %s",
mSocketName, strerror(errno));
return -1;
}
SLOGV("got mSock = %d for %s", mSock, mSocketName);
}
SocketListener有两个构造函数,
SocketListener::SocketListener(int socketFd, bool listen) {
init(NULL, socketFd, listen, false);
}
SocketListener::SocketListener(const char *socketName, bool listen, bool useCmdNum) {
init(socketName, -1, listen, useCmdNum);
}
NetlinkHandler在构造时使用的是第一个,它直接指定了socketFd,并且指定socketName为NULL:
mHandler = new NetlinkHandler(mSock); //代码在NetlinkManager::start()中
NetlinkHandler::NetlinkHandler(int listenerSocket) :
NetlinkListener(listenerSocket) {
}
//父类NetlinkListener的构造函数
NetlinkListener::NetlinkListener(int socket) :
SocketListener(socket, false) {
mFormat = NETLINK_FORMAT_ASCII;
}
CommandListener在构造时使用的是第二个,它指定了socketName,但没有指定socketFd:
CommandListener::CommandListener() :
FrameworkListener("vold", true) {
registerCmd(new DumpCmd());
registerCmd(new VolumeCmd());
registerCmd(new AsecCmd());
registerCmd(new ObbCmd());
registerCmd(new StorageCmd());
registerCmd(new XwarpCmd());
registerCmd(new CryptfsCmd());
registerCmd(new FstrimCmd());
}
FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
SocketListener(socketName, true, withSeq) {
init(socketName, withSeq);
}
再回到android_get_control_socket函数,这里的参数是上面构造函数指定的“vold”,此函数的代码在socket.h中:
根据参数mSocketName, 加上前缀ANDROID_SOCKET_,即字符串ANDROID_SOCKET_vold,调用getenv获取到相应socket的文件描述符。vold会在init.rc中创建这个socket:
service vold /system/bin/vold
class core
socket vold stream 0660 root mount
ioprio be 2
继承关系:
SocketListener ---> FrameworkListener ---> CommandListener
对比NetlinkHandle的继承关系:
SocketListener ---> NetlinkListener ---> NetlinkHandler
nm->start()执行流程
(1)nm->start() 即 NetlinkManager::start()
(2)调用NetlinkHandler::start()
(3)调用SocketListener::startListener()
CommandListener:: startListener ()
当执行CommandListener:: startListener ()时,它的调用即是调用SocketListener::startListener()。但二者使用的socket不同,NetlinkHandler在调用前创建了一个socket,但CommandListener在SocketListener::startListener()中通过调用android_get_control_socket(mSocketName)获得socket,相关代码如下:
int SocketListener::startListener() {
if (!mSocketName && mSock == -1) {
SLOGE("Failed to start unbound listener");
errno = EINVAL;
return -1;
} else if (mSocketName) {
if ((mSock = android_get_control_socket(mSocketName)) < 0) {
SLOGE("Obtaining file descriptor socket '%s' failed: %s",
mSocketName, strerror(errno));
return -1;
}
SLOGV("got mSock = %d for %s", mSock, mSocketName);
}
SocketListener有两个构造函数,
SocketListener::SocketListener(int socketFd, bool listen) {
init(NULL, socketFd, listen, false);
}
SocketListener::SocketListener(const char *socketName, bool listen, bool useCmdNum) {
init(socketName, -1, listen, useCmdNum);
}
NetlinkHandler在构造时使用的是第一个,它直接指定了socketFd,并且指定socketName为NULL:
mHandler = new NetlinkHandler(mSock); //代码在NetlinkManager::start()中
NetlinkHandler::NetlinkHandler(int listenerSocket) :
NetlinkListener(listenerSocket) {
}
//父类NetlinkListener的构造函数
NetlinkListener::NetlinkListener(int socket) :
SocketListener(socket, false) {
mFormat = NETLINK_FORMAT_ASCII;
}
CommandListener在构造时使用的是第二个,它指定了socketName,但没有指定socketFd:
CommandListener::CommandListener() :
FrameworkListener("vold", true) {
registerCmd(new DumpCmd());
registerCmd(new VolumeCmd());
registerCmd(new AsecCmd());
registerCmd(new ObbCmd());
registerCmd(new StorageCmd());
registerCmd(new XwarpCmd());
registerCmd(new CryptfsCmd());
registerCmd(new FstrimCmd());
}
FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
SocketListener(socketName, true, withSeq) {
init(socketName, withSeq);
}
再回到android_get_control_socket函数,这里的参数是上面构造函数指定的“vold”,此函数的代码在socket.h中:
/* * android_get_control_socket - simple helper function to get the file * descriptor of our init-managed Unix domain socket. `name' is the name of the * socket, as given in init.rc. Returns -1 on error. * * This is inline and not in libcutils proper because we want to use this in * third-party daemons with minimal modification. */ static inline int android_get_control_socket(const char *name) { char key[64] = ANDROID_SOCKET_ENV_PREFIX; const char *val; int fd; /* build our environment variable, counting cycles like a wolf ... */ #if HAVE_STRLCPY strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, name, sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); #else /* for the host, which may lack the almightly strncpy ... */ strncpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, name, sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); key[sizeof(key)-1] = '\0'; #endif val = getenv(key); if (!val) return -1; errno = 0; fd = strtol(val, NULL, 10); if (errno) return -1; return fd; }
根据参数mSocketName, 加上前缀ANDROID_SOCKET_,即字符串ANDROID_SOCKET_vold,调用getenv获取到相应socket的文件描述符。vold会在init.rc中创建这个socket:
service vold /system/bin/vold
class core
socket vold stream 0660 root mount
ioprio be 2
相关文章推荐
- 【转】 Android中退出程序的提示框
- Android初级教程小案例之单选框RadioGroup与复选框CheckBox
- Android初级教程小案例之单选框RadioGroup与复选框CheckBox
- Android 2016新技术
- android /system/vold源码分析(4)
- Android视图的绘制流程(上)——View的测量
- android中如何使用v7包
- Android初级教程Activity小案例(计算器乘法运算)
- 乐学成语(1)
- Android初级教程Activity小案例(计算器乘法运算)
- API
- android调用高版本api函数的兼容性问题
- Android lrucache 实现与使用(Android内存优化)
- Android 事件总线OTTO使用说明和源码解析
- Android IOS WebRTC 音视频开发总结(七三)-- 我为什么走上了创业这条不归路?
- 实现PHP服务器+Android客户端(Retrofit+RxJava)第二天客户端界面的大致实现
- 解决Android解析图片的OOM问题!!!
- 【Android】刮刮卡实例
- Activity之间传递数据方式
- android activity知识总结