Android2.2 Vold 分析(三)---Vold 中 volumeManager分析

来源:互联网 发布:vscode css智能提示 编辑:程序博客网 时间:2024/06/13 07:02
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;
   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);                }     ...   ... }

   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(...);

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;}