您的位置:首页 > 移动开发 > Android开发

android 2.2 vold VolumeManager 分析

2011-01-12 14:24 253 查看
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;

}

下节分析消息接收部分
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: