人人范文网 范文大全

android vold学习总结

发布时间:2020-03-02 01:48:25 来源:范文大全 收藏本文 下载本文 手机版

vold学习总结

Vold(volume daemon):源码路径android/system/vold,部分引用代码位于android/system/core/libsysutils/src,android/system/core/include/sysutils/下。

它用于管理和控制android平台的外部设备,包括u盘、sd卡等的插入,拔出和格式化等。 Vold为守护进程,由init进程启动,Vold的框架如下图所示:

Linux kernel与vold进程通过netlink机制进行跨进程通信,vold中的NetlinkManager接收来自linux kernel上报的uevent事件,然后将其转换成一个NetlinkEvent类型,并调用VolumeManager类的相应方法进行处理,VolumeManager会将处理的结果发送给MountService,VolumeManager与MountService之间通过CommandListener机制进行通信,本质是通过socket进行跨进程通信,MountService运行在SystemServer进程中。

Uevent事件内容就是一个字符串,linux kernel在下列两种情况下会上报uevent事件: 1.外设状态发生变化触发,当有U盘、sd卡等外设的插拔动作时,都会引起linux kernel上报uevent事件,如果vold在外设状态发生变化之前已经建立了netlink连接,就能收到相应的uevent事件。

2.在/sys目录下会有一个叫做uevent的文件,往该文件中写入特定的数据,也会触发kernel发送和该设备相关的uevent事件,这个由应用层触发,例如vold启动时,会往uevent文件中写入数据,它就会触发linux kernel发送uevent事件,这样vold就能获取设备的当前信息。

在etc/目录下有个vold.fstab文件(实际上该文件是在system/etc目录下,它在system/core/rootdir/init.rc中有配置:symlink /system/etc /etc,通过软链接而链接到etc目录下),该文件是android系统与硬件平台交互的接口,用户可以手动配置该文件,在 android\\system\\core\\rootdir\\etc\\下有个vold.fstab文件,它描述了vold.fstab文件配置挂载设备的模板,

dev_mount

其中part表示分区,值为auto或具体的分区编号,auto表示挂载该设备上的第一个分区(该设备只有一个分区),分区编号表示使用该设备上的第几个分区,sysfs_path表示设备在sys目录下的设备路径(可多个),各个参数之间用全部用空格或tab键隔开。注:sysfs文件系统是linux中一种特殊的文件系统,用于将系统中的设备组织成层次结构,并向用户模式程序提供详细的内核数据结构信息。sysfs_path表示vold监测的路径,当有设备插入时,在监测的路径下会多出一个文件夹,该文件夹中描述了插入设备的各种ID信息。

在sys目录下有多个目录:block(系统中的所有块设备)、bus(系统中的所有总线设备)、devices(系统中的所有设备层次结构)、drivers(系统中的所有驱动)等。

dev_mount sdcard1 /mnt/sdcard auto /devices/platform/sdhci-tegra.2/mmc_host/mmc1/mmc1 当设备中出入sd卡后,在dev/block目录下会多出几个设备节点,表示sd卡驱动已经加载成功,一般会多出两个设备节点mmcblk0和mmcblk0p1节点,其中mmcblk0表示第一个sd卡设备,mmcblk0p1表示第一个sd卡设备的第一个分区,真正挂载到系统中的是mmcblk0p1而非mmcblk0,如果手动使用mount挂载时,不能直接挂载设备,而是选择挂载设备的分区,例如

mount -t vfat /dev/block/mmcblk0p1 sdcard 关键点:

1.Vold的main方法中会调用proce_config()方法解析vold.fstab文件,根据文件内容去配置VolumeManager对象。

2.当linux kernel上报一个uevent事件时,NetlinkManager会处理该事件,实际是它是调用NetlinkHandler类处理的,NetlinkHandler类的继承层次关系:NetlinkHandler继承自NetlinkListener,而NetlinkListener又继承自SocketListener。在NetlinkListener类的onDataAvailable()方法中,会将一个原始的uevent事件内容解析为NetlinkEvent类,并调用NetlinkHandler类的onEvent()方法。

3.从kernel上报uevent事件时,vold的处理简单流程为:

SocketListener::runListener() ->NetlinkListener::onDataAvailable()->NetlinkHandler::onEvent()->VolumeManager::handleBlockEvent()->DirectVolume::handleBlockEvent()->CommandListener::sendBroadcast()。 4.vold与MountService进行通信的简单处理流程为:

SocketListener::runListener()->FrameworkListener::onDataAvailable()->FrameworkListener::dispatchCommand()->***Cmd:: runCommand()。

在dispatchCommand()中会根据命令字符串内容不同调用相应的VoldCommand子类的runCommand()进行处理,进而调用VolumeManager的相应方法。 经过VolumeManager处理的uevent类型主要有:block、switch、usb_composite、battery、power_supply,在DirectVolume的handleBlockEvent()方法中,会根据设备类型和执行的动作(add/remove/change)执行相应的函数:handleDiskAdded()、handlePartitionAdded()、handleDiskRemoved()、handlePartitionRemoved()等,在这些方法中,最终会调用mVm->getBroadcaster()->sendBroadcast()方法,实际调用了CommandListener类的sendBroadcast()方法,该方法利用socket通信将消息发送给MountService类。

