分享

三、Storage框架整理

 android之情殇 2014-05-29

转自:http://blog.sina.com.cn/s/blog_6100a4f10101ee40.html

 storage功能相关模块

  • MountService.java

              base/services/java/com/android/server/MountService.java

  • PackageManagerService.java

              base/services/java/com/android/server/pm/PackageManagerService.java

  • StorageManager.java

              base/core/java/android/os/storage/StorageManager.java

  • DefaultContainerService.java

              base/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java

  • Settings—storage/application

              packages/apps/Settings/src/com/android/settings

  • Vold框架

              system/vold

  • Kernel

 StorageManager

2.1 方法//变量

package                                                                                                   

   android.os.storage  

 class                                                                                                     

   StorageManager                                                                                           

   MountServiceBinderListener [StorageManager]                                                             

   ObbActionListener [StorageManager]                                                                       

   ObbListenerDelegate [StorageManager]                                                                    

   ObbStateChangedStorageEvent [StorageManager]                                                            

   StorageEvent [StorageManager]                                                                           

   UmsConnectionChangedStorageEvent [StorageManager]                                                       

   StorageStateChangedStorageEvent [StorageManager]                                                        

   ListenerDelegate [StorageManager]                                                                       

  field                                                                                                     

   TAG [StorageManager]                                                                                    

   PROP_SD_DEFAULT_PATH [StorageManager]                                                                   

   PROP_SD_INTERNAL_PATH [StorageManager]                                                                  

   PROP_SD_EXTERNAL_PATH [StorageManager]                                                                   

   ICS_STORAGE_PATH_SD1 [StorageManager]                                                                   

   ICS_STORAGE_PATH_SD2 [StorageManager]                                                                    

   STORAGE_PATH_SD1 [StorageManager]                                                                       

   STORAGE_PATH_SD2 [StorageManager]                                                                       

   mMTKExternalCacheDir [StorageManager]                                                                   

   mMountService [StorageManager]                                                                          

   mTgtLooper [StorageManager]                                                                              

   mBinderListener [StorageManager] 

   mListeners [StorageManager]                                                                             

   mNextNonce [StorageManager]                                                                              

   mObbActionListener [StorageManager]                                                                     

   mListeners [StorageManager.ObbActionListener]                                                            

   mObbEventListenerRef [StorageManager.ObbListenerDelegate]                                               

   mHandler [StorageManager.ObbListenerDelegate]                                                           

   nonce [StorageManager.ObbListenerDelegate]                                                              

   path [StorageManager.ObbStateChangedStorageEvent]                                                       

   state [StorageManager.ObbStateChangedStorageEvent]                                                       

   EVENT_UMS_CONNECTION_CHANGED [StorageManager.StorageEvent]                                              

   EVENT_STORAGE_STATE_CHANGED [StorageManager.StorageEvent]                                                

   EVENT_OBB_STATE_CHANGED [StorageManager.StorageEvent]                                                   

   mMessage [StorageManager.StorageEvent]                                                                  

   available [StorageManager.UmsConnectionChangedStorageEvent]                                             

   path [StorageManager.StorageStateChangedStorageEvent]                                                   

   oldState [StorageManager.StorageStateChangedStorageEvent]                                                

   newState [StorageManager.StorageStateChangedStorageEvent]                                               

   mStorageEventListener [StorageManager.ListenerDelegate]                                                  

   mHandler [StorageManager.ListenerDelegate]                                                              

                                                                                                           

 method                                                                                                     

   onUsbMassStorageConnectionChanged [StorageManager.MountServiceBinderListener]                           

   onStorageStateChanged [StorageManager.MountServiceBinderListener]                                       

   onObbResult [StorageManager.ObbActionListener]                                                          

   addListener [StorageManager.ObbActionListener]                                                           

   getNextNonce [StorageManager]                                                                           

   ObbListenerDelegate [StorageManager.ObbListenerDelegate]                                                

   getListener [StorageManager.ObbListenerDelegate]                                                        

   sendObbStateChanged [StorageManager.ObbListenerDelegate]                                                

   ObbStateChangedStorageEvent [StorageManager.ObbStateChangedStorageEvent]

