Android-vold源码分析之runCommand(7)

作者:gzshun. 原创作品,转载请标明出处!

说了这么多,该到执行命令的函数了,要不黄花菜都凉了。上一篇文章讲了vold如何开启接收framework下发命令的线程,最终到了runCommand函数的实现,总共有6个版本,由于重复性大,只讲VolumeCmd类的runCommand函数的实现。
VolumeCmd可以说是最重要的,该类的实现处理了list,debug,mount,unmount,format,unshare,shared等等操作,详细说明:
list: 在启动vold之后,接收的第一条命令就是list,这里是获取系统的所有磁盘对象,一般只有sd卡。
debug: 设置USB的调试模式
mount: 挂载磁盘
unmount: 卸载磁盘
format: 格式化磁盘
unshare: 关闭USB的大容量存储模式,相当于断开手机与电脑的连接
shared: 开启USB的大容量存储模式,相当于手机与电脑连接,并挂载在电脑

下面把该函数的源码贴出来,一目了然,程序员,代码说话:

int CommandListener::VolumeCmd::runCommand(SocketClient *cli, int argc, char **argv) { dumpArgs(argc, argv, -1); if (argc < 2) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false); return 0; } VolumeManager *vm = VolumeManager::Instance(); int rc = 0; if (!strcmp(argv[1], "list")) { return vm->listVolumes(cli); } else if (!strcmp(argv[1], "debug")) { if (argc != 3 || (argc == 3 && (strcmp(argv[2], "off") && strcmp(argv[2], "on")))) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume debug <off/on>", false); return 0; } vm->setDebug(!strcmp(argv[2], "on") ? true : false); } else if (!strcmp(argv[1], "mount")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mount <path>", false); return 0; } rc = vm->mountVolume(argv[2]); } else if (!strcmp(argv[1], "unmount")) { if (argc < 3 || argc > 4 || (argc == 4 && strcmp(argv[3], "force"))) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unmount <path> [force]", false); return 0; } bool force = false; if (argc >= 4 && !strcmp(argv[3], "force")) { force = true; } rc = vm->unmountVolume(argv[2], force); } else if (!strcmp(argv[1], "format")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume format <path>", false); return 0; } rc = vm->formatVolume(argv[2]); } else if (!strcmp(argv[1], "share")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume share <path> <method>", false); return 0; } rc = vm->shareVolume(argv[2], argv[3]); } else if (!strcmp(argv[1], "unshare")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unshare <path> <method>", false); return 0; } rc = vm->unshareVolume(argv[2], argv[3]); } else if (!strcmp(argv[1], "shared")) { bool enabled = false; if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume shared <path> <method>", false); return 0; } if (vm->shareEnabled(argv[2], argv[3], &enabled)) { cli->sendMsg( ResponseCode::OperationFailed, "Failed to determine share enable state", true); } else { cli->sendMsg(ResponseCode::ShareEnabledResult, (enabled ? "Share enabled" : "Share disabled"), false); } return 0; } else { cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false); } if (!rc) { cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false); } else { int erno = errno; rc = ResponseCode::convertFromErrno(); cli->sendMsg(rc, "volume operation failed", true); } return 0; }
每次操作完成后,都要将操作结果汇报给framework,阶级负责工作,一定要把工作结果汇报给领导,这里使用了sendMsg函数。
1.搜索需要挂载的磁盘对象信息列表。先从listVolumes函数开始,贴源码:

int VolumeManager::listVolumes(SocketClient *cli) { VolumeCollection::iterator i; for (i = mVolumes->begin(); i != mVolumes->end(); ++i) { char *buffer; asprintf(&buffer, "%s %s %d", (*i)->getLabel(), (*i)->getMountpoint(), (*i)->getState()); cli->sendMsg(ResponseCode::VolumeListResult, buffer, false); free(buffer); } cli->sendMsg(ResponseCode::CommandOkay, "Volumes listed.", false); return 0; }
这函数扫描了mVolumes容器,里面保存着从配置文件/etc/vold.fstab解析出来的磁盘。
该容器是在main函数中添加的:vm->addVolume(dv);
这函数先将每个磁盘的标签,挂载点,状态汇报给framework,然后再循环工作结束后,再次向领导汇报工作结束。
2.设置调试模式。贴源码:

void VolumeManager::setDebug(bool enable) { mDebug = enable; VolumeCollection::iterator it; for (it = mVolumes->begin(); it != mVolumes->end(); ++it) { (*it)->setDebug(enable); } }
每个Volume对象都有一个setDebug函数设置调试状态:

void Volume::setDebug(bool enable) { mDebug = enable; }
挂载磁盘涉及到很多内容和源码,将在下一篇文章继续说明,待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值