android 2.2 vold VolumeManager 分析

来源:互联网 发布:淘宝中国制造可信吗 编辑:程序博客网 时间:2024/06/06 08:52

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;

}
下节分析消息接收部分

原创粉丝点击