StorageEvent [StorageManager.StorageEvent]                                                                 

   getMessage [StorageManager.StorageEvent]                                                                

   UmsConnectionChangedStorageEvent [StorageManager.UmsConnectionChangedStorageEvent]                      

   StorageStateChangedStorageEvent [StorageManager.StorageStateChangedStorageEvent]                        

   ListenerDelegate [StorageManager.ListenerDelegate]                                                       

   getListener [StorageManager.ListenerDelegate]                                                           

   sendShareAvailabilityChanged [StorageManager.ListenerDelegate]                                          

   sendStorageStateChanged [StorageManager.ListenerDelegate]                                               

   from [StorageManager]                                                                                   

   StorageManager [StorageManager]                                                                          

   registerListener [StorageManager]                                                                       

   unregisterListener [StorageManager]                                                                      

   enableUsbMassStorage [StorageManager]                                                                   

   disableUsbMassStorage [StorageManager]                                                                  

   isUsbMassStorageConnected [StorageManager]                                                              

   isUsbMassStorageEnabled [StorageManager]                                                                

   mountObb [StorageManager]                                                                                

   unmountObb [StorageManager]                                                                             

   isObbMounted [StorageManager]                                                                            

   getMountedObbPath [StorageManager]                                                                      

   getVolumeState [StorageManager]                                                                         

   getVolumeList [StorageManager]                                                                          

   getVolumePaths [StorageManager]                                                                         

   getPrimaryVolume [StorageManager]                                                                        

   getPrimaryVolume [StorageManager]                                                                       

   getDefaultPath [StorageManager]                                                                          

   setDefaultPath [StorageManager]                                                                         

   getMTKExternalCacheDir [StorageManager]                                                                 

   getExternalStoragePath [StorageManager]                                                                 

   getInternalStoragePath [StorageManager]         

 

2.2 工作流程

应用PhoneStatusBarPolicy.java

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java

调用StorageManager的监听注册函数,将监听的StorageEventListener注册到StorageManager中,当有状态变化时,会调用该类的对应函数。通常在具体需要storage状态变化的场景会定义一个新类,继承于StorageEventListener。下面注册到StorageManagerlistener就是继承于StorageEventListener

// storage

mStorageManager=(StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

mStorageManager.registerListener(new com.android.systemui.usb.StorageNotification(context));

com.android.systemui.usb.StorageNotification就是继承于StorageEventListener

1)      registerListener

    public void registerListener(StorageEventListener listener) {

        if (listener == null) {

            return;

        }

        synchronized (mListeners) {

            if (mBinderListener == null ) {

                try {

                    mBinderListener = new MountServiceBinderListener();

                    mMountService.registerListener(mBinderListener);

                } catch (RemoteException rex) {

                    Log.e(TAG, "Register mBinderListener failed");

                    return;

                }

            }

            mListeners.add(new ListenerDelegate(listener));

        }

    }

2)      StorageManagerregisterListener有两个功能,一个是接收其他应用过来的申请,将他们的StorageEventListener,转换成ListenerDelegate 对象,然后保存在mListeners 这个数组中。

     private List<ListenerDelegate> mListeners = new ArrayList<ListenerDelegate>();

mListeners.add(new ListenerDelegate(listener));

       另外一个功能就是向mountService注册listenerStorageManager也是个中间者,拿不到一手信息,需要从上线拿到资源,所以它需要向mountService注册listener

                    mBinderListener = new MountServiceBinderListener();

                    mMountService.registerListener(mBinderListener);

       注册进去的类型为MountServiceBinderListener,是MountServiceListener的实现。

       特别注意:在mountService中,对注册进来的MountServiceBinderListener又做了一层处理,恶心的是两个类是同一个名字。

