Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android4.2.2 SurfaceFlinger啟動流程詳解(一)

Android4.2.2 SurfaceFlinger啟動流程詳解(一)

編輯:關於Android編程

 

 

這周繼續我的Blog,前面幾篇博文簡單的介紹了閱讀Android FW的源碼所需要的基礎知識,主要和C++相關。從這篇博文開始將會和大家一起學習並總結SurfaceFlinger模塊在Android中的相關內容,本文主要描述的是SurfaceFlinger的詳細啟動流程。

 

1.SurfaceFlinger在哪裡啟動?

在android系統中一個核心的Service都有ServiceManager管理,核心Service啟動一般是在SystemServer來啟動,但是比較重要的Service會在Zygote啟動前,由init進程來負責直接啟動。故SurfaceFlinger作為一個核心Service,一般有下面2種啟動方式。

a.在systemserver中如何啟動。

源碼目錄/android/frameworks/base/cmds/system_server/library/system_init.cpp.

extern C status_t system_init()
{
    ALOGI(Entered system_init());

    sp proc(ProcessState::self());

    sp sm = defaultServiceManager();
    ALOGI(ServiceManager: %p
, sm.get());

    sp grim = new GrimReaper();
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);

    char propBuf[PROPERTY_VALUE_MAX];
    property_get(system_init.startsurfaceflinger, propBuf, 1);
    if (strcmp(propBuf, 1) == 0) {
        // Start the SurfaceFlinger
        SurfaceFlinger::instantiate();
    }

    property_get(system_init.startsensorservice, propBuf, 1);
    if (strcmp(propBuf, 1) == 0) {
        // Start the sensor service
        SensorService::instantiate();
    }
......
}

在這裡可以看到在systemserver的啟動過程中,property_get通過獲取system_init.startsurfaceflinger的屬性值,這個屬性值一般在init.rc中進配置,如果該數值為0,則賦值propBuf=1,故以此會使用system_init中來啟動SF。

 

b.相對比上面的啟動,另一種啟動就是直接像ServiceManager一樣,作為init進程中的一個Service來啟動。

在init.rc中添加如下配置代碼:

# Set this property so surfaceflinger is not started by system_init
setprop system_init.startsurfaceflinger 0

啟動SurfaceFlinger的過程:

469 service surfaceflinger /system/bin/surfaceflinger
470     class main
471     user system
472     group graphics drmrpc
473     onrestart restart zygote
474 

對於Service如何啟動,可以查看Blog:android系統啟動流程啟動畫面學習之init和init.rc分析的相關內容即可理解。

 

2.以第二種方式啟動來進一步分析SF,看看SurfaceFlinger的main函數源碼。

路徑:android/frameworks/native/cmds/surfaceflinger/main_surfaceflinger.cpp

int main(int argc, char** argv) {
    SurfaceFlinger::publishAndJoinThreadPool(true);
    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    ProcessState::self()->setThreadPoolMaxThreadCount(4);
    return 0;
}

要開始結束SurfaceFlinger的函數處理過程時,有必要先進SF的基本UML圖提出來,如下所示:

align=middle

 

step1: 調用publishAndJoinThreadPool函數:

該函數是C++裡一個帶默認參數的函數的,這裡傳入的參數的true。

    static void publishAndJoinThreadPool(bool allowIsolated = false) {
        sp sm(defaultServiceManager());
        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }

這裡會涉及到和ServerManger的交互,變量sm是SM在當前進程的一個代理proxy,用於Binder驅動的交互,而addService正是將SurfaceFlinger做為一個核心的系統服務注冊到SM當中。隨後就是當前進程由ProcessState通過依次調用會新run起來一個thread如下所示,Poolthread繼承與Thread類,故一旦run起來就運行thread的run函數故而依舊前面介紹的thread類是依次會執行PoolThread類的readyToRun和threadLoop;

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
        char buf[16];
        snprintf(buf, sizeof(buf), Binder_%X, s);
        ALOGV(Spawning new pooled thread, name=%s
, buf);
        sp t = new PoolThread(isMain);
        t->run(buf);
    }
}

在對應的threadLoop裡面可以找到IPCThreadState::self()->joinThreadPool(mIsMain);即新建一個IPCThreadState進程間通信的線程狀態類,該類的函數joinThreadPool
即是與Binder驅動交互的接口,核心是和內核Binder驅動進行talkWithDriver()以及executeCommand(), 因為當前的SurfaceFlinger已經進入了正常的運行狀態。

當然在本主線程也會 調用IPCThreadState::self()->joinThreadPool();進行Binder間的通信,確保通信的穩定性。

 

step2: 回歸SurfaceFlinger對象的創建
作為繼承了public BinderService模板類的SF,他的創建就在上文提到的publishAndJoinThreadPool函數中的

       sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);

new SERVICE() = new SurfaceFlinger().從這裡該進入SF的創建和相關初始化了

SF類的定義和初始化成員函數的文件目錄:

源文件/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp;頭文件/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.h;

如下是SF的狗構造函數,首先對基類BnSurfaceComposer、Thread進行初始化

SurfaceFlinger::SurfaceFlinger()
    :   BnSurfaceComposer(), Thread(false),
        mTransactionFlags(0),
        mTransactionPending(false),
        mAnimTransactionPending(false),
        mLayersRemoved(false),
        mRepaintEverything(0),
        mBootTime(systemTime()),
        mVisibleRegionsDirty(false),
        mHwWorkListDirty(false),
        mDebugRegion(0),
        mDebugDDMS(0),
        mDebugDisableHWC(0),
        mDebugDisableTransformHint(0),
        mDebugInSwapBuffers(0),
        mLastSwapBufferTime(0),
        mDebugInTransaction(0),
        mLastTransactionTime(0),
        mBootFinished(false)

這裡乘熱打鐵來看thread類,很容易知道必然有地方會run起thread類所屬的線程,好吧接下去揭開謎底所在,來看這個:

void SurfaceFlinger::onFirstRef()
{
    mEventQueue.init(this);

    run(SurfaceFlinger, PRIORITY_URGENT_DISPLAY);//啟動一個新的thread線程,調用thread類的run函數

    // Wait for the main thread to be done with its initialization
    mReadyToRunBarrier.wait();//等待線程完成相關的初始化
}

OK這個onFirstRef似乎特別熟悉,的確在Android FrameWork中的SP、RefBase、weakref_impl,Thread類裡面詳細說明了他的由來,其實也就是和RefBase的關系特別密切。一般new一個SP的模板類,會最終調用該類對象對Refase重載的onFirstRef()。這裡就可以看到進行了mEventQueue(在介紹SF的消息機制時再深入分析)的初始化以及啟動一個run函數。故最終調用SF的readyToRun和threadLoop。

 

 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved