处理不同的事件这里重要的事件有 “block”事件主要指Volume的mount、unmount、createAsec等。
由VolumeManager的handleBlockEventevt来处理根据多态性最终将会调用AutoVolume或者DirectVolume的handleBlockEvent方法来处理。
“switch”事件主要指Volume的connet、disconnet等。
根据相关操作改变设备参数设备类型、挂载点等通过CommandListener告知FrameWork层。
b. FrameWork发出控制命令 与a相反CommandListener检测到FrameWork层的命令MountService发出的命令调用VolumeManager的函数VolumeManager找出对应的Volume调用Volume函数去挂载/卸载操作。
而Volume类中的相关操作最终通过调用Linux函数完成。
这里再次贴上这张流程图 3.SD卡挂载流程代码浅析 这里只是简要的分析SD卡挂载过程中重要的代码调用并没有深入分析代码因为这一部分网上已有牛人比较详尽的分析了后面我会贴出这些参考文章。
整个过程从Kernel检测到SD卡插入事件开始之前的一些硬件中断的触发以及driver的加载这里并不叙述一直到SD卡挂载消息更新到“Android——系统设置——存储”一项中。
1. Kernel发出SD卡插入uevent。
2. NetlinkHandler::onEvent接收内核发出的uevent并进行解析。
3. VolumeManager::handlBlockEvent处理经过第二步处理后的事件。
4. 接下来调用DirectVolume:: handleBlockEvent。
在该方法中主要有两点需要注意 第一程序首先会遍历mPath容器寻找与event对应的sysfs_path是否存在与mPath容器中。
第二针对event中的action有4种处理方式AddRemovedChangeNoaction 。
例如在Add action中会有如下操作因为我们这里所讲的是SD卡的挂载流程因此以Add来说明首先创建设备节点其次对disk和partition两种格式的设备分别进行处理。
SD卡属于disk类型。
5. 经过上一步之后会调用DirectVolume::handleDiskAdded方法在该方法中会广播disk insert消息。
6. SocketListener::runListener会接收DirectVolume::handleDiskAdded广播的消息。
该方法主要完成对event中数据的获取通过Socket。
PS:这里的SocketListener.cpp位于
Android源码/system/core/libsysutils/src/中后文的FramworkListener.cpp也是之前自己找了很久 T_T 7. 调用FrameworkListener::onDataAvailable方法处理接收到的消息内容。
8. FrameworkListener::dispatchCommand该方法用于分发指令。
9. 在FrameworkListener::dispatchCommand方法中通过runCommand方法去调用相应的指令。
10. 在/system/vold/CommandListener.cpp中有runCommand的具体实现。
在该类中可以找到这个方法CommandListener::VolumeCmd::runCommand从字面意思上来看这个方法就是对Volume分发指令的解析。
该方法中会执行“mount”函数vm-mountVolumearg2。
11. mountVolumearg2在VolumeManager::mountVolume中实现在该方法中调用v-mountVol。
12. mountVol方法在Volume::mountVol中实现该函数是真正的挂载函数。
在该方法中后续的处理都在该方法中在Mount过程中会广播相应的消息给上层通过setState函数。
13. setStateVolume::Checking广播给上层正在检查SD卡为挂载做准备。
14. Fat::checkSD卡检查方法检查SD卡是否是FAT格式。
15. Fat::doMount挂载SD卡。
至此SD的挂载已算初步完成接下来应该将SD卡挂载后的消息发送给上层在13中也提到过在挂载以及检查的过程中其实也有发送消息给上层的。
16. MountService的构造函数中会开启监听线程用于监听来自vold的socket信息。
Thread thread new ThreadmConnectorVOLD_TAG thread.start 17. mConnector是NativeDaemonConnector的对象NativeDaemonConnector继承了Runnable并Override了run方法。
在run方法中通过一个whiletrue调用ListenToSocket方法来实现实时监听。
18. 在ListenToSocket中首先建立与Vold通信的Socket Server端然后调用MountService中的onDaemonConnected方法。
PS:Java与Native通信可以通过JNI那么Native与Java通信就需要通过Socket来实现了。
Android中Native与Frameworks通信 这篇文章中有简介感兴趣的朋友可以参考一下 19. onDaemonConnected方法是在接口INativeDaemonConnectorCallbacks中定义的MountService实现了该接口并Override了onDaemonConnected方法。
该方法开启一个线程用于更新外置存储设备的状态主要更新状态的方法也在其中实现。
20. 然后回到ListenToSocket中通过inputStream来获取Vold传递来的event并存放在队列中。
21. 然后这些event会在onDaemonConnected通过队列的”队列.take”方法取出。
并根据不同的event调用updatePublicVolumeState方法在该方法中调用packageManagerService中的updateExteralState方法来更新存储设备的状态。
注这里不太理解packageManagerService中的unloadAllContainersargs方法 22. 更新是通过packageHelper.getMountService.finishMediaUpdate方法来实现的。
23. 在updatePublicVolumeState方法中更新后会执行如下代码 bl.mListener.onStorageStateChanged 在
Android源码/packages/apps/Settings/src/com.android.settings.deviceinfo/Memory.java代码中实现了StorageEventListener 的匿名内部类并Override了onStorageStateChanged方法。
因此在updatePublicVolumeState中调用onStorageStateChanged方法后Memory.java中也会收到。
在Memory.java中收到以后会在Setting界面进行更新系统设置——存储中会更新SD卡的状态。
从而SD卡的挂载从底层到达了上层。
在经过了上面步骤之后SD卡的挂载的消息已经从底层到达了上层。
这是自己在网上查找资料同时一边跟踪代码后得出的结论其中可能还有很多不正确的地方也有很多自己没有理解的地方希望大家能够帮忙指正感激不尽。
后续将继续分析SD挂载广播的发出流程以及SD卡挂载程序调用流程图。
绿色箭头表示插入SD卡后事件传递以及SD卡挂载 红色箭头表示挂载成功后的消息传递流程 黄色箭头表示MountService发出挂载/卸载SD卡的命令 大家可能对图中突然出现的这么多的名称感到奇怪这些都是在Android 2.3 源码中可以找到的接下来我会为大家一一解释这些类的作用。
2.各个文件的主要作用 1Kernel:这个是系统内核啦。
不是我要分析的文件本文涉及内容不是内核级的哦努力学习中... 2NetlinkManager:全称是NetlinkManager.cpp位于Android 2.3源码位置/system/vold/NetlinkManager.cpp。
该类的主要通过引用NetlinkHandler类中的onEvent方法来接收来自内核的事件消息NetlinkHandler位于/system/vold/NetlinkHandler.cpp。
3VolumeManager:全称是VolumeManager.cpp位于Android 2.3源码位置/system/vold/VolumeManager.cpp。
该类的主要作用是接收经过NetlinkManager处理过后的事件消息。
因为我们这里是SD卡的挂载因此经过NetlinkManager处理过后的消息会分为五种分别是blockswitchusb_compositebatterypower_supply。
这里SD卡挂载的事件是block。
4DirectVolume:位于/system/vold/DirectVolume.cpp。
该类的是一个工具类主要负责对传入的事件进行进一步的处理block事件又可以分为AddRemovedChangeNoaction这四种。
后文通过介绍Add事件展开。
5Volume:Volume.cpp位于/system/vold/Volume.cpp该类是负责SD卡挂载的主要类。
Volume.cpp主要负责检查SD卡格式以及对复合要求的SD卡进行挂载并通过Socket将消息SD卡挂载的消息传递给NativeDaemonConnector。
6NativeDaemonConnector:该类位于frameworks/base/services/java/com.android.server/NativeDaemonConnector.java。
该类用于接收来自Volume.cpp 发来的SD卡挂载消息并向上传递。
7MountService:位于frameworks/base/services/java/com.android.server/MountService.java。
MountService是一个服务类该服务是系统服务提供对外部存储设备的管理、查询等。
在外部存储设备状态发生变化的时候该类会发出相应的通知给上层应用。
在Android系统中这是一个非常重要的类。
8StorageManaer:位于frameworks/base/core/java/andriod/os/storage/StorageManager.java。
在该类的说明中有提到该类是系统存储服务的接口。
在系统设置中有Storage相关项同时Setting也注册了该类的监听器。
而StorageManager又将自己的监听器注册到了MountService中因此该类主要用于上层应用获取SD卡状态。
通过上文对各个文件的作用简介以及整个SD卡的挂载流程图可以知道Android 系统是如何从底层获取SD卡挂载信息的。
后文将继续分析程序调用流程图。
特别声明 1资料来源于互联网版权归属原作者 2资料内容属于网络意见与本账号立场无关 3如有侵权请告知立即删除。