MountServiceBinderListener bl = new MountServiceBinderListener(listener);

参数listener的类型是上面蓝色的,从StorageManager传过来,红色的是mountService中的类,类似于StorageManager中的ListenerDelegate。实现如下:

    private final class MountServiceBinderListener implements IBinder.DeathRecipient {

        final IMountServiceListener mListener;

        MountServiceBinderListener(IMountServiceListener listener) {

            mListener = listener;

        }

StorageManagerMountService都有一个用来记录外边注册进来的listener的数组mListeners,但是使用的类型都是自己包中定义的类,都对传进来的进行了处理。

3)      从底向上的触发

MountServiceonEvent会收到底层的调用,进而触发相应的动作,例如调用updatePublicVolumeState,这里边就会调用注册进来的listener的成员函数; bl.mListener.onStorageStateChanged。这样就进入到了StorageManager,其中的listenerMountServiceBinderListeneronStorageStateChanged会被触发。进而依次触发每一个注册到StorageManagerlistenersendStorageStateChanged,发出EVENT_STORAGE_STATE_CHANGED消息。在每个listener注册到StorageManager时,通过ListenerDelegate进行过一次打包,在其构造函数中对每个listener创建了一个handler,不停的接收消息并处理。当接收到EVENT_STORAGE_STATE_CHANGED后就调用注册进来的listeneronStorageStateChanged方法。如上即为com.android.systemui.usb.StorageNotificationonStorageStateChanged函数,所以该类的onStorageStateChanged方法需要重载。

以上内容参考了这篇文章:usb状态相关

2.3 功能调用

上面介绍的是上层如何获取系统及底层信息的中断通知的方式,除了这种被动通知状态改变的行为以外,更多的则是应用主动的获取系统的storage信息。这个功能就相对简单、直白了,可以直接调用StorageManager的成员方法。

       1) ums功能的使能/禁能/状态查询

       2)obb的挂载/卸载及查询

       3)获取分区的所有信息:分区列表/挂载点状态/主分区路径等

4) 应用的默认存储路径的管理及内外置卡的路径获取

       JB的挂载路径较ics做了更新:

    private static final String ICS_STORAGE_PATH_SD1 = "/mnt/sdcard";

    private static final String ICS_STORAGE_PATH_SD2 = "/mnt/sdcard2";

    private static final String STORAGE_PATH_SD1 = "/storage/sdcard0";

    private static final String STORAGE_PATH_SD2 = "/storage/sdcard1";

       JB版本以后,为了兼容ICS,将/mnt/sdcard链接到/storage/sdcard0

2.4 使用方法

mStorageManager=(StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

mStorageManager.functions;

2.5 StorageManager总结

如果外界需要知道系统的storage信息,直接调用StorageManager的方法。那么如果需要实时的知道状态的改变,就需要派一个信使驻扎在StorageManager家里,当有状态变化时,StorageManager会通知驻扎在他家的信使,listener。这就是为什么要安排驻京人员,能够及时的拿到一手信息。

 MountService

3.1 MountServiceStorageManager的交互   

紧接上面的StorageManager,MountService是为framework层和StorageManager服务的,StorageManager为应用程序服务。

-----------------------下面来自网友总结

MountService是运行在SystemService这个进程中,所以上层应用无法直接访问,StorageManager就是提供给应用层来访问存储服务的,它通过Binder机制与MountService所在进程进行通信,将使用者的请求转发进MountService中进行处理。目前StorageManager中支持的方法有enableUsbMassStoragedisableUsbMassStorageisUsbMassStorageConnectedisUsbMassStorageConnected。在StorageManager的构造函数中,还通过调用MountService中的registerListener函数来注册listenerMountService,同时,它自己也提供了registerListener函数供其它应用来注册listener,这样,当MountService知道存储设备状态变更时,会调用StorageManagerlistener的方法,而StorageManager又会继续回调上去,上层应用也就可以做相应的操作,比如图示的更新等。

MountService是一个服务类,在ServiceManager中注册为系统服务,提供对外部存储设备的管理、查询等服务,并在存储设备状态变更时发出通知。MountService起到了一个承上启下的作用,向上公开方法供上层对存储设备进行操作(enable/disable/mount…),并在存储设备状态变更时发出通知。向下接收Vold发来的事件(设备状态变更,设备插入,设备移除等),同时也会将命令发送给Vold,进行更底层的操作。

------------------

3.2 工作流程

工作流程有几个:首先是构造函数的准备工作、一些接口的被调用、以及监听回调。

1)      构造函数

