在前面一篇文章中,我們簡(jiǎn)要介紹了Android系統(tǒng)Surface機(jī)制中的SurfaceFlinger服務(wù)。SurfaceFlinger服務(wù)是在System進(jìn)程中啟動(dòng)的,并且負(fù)責(zé)統(tǒng)一管理設(shè)備的幀緩沖區(qū)。SurfaceFlinger服務(wù)在啟動(dòng)的過(guò)程中,會(huì)創(chuàng)建兩個(gè)線程,其中一個(gè)線程用來(lái)監(jiān)控控制臺(tái)事件,而另外一個(gè)線程用來(lái)渲染系統(tǒng)的UI。在本文中,我們就將詳細(xì)分析SurfaceFlinger服務(wù)的啟動(dòng)過(guò)程。 從前面Android系統(tǒng)進(jìn)程Zygote啟動(dòng)過(guò)程的源代碼分析一文可以知道,System進(jìn)程是由Zygote進(jìn)程啟動(dòng)的,并且是以Java層的SystemServer類的靜態(tài)成員函數(shù)main為入口函數(shù)的。因此,接下來(lái)我們就從SystemServer類的靜態(tài)成員函數(shù)main開始,分析SurfaceFlinger服務(wù)的啟動(dòng)過(guò)程,如圖1所示。 圖1 SurfaceFlinger服務(wù)的啟動(dòng)過(guò)程 SurfaceFlinger服務(wù)的啟動(dòng)過(guò)程可以劃分為8個(gè)步驟,接下來(lái)我們就詳細(xì)分析每一個(gè)步驟。 Step 1. SystemServer.main
SystemServer類的靜態(tài)成員函數(shù)main首先將android_servers庫(kù)加載到System進(jìn)程中來(lái),接著調(diào)用另外一個(gè)靜態(tài)成員函數(shù)init1來(lái)啟動(dòng)那些使用C++語(yǔ)言來(lái)實(shí)現(xiàn)的系統(tǒng)服務(wù)。 SystemServer類的靜態(tài)成員函數(shù)init1是一個(gè)JNI方法,它是由C++層的函數(shù)android_server_SystemServer_init1來(lái)實(shí)現(xiàn)的,接下來(lái)我們就繼續(xù)分析它的實(shí)現(xiàn)。 Step 2. SystemServer.init1
SystemServer類的靜態(tài)成員函數(shù)init1調(diào)用另外一個(gè)函數(shù)system_init來(lái)啟動(dòng)那些使用C++語(yǔ)言來(lái)實(shí)現(xiàn)的系統(tǒng)服務(wù),它的實(shí)現(xiàn)在文件frameworks/base/cmds/system_server/library/system_init.cpp中,如下所示:
函數(shù)接下來(lái)就檢查系統(tǒng)中是否存在一個(gè)名稱為“system_init.startsurfaceflinger”的屬性。如果存在的話,就將它的值獲取回來(lái),并且保存在緩沖區(qū)proBuf中。如果不存在的話,那么函數(shù)property_get就會(huì)將緩沖區(qū)proBuf的值設(shè)置為“1”。當(dāng)緩沖區(qū)proBuf的值等于“1”的時(shí)候,就表示需要在System進(jìn)程中將SurfaceFlinger服務(wù)啟動(dòng)起來(lái),這是通過(guò)調(diào)用SurfaceFlinger類的靜態(tài)成員函數(shù)instantiate來(lái)實(shí)現(xiàn)的。 函數(shù)最后檢查系統(tǒng)是否支持Binder進(jìn)程間通信機(jī)制。如果支持的話,那么接下來(lái)就會(huì)調(diào)用當(dāng)前進(jìn)程中的ProcessState單例的成員函數(shù)startThreadPool來(lái)啟動(dòng)一個(gè)Binder線程池,并且調(diào)用當(dāng)前線程中的IPCThreadState單例來(lái)將當(dāng)前線程加入到前面所啟動(dòng)的Binder線程池中去。從前面Android系統(tǒng)進(jìn)程Zygote啟動(dòng)過(guò)程的源代碼分析和Android應(yīng)用程序進(jìn)程啟動(dòng)過(guò)程的源代碼分析兩篇文章可以知道,System進(jìn)程前面在初始化運(yùn)行時(shí)庫(kù)的過(guò)程中,已經(jīng)調(diào)用過(guò)當(dāng)前進(jìn)程中的ProcessState單例的成員函數(shù)startThreadPool來(lái)啟動(dòng)Binder線程池了,因此,這里其實(shí)只是將當(dāng)前線程加入到這個(gè)Binder線程池中去。有了這個(gè)Binder線程池之后,SurfaceFlinger服務(wù)在啟動(dòng)完成之后,就可以為系統(tǒng)中的其他組件或者進(jìn)程提供服務(wù)了。 假設(shè)系統(tǒng)存在一個(gè)名稱為“system_init.startsurfaceflinger”的屬性,并且它的值等于“1”,接下來(lái)我們就繼續(xù)分析SurfaceFlinger類的靜態(tài)成員函數(shù)instantiate的實(shí)現(xiàn),以便可以了解SurfaceFlinger服務(wù)的啟動(dòng)過(guò)程。由于SurfaceFlinger類的靜態(tài)成員函數(shù)instantiate是從父類BinderService繼承下來(lái)的,因此,接下來(lái)我們要分析的實(shí)際上是BinderService類的靜態(tài)成員函數(shù)instantiate的實(shí)現(xiàn)。 Step 3. BinderService.instantiate
BinderService類的靜態(tài)成員函數(shù)instantiate的實(shí)現(xiàn)很簡(jiǎn)單,它只是調(diào)用BinderService類的另外一個(gè)靜態(tài)成員函數(shù)publish來(lái)繼續(xù)執(zhí)行啟動(dòng)SurfaceFlinger服務(wù)的操作。 Step 4. BinderService.publish
BinderService是一個(gè)模板類,它有一個(gè)模板參數(shù)SERVICE。當(dāng)BinderService類被SurfaceFlinger類繼承時(shí),模板參數(shù)SERVICE的值就等于SurfaceFlinger。因此,BinderService類的靜態(tài)成員函數(shù)publish所執(zhí)行的操作就是創(chuàng)建一個(gè)SurfaceFlinger實(shí)例,用來(lái)作為系統(tǒng)的SurfaceFlinger服務(wù),并且將這個(gè)服務(wù)注冊(cè)到Service Manager中去,這樣系統(tǒng)中的其它組件或者進(jìn)程就可以通過(guò)Service Manager來(lái)獲得SurfaceFlinger服務(wù)的Binder代理對(duì)象,進(jìn)而使用它所提供的服務(wù)。Binder進(jìn)程間通信機(jī)制中的服務(wù)對(duì)象的注冊(cè)過(guò)程可以參考Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析一文。 接下來(lái),我們就繼續(xù)分析SurfaceFlinger服務(wù)的創(chuàng)建過(guò)程。 Step 5. new SurfaceFlinger
這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。 從前面Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文可以知道,SurfaceFlinger類繼承了BnSurfaceComposer類,而后者是一個(gè)實(shí)現(xiàn)了ISurfaceComposer接口的Binder本地對(duì)象類。此外,SurfaceFlinger類還繼承了Thread類,后者是用來(lái)創(chuàng)建一個(gè)線程的,這個(gè)線程就是我們?cè)?a target="_blank">Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文中提到的UI渲染線程,它的線程執(zhí)行體函數(shù)為SurfaceFlinger類的成員函數(shù)threadLoop。后面在分析SurfaceFlinger服務(wù)渲染UI的過(guò)程時(shí),我們?cè)俜治鯯urfaceFlinger類的成員函數(shù)threadLoop的實(shí)現(xiàn)。注意,在初始化SurfaceFlinger的父類Thread時(shí),傳進(jìn)去的參數(shù)為false,表示先不要將SurfaceFlinger服務(wù)的UI渲染線程啟動(dòng)起來(lái),等到后面再啟動(dòng)。 SurfaceFlinger服務(wù)在創(chuàng)建的過(guò)程中,會(huì)調(diào)用SurfaceFlinger類的成員函數(shù)init來(lái)執(zhí)行初始化的操作,接下來(lái),我們就繼續(xù)分析它的實(shí)現(xiàn)。 Step 6. SurfaceFlinger.init
SurfaceFlinger類的成員函數(shù)init的實(shí)現(xiàn)很簡(jiǎn)單,它分別獲得系統(tǒng)中兩個(gè)名稱為“debug.sf.showupdates”和“debug.sf.showbackground”的屬性的值,并且分別保存在SurfaceFlinger類的成員變量mDebugRegion和mDebugBackground中。這兩個(gè)成員變量是與調(diào)試相關(guān)的,我們不關(guān)心。 這一步執(zhí)行完成之后,返回到前面的Step 4中,即BinderService類的靜態(tài)成員函數(shù)publish中,這時(shí)候在前面的Step 5中所創(chuàng)建的一個(gè)SurfaceFlinger實(shí)例就會(huì)被注冊(cè)到Service Manager中,這是通過(guò)調(diào)用Service Manager的Binder代理對(duì)象的成員函數(shù)addService來(lái)實(shí)現(xiàn)的。由于Service Manager的Binder代理對(duì)象的成員函數(shù)addService的第二個(gè)參數(shù)是一個(gè)類型為IBinder的強(qiáng)指針引用。從前面Android系統(tǒng)的智能指針(輕量級(jí)指針、強(qiáng)指針和弱指針)的實(shí)現(xiàn)原理分析一文可以知道,當(dāng)一個(gè)對(duì)象第一次被一個(gè)強(qiáng)指針引用時(shí),那么這個(gè)對(duì)象的成員函數(shù)onFirstRef就會(huì)被調(diào)用。因此,接下來(lái)前面所創(chuàng)建的SurfaceFlinger實(shí)例的成員函數(shù)onFirstRef就會(huì)被調(diào)用,以便可以繼續(xù)執(zhí)行初始化操作。 Step 7. SurfaceFlinger.onFirstRef
這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。 函數(shù)首先調(diào)用從父類繼承下來(lái)的成員函數(shù)run來(lái)啟動(dòng)一個(gè)名秒為“SurfaceFlinger”的線程,用來(lái)執(zhí)行UI渲染操作。這就是前面我們所說(shuō)的UI渲染線程了。這個(gè)UI渲染線程創(chuàng)建完成之后,首先會(huì)調(diào)用SurfaceFlinger類的成員函數(shù)readyToRun來(lái)執(zhí)行一些初始化操作,接著再循環(huán)調(diào)用SurfaceFlinger類的成員函數(shù)threadLoop來(lái)作為線程的執(zhí)行體。 mReadyToRunBarrier是SurfaceFlinger類的一個(gè)成員變量,它的類型是Barrier,用來(lái)描述一個(gè)屏障,是通過(guò)條件變量來(lái)實(shí)現(xiàn)的。我們可以把它看作是一個(gè)線程同步工具,即阻塞當(dāng)前線程,直到SurfaceFlinger服務(wù)的UI渲染線程執(zhí)行完成初始化操作為止。 接下來(lái),我們就繼續(xù)分析SurfaceFlinger類的成員函數(shù)readyToRun的實(shí)現(xiàn),以便可以了解SurfaceFlinger服務(wù)的UI渲染線程的初始化過(guò)程。 Step 8. SurfaceFlinger.oreadyToRun 這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp文件中,用來(lái)初始化SurfaceFlinger服務(wù)的UI渲染線程,我們分段來(lái)閱讀:
我們接著往下閱讀代碼:
這塊匿名共享內(nèi)存用來(lái)保存設(shè)備顯示屏的屬性信息,例如,寬度、高度、密度和每秒多少幀等信息,后面我們就會(huì)看到這塊匿名共享內(nèi)存的初始化過(guò)程。為什么會(huì)使用匿名共享內(nèi)存來(lái)保存設(shè)備顯示屏的屬性信息呢?這是為了方便將這些信息傳遞給系統(tǒng)中的其它進(jìn)程訪問(wèn)的。系統(tǒng)中的其它進(jìn)程可以通過(guò)調(diào)用調(diào)用SurfaceFlinger服務(wù)的代理對(duì)象的成員函數(shù)getCblk來(lái)獲得這塊匿名共享內(nèi)存的內(nèi)容。 我們?cè)俳又麻喿x代碼:
我們繼續(xù)往下閱讀代碼:
我們?cè)倮^續(xù)往下閱讀代碼:
我們?cè)倮^續(xù)往下閱讀最后一段代碼:
第一件事情是調(diào)用LayerDim類的靜態(tài)成員函數(shù)initDimmer來(lái)初始化LayerDim類。LayerDim類是用來(lái)描述一個(gè)具有顏色漸變功能的Surface的,這種類型的Surface與普通的Surface不一樣,前者是在后者的基礎(chǔ)上創(chuàng)建和渲染的。 第二件事情是調(diào)用SurfaceFlinger類的成員變量mReadyToRunBarrier所描述的一個(gè)屏障的成員函數(shù)open來(lái)告訴System進(jìn)程的主線程,即在前面的Step 7中正在等待的線程,SurfaceFlinger服務(wù)的UI渲染線程已經(jīng)創(chuàng)建并且初始化完成了,這時(shí)候System進(jìn)程的主線程就可以繼續(xù)向前執(zhí)行其它操作了。 第三件事情是調(diào)用函數(shù)property_set來(lái)設(shè)置系統(tǒng)中名稱為“ctl.start”的屬性,即將它的值設(shè)置為“bootanim”。從前面Android系統(tǒng)的開機(jī)畫面顯示過(guò)程分析一文可以知道,ctl.start是Android系統(tǒng)的一個(gè)控制屬性,當(dāng)它的值等于““bootanim”的時(shí)候,就表示要啟動(dòng)Android系統(tǒng)的開機(jī)動(dòng)畫。從這里就可以看出,當(dāng)我們看到Android系統(tǒng)的開機(jī)動(dòng)畫時(shí),就說(shuō)明Android系統(tǒng)的SurfaceFlinger服務(wù)已經(jīng)啟動(dòng)起來(lái)了。 至此,我們就分析完成SurfaceFlinger服務(wù)的啟動(dòng)過(guò)程中了。在分析過(guò)程中,有兩個(gè)比較重要的知識(shí)點(diǎn):第一個(gè)知識(shí)點(diǎn)是系統(tǒng)主顯示屏的創(chuàng)建和初始化過(guò)程,第二個(gè)知識(shí)點(diǎn)是UI渲染線程的執(zhí)行過(guò)程。在接下來(lái)的第一篇文章中,我們將詳細(xì)分析第一個(gè)知識(shí)點(diǎn)。在分析第一個(gè)知識(shí)點(diǎn)的過(guò)程中,會(huì)涉及到SurfaceFlinger服務(wù)的控制臺(tái)事件監(jiān)控線程的創(chuàng)建過(guò)程,因此,結(jié)合Step 2提到的Binder線程,以及Step 7提到的UI渲染線程,我們將在接下來(lái)的第二篇文章中,綜合描述SurfaceFlinger服務(wù)的線程協(xié)作模型。有了前面的基礎(chǔ)知識(shí)之后,在接下來(lái)的第三篇文章中,我們就將詳細(xì)分析第二個(gè)知識(shí)點(diǎn)。敬請(qǐng)關(guān)注! 老羅的新浪微博:http://weibo.com/shengyangluo,歡迎關(guān)注!
|
|