5.当vold发送消息给MountService后,会触发MountService类的onEvent()方法调用(由NativeDaemonConnector调用)。在onEvent()方法中,会发送相应广播消息,并且会调用相应接口触发通知。StorageManager可看做MountService在客户端的代理类。应用程序可以通过调用StorageManager类的相应方法,例如注册监听器获取外设的插拔通知。对于应用程序来说,有两种方式获取外设插拔通知,一是通过StorageManager类的registerListener()注册监听器,二是注册广播接收器接收相应的广播消息。

6.MountService.java中会读取storage_list.xml文件(位于framework/res/res/xml/),

7.Android系统中使用UeventObserver类可以监控linux kernel上报的uevent事件,利用UeventObserver检测外部设备插拔的设备有: BatteryService:检测充电器的插拔。

PhoneWindowManager:检测hdmi的插拔。

WiredAcceoryManager:检测有线耳机的插拔。 DockObserver:检测底座的插拔。

UsbDeviceManager:Android系统作为从设备,连接到主设备pc的检测。 读取Uevent事件代码:hardware\\libhardware_legacy\\uevent\\uevent.c.

SocketListener: 处理套接字监听器的基类,vold利用两个socket分别与上层应用和linux kernel进行通信,与上层应用进行通信时,利用的是CommandListener,与linux kernel进行通信利用的是NetlinkHandler,通信机制用的是netlink socket机制。

SocketListener的构造函数中指定了两个参数,分别表示socket名字和是否监听套接字(根据定义变量mListen判断)。SocketListener类主要有以下几个方法:

startListener():启动监听器,该方法中会创建一个套接字,并启动一个子线程处理socket通信,子线程中会进入一个死循环,然后利用select机制来监听多个套接字,监听套接字有三种:来自客户端的连接请求,客户端发送过来的数据,管道读端。如果变量mListen为false,是不会监听来自客户端的连接请求的。管道读端用于确定是否退出子线程操作。当有客户端发送数据过来时,select()会返回,会调用onDataAvailable()进行处理。onDataAvailable是虚函数,由其子类实现。

stopListener():停止监听器,通过往管道中写数据来退出socket通信的子线程。

sendBroadcast():遍历所有连接的客户端SocketClient实例,并调用每个实例的sendMsg()方法将消息发送给客户端。

FrameworkListener:继承自SocketListener,指定监听套接字变量mListen为true。onDataAvailable()中从socket buffer中获取客户端发送过来的数据,并调用dispatchCommand(),在dispatchCommand()中会解析数据,然后比较command的名字与哪个FrameworkCommand名字匹配,并调用匹配的FrameworkCommand子类的runCommand()方法。该类中还定义了一个registerCmd()方法用于注册各种FrameworkCommand子类。

CommandListener:继承自FrameworkListener,在构造函数中指定套接字名称为vold。在CommandListener的头文件中定义了很多种VoldCommand(它继承自FrameworkCommand), 这些VoldCommand子类主要有:DumpCmd、VolumeCmd、AsecCmd 、ObbCmd、StorageCmd、XwarpCmd、CryptfsCmd、FstrimCmd。其中DumpCmd 类处理打印信息,VolumeCmd处理外部设备Volume的各种操作,例如挂载、卸载、格式化等,AsecCmd处理asec目录相关,安装在sdcard的应用程序相关文件会存放在目录,ObbCmd处理obb文件相关操作(obb文件称为不透明二进制文件,obb文件可能在磁盘上被加密,供应用程序使用,应用程序使用时进行解密,obb文件尺寸一般很大,一般放在sdcard中,不会打包进apk中,它可能被其它应用程序访问和修改)。

在CommandListener的构造函数中调用registerCmd()注册了上述8个VoldCommand实例。 NetlinkListener:继承自SocketListener,指定监听套接字变量mListen为false,定义了两个虚函数onDataAvailable()和onEvent()。该类主要实现了一个方法onDataAvailable():该方法中会创建一个NetlinkEvent对象,并调用该对象的decode()方法,将其解析为一个NetlinkEvent事件。

NetlinkHandler:继承自NetlinkListener,该类中定义了三个方法,

start():调用基类SocketListener的startListener(),启动socket监听器。 stop():调用基类SocketListener的stopListener(),停止socket监听器。

onEvent():处理NetlinkEvent事件,调用VolumeManager::handleBlockEvent(),目前只处理子系统为block的块设备。 Volume:处理卷标类。

DirectVolume:继承自Volume,该类中的主要方法有handleBlockEvent(),根据上报的NetlinkEvent事件类型和动作类型,来调用不同的处理函数,例如handleDiskAdded()、handlePartitionAdded()、handleDiskRemoved()、handlePartitionRemoved()等。 VolumeManager:Volume管理器。

MountService:运行在SystemServer进程中,在其构造函数中,会创建一个NativeDaemonConnector实例,并启动一个子线程来执行这个实例,NativeDaemonConnector是一个Runnable对象,它用于建立与vold的socket连接。NativeDaemonConnector实例收到vold发送来的消息时,会触发回调INativeDaemonConnectorCallbacks的onEvent()的执行, MountService实现了INativeDaemonConnectorCallbacks的onEvent(),例如有新的外部设备插入时,MountService会收到VoldResponseCode.VolumeDiskInserted消息,并执行doMountVolume()挂载该设备,doMountVolume()方法最终会调用NativeDaemonConnector类实例的execute()方法往/dev/socket/vold中写入特定的命令消息给vold。

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

android vold学习总结
《android vold学习总结.doc》
将本文的Word文档下载到电脑,方便编辑。
推荐度:
点击下载文档
点击下载本文文档