Mediatek/custom/mt8389_tablet_a3v2/resource_overlay/generic/frameworks/base/core/res/res/xml/

<StorageList xmlns:android="http://schemas./apk/res/android">

    <!-- removable is not set in nosdcard product -->

    <storage android:mountPoint="/storage/sdcard0"

             android:storageDescription="@string/storage_usb"

           android:allowMassStorage="true"

           android:mtpReserve="10485760"

             android:primary="true" />

    <storage android:mountPoint="/storage/sdcard1"

             android:storageDescription="@string/storage_sd_card"

             android:removable="true"

           android:allowMassStorage="true"

           android:mtpReserve="10485760"

             android:primary="false" />

<storage android:mountPoint="/mnt/usbotg"

             android:storageDescription="@string/storage_external_usb"

             android:removable="true"

             android:primary="false" />                                                                                      

</StorageList>

但是vold 中关于外部存储器的挂载路径是在

mediatek /config/mt8389_tablet_a3v2/vold.fstab文件中指定的,

 dev_mount sdcard /storage/sdcard0 emmc@fat /devices/platform/goldfish_mmc.0

                                                               /devices/platform/mtk-msdc.0/mmc_host

  dev_mount sdcard2 /storage/sdcard1 auto /devices/platform/goldfish_mmc.1

                                                               /devices/platform/mtk-msdc.1/mmc_host

dev_mount usbotg /mnt/usbotg auto /devices/platform/mt_usb

                                                               /devices/platform/musbfsh_hdrc

       所以这个xmlvold.fstab的路径必须统一。

readStorageList函数通过解析xml,丰富了系统的分区信息。mVolumesmVolumeMapmPrimaryVolume 

2)      intent 接收处理

private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

            String action = intent.getAction();

通过在构造函数中注册intentfilter,接收系统发出的intent,执行相应的动作。

       3) Callback from NativeDaemonConnector

MountService注册到NativeDaemonConnector 的两个回调函数:onDaemonConnectedonEvent。在构造函数创建NativeDaemonConnector时,将MountService植入进了NativeDaemonConnector

onDaemonConnectedNativeDaemonConnector线程开始运行,创建socket监听时,执行一次。onEvent是在listenToSocket每次读取socket信息,然后通过mCallbackHandler发送消息,随后在handleMessage中调用onEvent

vold发生动作时,通过NativeDaemonConnector完成向上的通知。

NativeDaemonConnectorvold使用的是socket连接,大概使用流程如下:

{

LocalSocket socket = null;

socket = new LocalSocket();//创建socket

//创建目的地的socket地址

LocalSocketAddress address = new LocalSocketAddress(mSocket,

LocalSocketAddress.Namespace.RESERVED);//mSocketà "vold"

socket.connect(address);//连接目的socket

InputStream inputStream = socket.getInputStream()//获取inputStream

inputStream.read(buffer, start, BUFFER_SIZE - start);//读取socket数据

}

init.rc中,vold服务启动时,创建与framework通讯的socket

service vold /system/bin/vold

    class core

    socket vold stream 0660 root mount                                                                                      

    ioprio be 2

3)功能调用

              setUsbMassStorageEnabled,有其他功能直接调用。

mountVolume----àdoMountVolume-------àmConnector.execute(cmd);

3.3 使用方法

1)定义变量

private IMountService mMountService;

