Android SDCard UnMounted 流程分析(一)

來源:互聯網
上載者:User

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::threadStart, this)) {
        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();

     //代碼有所省略www.2cto.com
  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 。

 

摘自  Terry_龍  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.