Android SDCard UnMounted 流程分析(一)


Android SDCard框架 

Android SDCard框架,我們修改一般涉及到四大模塊

  1. Linux Kernel 用於檢測熱拔插,作為框架開發者來說,這者不用涉及
  2. Vold 作為Kernel 與 Framework 之間的橋梁
  3. Framework 操作Vold ,給Vold 下發操作命令
  4. UI 與Framework 交互,用於掛載/卸載SD卡

框架涉及的源碼位置

Vold :System/vold

        為vold 提供接口:System/Netd

        其他涉及的部分:System/core/libsysutils/src

                               System/core/include/sysutils

 

Framework:frameworks/base/services/java/com/android/server 

                 訪問和提供接口類:framework/base/core/java/android/os/storage/ 

                 可能還要參考的庫:framework/base/libs/storage

                                          framework/base/native

UI:Settings/src/com/android/setting/deviceinfo

 

SDCard UnMounted流程分析

初始化 

VolumeManager, CommandListener, NetlinkManager 都是在 main()函數里面初始化的。

其中 VolumeManager,NetlinkManager 內部采用單例模式。
(1) Class NetlinkManager 主要是創建於內核通信的 socket,接收來自底層的信息,然后傳交給VolumeManager 處理。
(2) class CommandListener 主要收到上層 MountService 通過 doMountVolume 發來的命令,分析后,轉交給 VolumeManager 處理;VolumeManager 處理信息后,或報告給上層 MountService,
或交給 volume 執行具體操作。CommandListener在main()初始化后,之后開始監聽,會開一個線程不停的監聽來自內核的消息。

深入main文件

 在Vold 的main.cpp里面,啟動一個線程用來監聽kernel 發出unMounted 的uevent事件,代碼:

 NetlinkManager *nm;
// NetlinkManager內部使用的單例模式
  if (!(nm = NetlinkManager::Instance())) {
        SLOGE( " Unable to create NetlinkManager ");
        exit( 1);
    };

// 開始監聽,從服務啟動就一直監聽
if ( nm->start()) {
        SLOGE( " Unable to start NetlinkManager (%s) ", strerror(errno));
        exit( 1);
    } 

 

 NetlinkManager的start 函數是實例化了一個NetlinkHandler(繼承關系:NetlinkHandler->NetlinkListener->SocketLinstener),並調用handler 的start方法,如下代碼:

  mHandler =  new NetlinkHandler(mSock);
     if ( mHandler->start()) {
        SLOGE( " Unable to start NetlinkHandler: %s ", strerror(errno));
         return - 1;
    } 

 

 深入NetlinkHandler 的start函數,見代碼:

int NetlinkHandler::start() {
     return  this-> startListener();

 

 上面有說過NetlinkHandler其實是SocketLinstener的子類,NetlinkHandler直接調用父類的startListener 方法,startListener開啟了一個線程用來執行threadStart函數,代碼太多,貼出主心代碼:

  if (pthread_create(&mThread, NULL,  SocketListener::threadStartthis)) {
        SLOGE( " pthread_create (%s) ", strerror(errno));
         return - 1;
    } 

 

而threadStart函數則調用了runListener方法,代碼如下:

void *SocketListener::threadStart( void *obj) {
    SocketListener *me = reinterpret_cast<SocketListener *>(obj);

     me->runListener();
    pthread_exit(NULL);
     return NULL;

 runListener會判斷socket 有無信息可讀,不會阻滯UI,最后調用onDataAvailable函數,代碼:

void SocketListener::runListener() {

 SocketClientCollection *pendingList =  new SocketClientCollection();

      //代碼有所省略
  while (!pendingList->empty()) {
            /* Pop the first item from the list */
            it = pendingList->begin();
            SocketClient* c = *it;
            pendingList->erase(it);
            /* Process it, if false is returned and our sockets are
             * connection-based, remove and destroy it */
            if (! onDataAvailable(c) && mListen) {
                /* Remove the client from our array */
                pthread_mutex_lock(&mClientsLock);
                for (it = mClients->begin(); it != mClients->end(); ++it) {
                    if (*it == c) {
                        mClients->erase(it);
                        break;
                    }
                }
                pthread_mutex_unlock(&mClientsLock);
                /* Remove our reference to the client */
                c->decRef();
            }
        }

}

 

 onDataAvailable會處理來自uEvent 的命令,並最終調用onEvent函數,onDataAvailable 位於System/core/libsysutils/src/NetlinkListener.cpp 這個主要處理一些socket方法的知識,一般不用修改。

最后由Netlinklinstener 來解析 ,代碼:

bool NetlinkListener::onDataAvailable(SocketClient *cli)
{
     int socket = cli->getSocket();
    ssize_t count;

    count = TEMP_FAILURE_RETRY( uevent_kernel_multicast_recv(socket, mBuffer,  sizeof(mBuffer)));
     if (count <  0) {
        SLOGE( " recvmsg failed (%s) ", strerror(errno));
         return  false;
    }

    NetlinkEvent *evt =  new NetlinkEvent();
     if (!evt->decode(mBuffer, count, mFormat)) {
        SLOGE( " Error decoding NetlinkEvent ");
    }  else {
         onEvent(evt);
    }

    delete evt;
     return  true;

 

小結

NetlinkManager其實就是用來處理uEvent 命令,並最終發送到vold/NetlinkHandler 的onEvent 。

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM