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

Android SDCard UnMounted 流程分析(二) 推荐

2012-03-23 14:13 337 查看
上一篇讲到通过NetlinkManager发送uevent 命令到NetlinkHandler 的onEvent,代码如下:

void NetlinkHandler::onEvent(NetlinkEvent *evt) {

VolumeManager *vm = VolumeManager::Instance();

const char *subsys = evt->getSubsystem();

if (!subsys) {

SLOGW("No subsystem found in netlink event");

return;

}

SLOGD("NetlinkHandler:OnEvent subsys values is %s",subsys);

if (!strcmp(subsys, "block")) {

SLOGD("NetlinkHandler:onEvent");

vm->handleBlockEvent(evt);

}

}
复制代码

在NetlinkHandler 里面得一个VolumeManager,当收到的命令为block时调用VolumnManager的handleBlockEvent,如上加红加粗的代码。
handleBlockEvent实则是通过一个循环将事先将main事先读取的配置文件:etc/vold.fstab存进VolumeCollection,得到VolumeCollection的对象,然后调用Volume 的handleBlockEvent,如代码:
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)) {

#ifdef NETLINK_DEBUG

SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel());

#endif

hit = true;

break;

}

}

if (!hit) {

#ifdef NETLINK_DEBUG

SLOGW("No volumes handled block event for '%s'", devpath);

#endif

}
复制代码

看一下Volume 的handleblockEvent代码:
int Volume::handleBlockEvent(NetlinkEvent *evt) {

errno = ENOSYS;

return -1;
复制代码

看起来好像没做什么事,其实真的实现在于Volume 的子类,DirectVolume,DirectVolme 中重写了handleBlockEvent,看代码:
int DirectVolume::handleBlockEvent(NetlinkEvent *evt) {

const char *dp = evt->findParam("DEVPATH");

PathCollection::iterator it;

for (it = mPaths->begin(); it != mPaths->end(); ++it) {

if (!strncmp(dp, *it, strlen(*it))) {

/* We can handle this disk */

int action = evt->getAction();

const char *devtype = evt->findParam("DEVTYPE");

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)) {

SLOGE("Error making device node '%s' (%s)", nodepath,

strerror(errno));

}

if (!strcmp(devtype, "disk")) {

handleDiskAdded(dp, evt);

} else {

handlePartitionAdded(dp, evt);

}

} else if (action == NetlinkEvent::NlActionRemove) {

if (!strcmp(devtype, "disk")) {

handleDiskRemoved(dp, evt);

} else {

SLOGD("DirectVolume:handleBlockEvent--->handlePartitionRemoved");

handlePartitionRemoved(dp, evt);

}

} else if (action == NetlinkEvent::NlActionChange) {

if (!strcmp(devtype, "disk")) {

handleDiskChanged(dp, evt);

} else {

handlePartitionChanged(dp, evt);

}

} else {

SLOGW("Ignoring non add/remove/change event");

}

return 0;

}

}

errno = ENODEV;

return -1;

}
复制代码

因为我的板子还未完善,所以这里它认为我的sdcard是一个分区,但无关紧要,原理一样,就根据分区的代码跟踪。:handlePartitionRemoved,由于代码过多,只贴出核心代码:
void DirectVolume::handlePartitionRemoved(const char *devpath, NetlinkEvent *evt) {

if ((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev) {

/*

* Yikes, our mounted partition is going away!

*/

snprintf(msg, sizeof(msg), "Volume %s %s bad removal (%d:%d)",

getLabel(), getMountpoint(), major, minor);

SLOGD("DirectVolume:(dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev:%d,msg is :%s.",mCurrentlyMountedKdev,msg);

mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval,

msg, false);


if (mVm->cleanupAsec(this, true)) {

SLOGE("Failed to cleanup ASEC - unmount will probably fail!");

}

if (Volume::unmountVol(true, false)) {

SLOGE("Failed to unmount volume on bad removal (%s)",

strerror(errno));

// XXX: At this point we're screwed for now

} else {

SLOGD("Crisis averted");

}

}

}
复制代码

到此,直接调用父类的unmountVol方法,unmountVol会通过setState通知框架状态改变。代码太多,只推荐核心代码:
int Volume::unmountVol(bool force, bool revert) {

setState(Volume::State_Unmounting);

}
复制代码

而setState会通过socket将msg消息传给框架
mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeStateChange,

msg, false);
复制代码

接下去的步骤是关于socket的操作,就不深入了。

小结

   到了这一步,Vold 向上层反馈的动作基本己经完成,下一篇文章将会讲解Framework 如何取得Vold 反馈过来的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android SDCARD UNMOUNTED