注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

时间记录器

记录我的Linux、Android学习之路

 
 
 

日志

 
 

Android之 VolumeCmd zz  

2012-08-27 16:01:49|  分类: Android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

了这么多,该到执行命令的函数了,要不黄花菜都凉了。上一篇文章讲了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的大容量存储模式,相当于手机与电脑连接,并挂载在电脑

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

  1. int CommandListener::VolumeCmd::runCommand(SocketClient *cli,  

  1.                                                       int argc, char **argv) {  
  2.     dumpArgs(argc, argv, -1);  
  3.   
  4.     if (argc < 2) {  
  5.         cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument"false);  
  6.         return 0;  
  7.     }  
  8.   
  9.     VolumeManager *vm = VolumeManager::Instance();  
  10.     int rc = 0;  
  11.   
  12.     if (!strcmp(argv[1], "list")) {  
  13.         return vm->listVolumes(cli);  
  14.     } else if (!strcmp(argv[1], "debug")) {  
  15.         if (argc != 3 || (argc == 3 && (strcmp(argv[2], "off") && strcmp(argv[2], "on")))) {  
  16.             cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume debug <off/on>"false);  
  17.             return 0;  
  18.         }  
  19.         vm->setDebug(!strcmp(argv[2], "on") ? true : false);  
  20.     } else if (!strcmp(argv[1], "mount")) {  
  21.         if (argc != 3) {  
  22.             cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mount <path>"false);  
  23.             return 0;  
  24.         }  
  25.         rc = vm->mountVolume(argv[2]);  
  26.     } else if (!strcmp(argv[1], "unmount")) {  
  27.         if (argc < 3 || argc > 4 || (argc == 4 && strcmp(argv[3], "force"))) {  
  28.             cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unmount <path> [force]"false);  
  29.             return 0;  
  30.         }  
  31.   
  32.         bool force = false;  
  33.         if (argc >= 4 && !strcmp(argv[3], "force")) {  
  34.             force = true;  
  35.         }  
  36.         rc = vm->unmountVolume(argv[2], force);  
  37.     } else if (!strcmp(argv[1], "format")) {  
  38.         if (argc != 3) {  
  39.             cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume format <path>"false);  
  40.             return 0;  
  41.         }  
  42.         rc = vm->formatVolume(argv[2]);  
  43.     } else if (!strcmp(argv[1], "share")) {  
  44.         if (argc != 4) {  
  45.             cli->sendMsg(ResponseCode::CommandSyntaxError,  
  46.                     "Usage: volume share <path> <method>"false);  
  47.             return 0;  
  48.         }  
  49.         rc = vm->shareVolume(argv[2], argv[3]);  
  50.     } else if (!strcmp(argv[1], "unshare")) {  
  51.         if (argc != 4) {  
  52.             cli->sendMsg(ResponseCode::CommandSyntaxError,  
  53.                     "Usage: volume unshare <path> <method>"false);  
  54.             return 0;  
  55.         }  
  56.         rc = vm->unshareVolume(argv[2], argv[3]);  
  57.     } else if (!strcmp(argv[1], "shared")) {  
  58.         bool enabled = false;  
  59.         if (argc != 4) {  
  60.             cli->sendMsg(ResponseCode::CommandSyntaxError,  
  61.                     "Usage: volume shared <path> <method>"false);  
  62.             return 0;  
  63.         }  
  64.   
  65.         if (vm->shareEnabled(argv[2], argv[3], &enabled)) {  
  66.             cli->sendMsg(  
  67.                     ResponseCode::OperationFailed, "Failed to determine share enable state"true);  
  68.         } else {  
  69.             cli->sendMsg(ResponseCode::ShareEnabledResult,  
  70.                     (enabled ? "Share enabled" : "Share disabled"), false);  
  71.         }  
  72.         return 0;  
  73.     } else {  
  74.         cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd"false);  
  75.     }  
  76.   
  77.     if (!rc) {  
  78.         cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded"false);  
  79.     } else {  
  80.         int erno = errno;  
  81.         rc = ResponseCode::convertFromErrno();  
  82.         cli->sendMsg(rc, "volume operation failed"true);  
  83.     }  
  84.   
  85.     return 0;  
  86. }  

每次操作完成后,都要将操作结果汇报给framework,阶级负责工作,一定要把工作结果汇报给领导,这里使用了sendMsg函数。
1.搜索需要挂载的磁盘对象信息列表。先从listVolumes函数开始,贴源码:

  1. int VolumeManager::listVolumes(SocketClient *cli) {  
  2.     VolumeCollection::iterator i;  
  3.   
  4.     for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {  
  5.         char *buffer;  
  6.         asprintf(&buffer, "%s %s %d",  
  7.                  (*i)->getLabel(), (*i)->getMountpoint(),  
  8.                  (*i)->getState());  
  9.         cli->sendMsg(ResponseCode::VolumeListResult, buffer, false);  
  10.         free(buffer);  
  11.     }  
  12.     cli->sendMsg(ResponseCode::CommandOkay, "Volumes listed."false);  
  13.     return 0;  
  14. }  

这函数扫描了mVolumes容器,里面保存着从配置文件/etc/vold.fstab解析出来的磁盘。
该容器是在main函数中添加的:vm->addVolume(dv);
这函数先将每个磁盘的标签,挂载点,状态汇报给framework,然后再循环工作结束后,再次向领导汇报工作结束。
2.设置调试模式。贴源码:

  1. void VolumeManager::setDebug(bool enable) {  
  2.     mDebug = enable;  
  3.     VolumeCollection::iterator it;  
  4.     for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {  
  5.         (*it)->setDebug(enable);  
  6.     }  
  7. }  

每个Volume对象都有一个setDebug函数设置调试状态:

  1. void Volume::setDebug(bool enable) {  
  2.     mDebug = enable;  
  3. }  
  评论这张
 
阅读(234)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017