android下usb框架系列文章---(3)Storage框架整理

Storage框架整理

一 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。下面注册到StorageManager的listener就是继承于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(newListenerDelegate(listener));

       }

   }

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

    privateList mListeners = newArrayList();

mListeners.add(newListenerDelegate(listener));

      另外一个功能就是向mountService注册listener,StorageManager也是个中间者,拿不到一手信息,需要从上线拿到资源,所以它需要向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 implementsIBinder.DeathRecipient {

       final IMountServiceListener mListener;

       MountServiceBinderListener(IMountServiceListener listener){

           mListener= listener;

       }

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

3)     从底向上的触发

MountService的onEvent会收到底层的调用,进而触发相应的动作,例如调用updatePublicVolumeState,这里边就会调用注册进来的listener的成员函数;bl.mListener.onStorageStateChanged。这样就进入到了StorageManager,其中的listener,MountServiceBinderListener的onStorageStateChanged会被触发。进而依次触发每一个注册到StorageManager的listener,sendStorageStateChanged,发出EVENT_STORAGE_STATE_CHANGED消息。在每个listener注册到StorageManager时,通过ListenerDelegate进行过一次打包,在其构造函数中对每个listener创建了一个handler,不停的接收消息并处理。当接收到EVENT_STORAGE_STATE_CHANGED后就调用注册进来的listener的onStorageStateChanged方法。如上即为com.android.systemui.usb.StorageNotification的onStorageStateChanged函数,所以该类的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 MountService与StorageManager的交互   

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

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

MountService是运行在SystemService这个进程中,所以上层应用无法直接访问,StorageManager就是提供给应用层来访问存储服务的,它通过Binder机制与MountService所在进程进行通信,将使用者的请求转发进MountService中进行处理。目前StorageManager中支持的方法有enableUsbMassStorage,disableUsbMassStorage,isUsbMassStorageConnected,isUsbMassStorageConnected。在StorageManager的构造函数中,还通过调用MountService中的registerListener函数来注册listener到MountService,同时,它自己也提供了registerListener函数供其它应用来注册listener,这样,当MountService知道存储设备状态变更时,会调用StorageManager中listener的方法,而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/storage_list.xml

   

   /storage/sdcard0"

            android:storageDescription="@string/storage_usb"

          android:allowMassStorage="true"

          android:mtpReserve="10485760"

            android:primary="true"/>

   

   /storage/sdcard1"

            android:storageDescription="@string/storage_sd_card"

            android:removable="true"

          android:allowMassStorage="true"

          android:mtpReserve="10485760"

            android:primary="false" />

 

/mnt/usbotg"

            android:storageDescription="@string/storage_external_usb"

            android:removable="true"

            android:primary="false"/>                                                                                     

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

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

 dev_mountsdcard /storage/sdcard0 emmc@fat/devices/platform/goldfish_mmc.0

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

  dev_mountsdcard2 /storage/sdcard1 auto/devices/platform/goldfish_mmc.1

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

dev_mount usbotg /mnt/usbotgauto /devices/platform/mt_usb

                                                              /devices/platform/musbfsh_hdrc

      所以这个xml和vold.fstab的路径必须统一。

readStorageList函数通过解析xml,丰富了系统的分区信息。mVolumes、mVolumeMap和mPrimaryVolume。

 

2)     intent 接收处理

privatefinal BroadcastReceiver mBroadcastReceiver = newBroadcastReceiver() {

           String action = intent.getAction();

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

      3) Callback from NativeDaemonConnector

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

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

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

NativeDaemonConnector和vold使用的是socket连接,大概使用流程如下:

{

LocalSocketsocket = null;

socket = newLocalSocket();//创建socket

//创建目的地的socket地址

LocalSocketAddress address = newLocalSocketAddress(mSocket,

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

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

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

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

}

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

service vold/system/bin/vold

    classcore

   socket vold stream 0660 rootmount                                                                                      

    iopriobe 2

3)功能调用

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

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

 

3.3 使用方法

1)定义变量

privateIMountService mMountService;

2)获取实例

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

   3)调用功能

mMountService.registerListener(mBinderListener);

3.4 MountService总结

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

四 volumedemo

参考文档:

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

android系统vold透析

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

        4.1 vold/kernel简介

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

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

uevent由内核发出,通过netlinksokect来传递给vold,在kobject被创建的时候,就会发生uevent的传递。对于未传递的uevent,会在kset下产生uevent文件,这是供用户态触发uevent使用的,通过向uevent档写入action(add,remove等),可以触发一个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 devicemount

##

## Format: dev_mount

## label       -Label for the volume

##mount_point  - Where the volume will bemounted

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

## - List of sysfs paths tosource devices

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

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

4.2 vold 代码流程

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

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

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

你可能感兴趣的:(USB)