2)获取实例

mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));

    3)调用功能

mMountService.registerListener(mBinderListener);

3.4 MountService总结

MountService是一个核心处理功能,承上启下。他的具体功能通过他提供的各种方法来体现。如何工作上面的工作流程已经涵盖。

 volume demo

参考文档:

http://terryblog.blog.51cto.com/1764499/826656

android系统vold透析

这两篇文章已经讲的很好,下面只是部分功能点的说明。

         4.1 vold/kernel简介

----------网友

kernel层能检测到有新的设备接入,加载相应的驱动,但如何通知用户层呢?这就是sysfs的工作,内核中的sysfs机制要求当有新的驱动加载时给用户层发送相应的event.但这些event只尽告知的义务,具体怎么处理,这就是vold的事了。

uevent由内核发出,通过netlink sokect来传递给vold,在kobject被创建的时候,就会发生uevent的传递。对于未传递的uevent,会在kset下产生uevent文件,这是供用户态触发uevent使用的,通过向uevent档写入actionaddremove等),可以触发一个uevent,这些uevent可以被vold捕获,从而完成未完成的vold处理。在系统启动的时候,vold未启动的时候,这些uevent写入了uevent档,vold启动后,会扫描sys目录查找uevent,然后触发它们,来完成之前未完成的事宜。uevent文件的内容,就是uevent事件的数据。

Vold.fstab文件中的设备路径是设备在sys下的路径,并不是kernel为该设备创建的节点:

dev_mount sdcard /storage/sdcard0 emmc@fat /devices/platform/goldfish_mmc.0

                                                               /devices/platform/mtk-msdc.0/mmc_host

#######################

## Regular device mount

##

## Format: dev_mount <label> <mount_point> <part> <sysfs_path1...>

## label        - Label for the volume

## mount_point  - Where the volume will be mounted

## part         - Partition # (1 based), or 'auto' for first usable partition.

## <sysfs_path> - List of sysfs paths to source devices

######################

Kernel 创建完设备节点后又再sys下创建了相关的内容,进而发出了uevent,让vold中的socket,NetLinkManager.cpp来处理,进而根据vold.fstab的配置挂载到指定的目录。那么kernel是如何将sys下创建的目录对象和具体的设备对应起来的呢?todo:sys

4.2 vold 代码流程

       1)入口:System/vold/main.c

              a)创建3vold框架使用的对象

VolumeManager *vm;

    CommandListener *cl; 接收上层MountService的命令,分析后转给volumeManager,处理后返给MountService或者交给volume执行具体操作。

NetlinkManager *nm; 创建与内核通讯的socket,接收底层的信息,交给volumeManager

b)解析/etc/vold.fstab

       process_config

2)netlinkManager

3)commandListener

4)volumeManager

分区管理类,volume.cpp代理人。真正的分区动作都在volume.cpp来完成。

5)其他文件

Fat.cpp/bicr.cpp/Ext4.cpp

        这些都是volume等配套的具体功能文件,最后一个环节。 

2013-7-31: voldkernel配合工作的流程:首先vold在开始执行时,通过解析vold.fstab得知了该设备用户层最终需要管理的存储设备分区信息,针对需要挂载的分区信息,创建对应的DirectVolume,放入VolumeManager中进行管理。解析vold.fstab时如果是emmc是要从/proc/emmc中获取信息的,以防止vold.fstab写的信息有误。所以上面这部分工作只是准备工作,意思是当有对应的分区设备在内核空间出现时,用户空间应该如何去处理,挂载还是不挂载,挂载点是哪里。那么当内核空间的设备创建时通过uevent机制传递到netlinkManager时,会调用到netlinkHandler.cpponEvent,进入调用VolumeManagerhandleBlockEvent,意思是处理块设备变化,由于开始时已经将vold.fstab中的分区信息创建对应的DirectVolume添加到了VolumeManager容器中,然后找出容器中的某个DirectVolume执行handleBlockEvent


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多