Android2.2 Vold 分析-2---20110105-2
Vold 中 volumeManager分析
void NetlinkHandler::onEvent(NetlinkEvent *evt) {
VolumeManager *vm = VolumeManager::Instance();
const char *subsys = evt->getSubsystem();
if (!strcmp(subsys, "block")) {
vm->handleBlockEvent(evt); //udisk/sdcard 主要涉及这一部分,调用VolumeManager类的成员函数handleBlockEvent;
} else if (!strcmp(subsys, "switch")) {
vm->handleSwitchEvent(evt);
} else if (!strcmp(subsys, "battery")) {
} else if (!strcmp(subsys, "power_supply")) {
}
}
VolumeManager的成员函数handleBlockEvent 遍历mVolumes容器中的所有volume,进行处理;
void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
const char *devpath = evt->findParam("DEVPATH");
/* Lookup a volume to handle this device */
VolumeCollection::iterator it;
bool hit = false;
for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
if (!(*it)->handleBlockEvent(evt)) { }
//由于VolumeCollection是Volume类型的容器,所以这里应该是调用volume类的成员函数handleBlockEvent()或其子类DirectVolume的成员函数handleBlockEvent();
}
}
在我的博文 “Android Vold 分析(一)--system/vold/main.cpp-----mian函数分析”中分析了process_config函数,该函数的一个功能就是为system/etc/vold.fstab中定义的每一挂载项构建一个DirectVolume对象,然后将这个DirectVolume对象添加到容器mVolumes,所以这里执行的一定是DirectVolume类的成员函数;
volume类的成员函数handleBlockEvent()
int Volume::handleBlockEvent(NetlinkEvent *evt) {
errno = ENOSYS;
return -1;
}
DirectVolume的成员函数handleBlockEvent()
int DirectVolume::handleBlockEvent(NetlinkEvent *evt) {
const char *dp = evt->findParam("DEVPATH");
在我的博文 “Android Vold 分析(一)--system/vold/main.cpp-----mian函数分析”中分析了process_config函数,该函数的一个功能就是将system/etc/vold.fstab中定义的每一挂载的sysfs_path添加到容器mPaths;
PathCollection::iterator it;
for (it = mPaths->begin(); it != mPaths->end(); ++it) {
if (!strncmp(dp, *it, strlen(*it))) { //遍历mPaths容器,寻找与event对应的sysfs_path是否存在于容器mPaths中;
/* We can handle this disk */
int action = evt->getAction();
const char *devtype = evt->findParam("DEVTYPE");
//针对Event中的action 有四种处理方式:Add, Remove, Change,noaction;分别如下:
if (action == NetlinkEvent::NlActionAdd) {
int major = atoi(evt->findParam("MAJOR"));
int minor = atoi(evt->findParam("MINOR"));
char nodepath[255];
snprintf(nodepath,sizeof(nodepath), "/dev/block/vold/%d:%d",major, minor);
if (createDeviceNode(nodepath, major, minor)) { } //创建设备节点;
//每一种处理方式中按照devtype又分为disk和partion分别进行处理;
if (!strcmp(devtype, "disk")) {
handleDiskAdded(dp, evt);
} else {
handlePartitionAdded(dp, evt);
}
... ...
}
分析 handleDiskAdded(dp, evt)
void DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) {
mDiskMajor = atoi(evt->findParam("MAJOR"));
mDiskMinor = atoi(evt->findParam("MINOR"));
const char *tmp = evt->findParam("NPARTS"); //分区个数
if (tmp) {
mDiskNumParts = atoi(tmp);
} else {
SLOGW("Kernel block uevent missing 'NPARTS'");
mDiskNumParts = 1;
}
char msg[255];
int partmask = 0;
int i;
for (i = 1; i <= mDiskNumParts; i++) {
partmask |= (1 << i);
}
mPendingPartMap = partmask;
setState(Volume::State_Idle);
snprintf(msg, sizeof(msg), "Volume %s %s disk inserted (%d:%d)", getLabel(), getMountpoint(), mDiskMajor, mDiskMinor);
mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskInserted, msg, false); 广播disk insert消息,请求对该事件进行处理;
//这里对该消息的广播对象也就是发给谁分析一下:
mVm是DirectVolume集成自Volume类的成员调用mVm->getBroadcaster()返回的是 VolumeManager类对象的成员mBroadcaster,mBroadcast 是在main.cpp中调用vm->setBroadcaster((SocketListener *) cl)而来的,所以其实mVm->getBroadcaster()返回的是经过强制类型转换的cl对象指针((SocketListener *) cl);相当于cl->sendBroadcast(...);
*********************
class VolumeManager 部分
void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
SocketListener *getBroadcaster() { return mBroadcaster; }
*********************
所以消息发送的对象还是cl->mClients容器中的socket;
}
下节分析消息接收部分