现在的位置: 首页 > 综合 > 正文

Android-Vold, Framework和UI的通信-大结局(12)

2013年09月03日 ⁄ 综合 ⁄ 共 2714字 ⁄ 字号 评论关闭

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

写了好几篇文章,花儿都快谢了,终于轮到Framework发挥领导的身份了,Framework作为界面与vold之间的桥梁,用户是Framework的大爷,那么Framework就是Vold的大哥大,Framework发出一个命令,Vold不敢不遵从,只能照着Framework的意思照办,千万不能出差错,不然Android就要丢大脸了,登不上三国争霸的舞台,iOS VS Android VS WP7?
在Framework里面,有一个目录是用来存放一些Java的系统服务,这些都在后台跑着,在:/android-2.2r2/frameworks/base/services/java/com/android/server目录下,比较重要的是这两个源文件:MountService.java和NativeDaemonConnector.java。
这里先列出在Vold中,VolumeCmd类处理的一些磁盘操作命令,这些命令均是有Framework下发的:
1.volume list:Framework先得到系统目前存在几个Volume对象,需要获取到这些对象的标签;
2.volume debug:设置USB调试模式
3.volume mount sdcard:挂载SD卡
4.volume unmount force:卸载SD卡
5.volume format sdcard:格式化SD卡
6.volume share sdcard ums:开启SD卡的OTG功能(大容量存储),也就是连接电脑
7.volume unshare sdcard ums:关闭SD卡的OTG功能(大容量存储)
8.volume shared sdcard ums:获取目前OTG的开启状态,就是是否连接电脑的状态。

以下分别列出每个命令的下发函数,对Java不熟,但看得懂程序的流程,真是惭愧啊。

一、Framework磁盘管理服务的开启?

在NativeDaemonConnector服务里面,开始监听底层Vold发送过来的磁盘热插拔事件的状态信息,当收到底层广播上来的状态,调用MountService服务中的onDaemonConnected函数进行处理,当然这是开机第一次去获取信息的,也就是下发"volume list"命令。

  1. public void run() {  
  2.     while (true) {  
  3.         try {  
  4.             /*开始监听底层广播信息*/  
  5.             listenToSocket();  
  6.         } catch (Exception e) {  
  7.             Slog.e(TAG, "Error in NativeDaemonConnector", e);  
  8.             SystemClock.sleep(5000);  
  9.         }  
  10.     }  
  11. }  
  12. private void listenToSocket() throws IOException {  
  13.     /*函数太长,以下是执行顺序*/  
  14.     //连接SOCKET  
  15.     socket.connect(address);  
  16.     ->  
  17.     /*调用该函数来处理下发"volume list"命令的反馈结果*/  
  18.     mCallbacks.onDaemonConnected();  
  19.     ->  
  20.     /*处理磁盘的状态*/  
  21.     mCallbacks.onEvent(code, event, tokens);  
  22. }  


以上两个比较重要的函数在MountService当中,处理相当多的内容,源码太长。
下发volume list命令,Framework收到反馈值,将调用onDaemonConnected函数获取到了磁盘的标签,挂载点与状态,然后调用doGetShareMethodAvailable函数判断现在是否连接OTG,若连接OTG,那么调用doShareUnshareVolume函数下发otg连接命令(volume share sdcard ums)。

二、Vold与Framework如何通信?
onEvent主要是处理状态信息的解析,将每一种状态进行判断,并调用相应的操作函数。比如此时vold发送一个VolumeDiskInserted状态,意味着系统插入一个磁盘,于是onEvent就调用doMountVolume挂载函数进行下发命令(volume mount sdcard)。
在系统使用当中,用户可能会插入,移除,挂载,卸载,格式化磁盘,那么这儿多状态如何告诉Framework呢?之前已经说过,vold使用了setState函数来广播磁盘的状态消息,使得Framework能够及时地判断下发什么命令与操作。该函数在Volume.cpp源文件中,先贴出setState源码看看:

  1. void Volume::setState(int state) {  
  2.     char msg[255];  
  3.     int oldState = mState;  
  4.   
  5.     if (oldState == state) {  
  6.         SLOGW("Duplicate state (%d)\n", state);  
  7.         return;  
  8.     }  
  9.   
  10.     mState = state;  
  11.   
  12.     SLOGD("Volume %s state changing %d (%s) -> %d (%s)", mLabel,  
  13.          oldState, stateToStr(oldState), mState, stateToStr(mState));  
  14.     snprintf(msg, sizeof(msg),  
  15.              "Volume %s %s state changed from %d (%s) to %d (%s)", getLabel(),  
  16.              getMountpoint(), oldState, stateToStr(oldState), mState,  
  17.              stateToStr(mState));  
  18.   
  19.     mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeStateChange,  

抱歉!评论已关闭.