一、首先看Vold的作用:
Vold:Volume Daemon,用于管理和控制Android平台外部存储设备的后台程序,例如SD卡的挂载、卸载、格式化,以及拔插事件的检查等。
Vold的实现在JNI层,Java层与它打交道的模块是MountService。MountService一方面接收来自Vold的消息,例如SD卡的拔插事件;一方面向Vold发送控制命令,例如挂载和卸载SD卡。
二、在分析Vold前,先介绍一下Linux系统中的Netlink和Uevent
Netlink:Netlink是linux系统中用户空间进程和kernel进行通信的一种机制,用户空间的进程能够接收来自kernel的设备拔插消息,同时应用层也可以通过Netlink向kernel发送控制命令
Uevent:CommandListener内部封装了一个socket用于进程间通讯,socket的服务端在Vold中,客户端在MountService中
三、Vold模块
1、在Vold的Main.cpp中:
1)创建VolumeManager对象
2)创建NetLinkManager对象
3)创建CommandListener对象
4)启动VolumeManager
5)根据配置文件初始化VolumeManager
6)启动NetLinkManager
7)VolumeManager通过CommandListener向感兴趣的模块发送UMS(USB Mass Storage)的状态
8)启动CommandListener
9)进入无限循环
2、NetLinkManager模块
它是一个单例,构造函数实例化自己
在其start函数中:
1)创建了一个socket,用于接收来自内核的Uevent事件
2)创建一个NetLinkHandler对象,并把上面创建的socket交给NetLinkHandler
3、NetLinkHandler分析
NetLinkHandler继承于NetLinkListener,而NetLinkListener又继承于SocketListener。
SocketListener监听连接,如果有数据从socket中发送过来,即调用派生类NetLinkListener中的onDataAvailable函数处理,处理函数中调用了recev接收数据,接收成功就传递到子类NetLinkHandler的onEvent函数处理数据。
在onEvent中,将事件交给了VolumeManager
4、VolumeManager分析
它也是一个单例模式
在其process_config函数中:
1)读取/etc/vold.fstab文件并解析
2)构造一个DirectVolume对象
3)添加设备路径
4)在DirectVolume中调用CommandListener对象的sendBroadcast给MountService发送消息
5、DirectVolume分析
DirectVolume从Volume类派生,可以把它看作一个外部存储卡在代码中的代表。它封装了对外部存储卡的操作。如加载/卸载、格式化等。
6、NetLinkManager与VolumeManager交互
NetLinkManager在NetLinkHandler的onEvent中将事件传给了VolumeManager,并调用了VolumeManager的两个函数:
1)handleSwitchEvent,处理SD卡个挂载磁盘的通知
2)handleBlockEvent,控制DirectVolume对象
7、CommandListener分析
它使用了命令设计模式。
CommandListener的工作过程:
1)创建一个服务端的socket(唯一的客户端是MountService)
2)接收客户端的请求,并把其发过来的命令与mCommand中的命令列表对比,如果命令合法,即交给命令对应的处理函数runCommands处理
8、Vold使用CommandListener的流程是:
1)new一个CommandListener对象
2)调用CommandListener的startListener函数(其实是调用了其父类SocketListener的startListener)
四、MountService
1、实现了NativeDaemonConnector的部分接口
2、创建了一个HandlerThread用于处理消息
3、创建了一个线程并利用NativeDaemonConnector和Vold通信