原文出處——>[Android應用程序與SurfaceFlinger服務的連接過程分析](http://blog.csdn.net/luoshengyang/article/details/7857163)
前文在描述Android應用程序和SurfaceFlinger服務的關系時提到,每一個有UI的Android應用程序都需要與SurfaceFlinger服務建立一個連接,以便可以通過這個連接來請求SurfaceFlinger服務為它創建和渲染Surface。在本文中,我們將以Android系統的開機動畫應用程序為例,詳細描述Android應用程序是如何與SurfaceFlinger服務建立連接的。
Android系統的開機動畫是由應用程序bootanimation來實現的,它位于/system/bin目錄下,它的具體實現可以參考Android系統的開機畫面顯示過程分析一文。為什么要選擇Android系統的開機動畫來分析Android應用程序與SurfaceFlinger服務的連接過程呢?首先,負責實現開機動畫的應用程序bootanimation也是一個Android應用程序,只不過它是使用C++語言來開發的;其次,應用程序bootanimation是與UI相關的,即它與使用Java語言來開發的標準Android應用程序一樣,都需要使用SurfaceFlinger服務來創建和渲染自己的Surface,即開機動畫;第三,由于應用程序bootanimation不涉及用戶輸入,即不需要與用戶進行交互(觸摸屏、鍵盤等),因此它能夠以最簡潔的方式來體現Android應用程序與SurfaceFlinger服務的關系。
從前面Android系統的開機畫面顯示過程分析一文可以知道,Android系統的開機動畫是主要一個BootAnimation對象來實現,這個BootAnimation對象在構造的時候,會在內部創建一個SurfaceComposerClient對象來負責創建一個到SurfaceFlinger服務的連接。
BootAnimation類的構造函數實現在文件frameworks/base/cmds/bootanimation/BootAnimation.cpp中,如下所示:
~~~
BootAnimation::BootAnimation() : Thread(false)
{
mSession = new SurfaceComposerClient();
}
~~~
mSession是BootAnimation類的成員變量,它是一個類型為SurfaceComposerClient的強指針,即`sp<SurfaceComposerClient>`。Android系統的智能指針的相關知識,可以參考Android系統的智能指針(輕量級指針、強指針和弱指針)的實現原理分析一文。
在SurfaceComposerClient類內部,有一個類型為`sp<ISurfaceComposerClient>`的成員變量mClient,如圖1所示:

圖1 SurfaceComposerClient的結構示意圖
SurfaceComposerClient類的成員變量mClient指向的實際上是一個類型為BpSurfaceComposerClient的Binder代理對象,而這個類型為BpSurfaceComposerClient的Binder代理對象引用的是一個類型為Client的Binder本地對象。在前面Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一文中提到,類型為Client的Binder本地對象是由SurfaceFlinger服務來負責創建的,并且運行在SurfaceFlinger服務中,用來代表使用SurfaceFlinger服務的一個客戶端,即一個與UI相關的Android應用程序。
由于Client類和BpSurfaceComposerClient類分別是一個Binder本地對象類和一個Binder代理對象類,它們都是根據Android系統在應用程序框架層提供的Binder進程間通信庫來實現的,它們的實現結構圖分別如圖2和圖3所示:

圖2 Client類的實現結構圖

圖3 BpSurfaceComposerClient類的實現結構圖
在圖2和圖3中,涉及到了比較多的Binder進程間通信庫的類,需要讀者對Android系統的Binder進程間通信機制有一定的理解和認識。在前面的Android進程間通信(IPC)機制Binder簡要介紹和學習計劃一系列文章,我們已經學習過Android系統的Binder進程間通信機制了,這里不再詳述。
圖2和圖3給我們最重要的信息是Client類和BpSurfaceComposerClient類均實現了類型為ISurfaceComposerClient的Binder接口。ISurfaceComposerClient接口有兩個重要的成員函數getControlBlock和createSurface,它們定義在文件frameworks/base/include/surfaceflinger/ISurfaceComposerClient.h中,如下所示:
~~~
class ISurfaceComposerClient : public IInterface
{
public:
......
virtual sp<IMemoryHeap> getControlBlock() const = 0;
......
/*
* Requires ACCESS_SURFACE_FLINGER permission
*/
virtual sp<ISurface> createSurface( surface_data_t* data,
int pid,
const String8& name,
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags) = 0;
......
};
~~~
其中,成員函數getControlBlock用來獲得由SurfaceFlinger服務創建的一塊用來傳遞UI元數據的匿名共享內存,而成員函數createSurface用來請求SurfaceFlinger服務創建一個Surface。從前面Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一文可以知道,用來傳遞UI元數據的匿名共享內存最終會被結構化為一個SharedClient對象,這個SharedClient對象在每個應用程序進程中至多存在一個。在接下來的兩篇文章中,我們再詳細分析ISurfaceComposerClient接口的成員函數getControlBlock和createSurface的實現。
理解了SurfaceComposerClient、Client以及BpSurfaceComposerClient這三個類的關系之后,接下來我們就可以分析Android系統的開機動畫應用程序bootanimation是如何與SurfaceFlinger服務建立連接的。
從圖1可以知道,SurfaceComposerClient類繼承了RefBase類,因此,當BootAnimation類在構造函數創建了一個SurfaceComposerClient對象,并且將這個對象賦值給類型為sp<SurfaceComposerClient>的智能指針mSession時,就會導致SurfaceComposerClient類的成員函數onFirstRef被調用,而SurfaceComposerClient類的成員函數onFirstRef在調用的過程中,就會在應用程序bootanimation與SurfaceFlinger服務建立一個連接,這個過程如圖4所示:

圖4 Android應用程序與SurfaceFlinger服務的連接過程
接下來,我們就詳細分析每一個步驟。
Step 1. SurfaceComposerClient::onFirstRef
~~~
void SurfaceComposerClient::onFirstRef()
{
sp<ISurfaceComposer> sm(getComposerService());
if (sm != 0) {
sp<ISurfaceComposerClient> conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
......
mStatus = NO_ERROR;
}
}
}
~~~
SurfaceComposerClient類的成員函數onFirstRef實現在文件frameworks/base/libs/surfaceflinger_client/SurfaceComposerClient.cpp文件中。
SurfaceComposerClient類的成員函數getComposerService用來獲得SurfaceFlinger服務的一個代理接口,它的實現如下所示:
~~~
sp<ISurfaceComposer> ComposerService::getComposerService() {
return ComposerService::getInstance().mComposerService;
}
~~~
ComposerService類是單例模式,當我們第一次調用它的靜態函數getInstance的時候,它就會在構造函數中獲得SurfaceFlinger服務的一個代理接口,并且保存在它的成員變量mComposerService中,如下所示:
~~~
ComposerService::ComposerService()
: Singleton<ComposerService>() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
mServerCblkMemory = mComposerService->getCblk();
mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
mServerCblkMemory->getBase());
}
~~~
在ComposerService類的構造函數中,除了會獲得SurfaceFlinger服務的代理接口之外,還會通過這個代理接口的成員函數getCblk來獲得一塊匿名共享內存mServerCblkMemory。這塊匿名共享內存是由SurfaceFlinger服務創建的,用來描述系統顯示屏的信息,例如,顯示屏的個數、大小、方向、密度等等信息。由于這些信息可以通過一個surface_flinger_cblk_t對象來描述,因此,ComposerService類的構造函數最后就將前面從SurfaceFlinger服務獲得的一塊匿名共享內存結構化為一個surface_flinger_cblk_t對象,并且保存在ComposerService類的成員變量mServerCblk中。
回到SurfaceComposerClient類的成員函數onFirstRef中,由于SurfaceFlinger服務實現了ISurfaceComposer接口,因此,我們可以將前面獲得的SurfaceFlinger服務的代理接口賦值給一個類型為ISurfaceComposer的強指針sm,并且調用它的成員函數createConnection來請求SurfaceFlinger服務創建一個連接,即創建一個類型為Client的Binder對象,并且將這個Binder對象的一個代理接口conn返回來。SurfaceComposerClient類獲得了SurfaceFlinger服務返回來的Client代理接口conn之后,就將它保存自己的成員變量mClient中,這樣開機動畫應用程序bootanimation后續就可以通過它來請求SurfaceFlinger創建和渲染Surface了。
接下來,我們就繼續分析SurfaceFlinger服務的成員函數createConnection的實現,以便可以了解它是如何為Android應用程序創建一個連接的。
Step 2. SurfaceFlinger::createConnection
~~~
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this));
status_t err = client->initCheck();
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}
~~~
SurfaceFlinger類的成員函數createConnection實現在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,它的實現很簡單,只是創建了一個類型為Client的Binder對象client,并且獲得它的一個ISurfaceComposerClient接口,最后將這個ISurfaceComposerClient接口,即一個Client代理對象,返回給開機動畫應用程序bootanimation。
接下來,我們再繼續分析Client對象的創建過程,,即Client類的構造函數的實現。
Step 3. new Client
~~~
Client::Client(const sp<SurfaceFlinger>& flinger)
: mFlinger(flinger), mNameGenerator(1)
{
}
~~~
Client類有兩個成員變量mFlinger和mNameGenerator,它們的類型分別為sp<SurfaceFlinger>和int32_t,前者指向了SurfaceFlinger服務,而后者用來生成SurfaceFlinger服務為Android應用程序所創建的每一個Surface的名稱。例如,假設一個Android應用程序請求SurfaceFlinger創建了兩個Surface,那么第一個Surface的名稱就由數字1來描述,而第二個Surface就由數字2來描述,依次類推。從前面Android應用程序與SurfaceFlinger服務的關系概述和學習計劃這篇文章可以知道,一個Android應用程序最多可以創建31個Surface。
回到SurfaceFlinger類的成員函數createConnection中,它將一個指向了一個Client對象的ISurfaceComposerClient接口返回到開機動畫應用程序bootanimation之后,開機動畫應用程序bootanimation就可以將它封裝成一個類型為BpSurfaceComposerClient的Binder代理對象。
Step 4. return BpSurfaceComposerClient
類型為BpSurfaceComposerClient的Binder代理對象的封裝過程實現在SurfaceFlinger服務的Binder代理對象類BpSurfaceComposer的成員函數createConnection中,如下所示:
~~~
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
......
virtual sp<ISurfaceComposerClient> createConnection()
{
uint32_t n;
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
......
}
~~~
interface_cast是一個模板函數,它定義在framework/base/include/binder/IInterface.h文件中:
~~~
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
~~~
從這里就可以看出,當模板參數為ISurfaceComposerClient的時候,模板函數interface_cast實際就是通過調用ISurfaceComposerClient類的靜態成員函數asInterface來將參數obj所描述的一個Binder代理對象,即一個BpBinder對象,封裝成一個BpSurfaceComposerClient對象。
ISurfaceComposerClient類的靜態成員函數asInterface是由frameworks/base/libs/surfaceflinger_client/ISurfaceComposerClient.cpp文件中的IMPLEMENT_META_INTERFACE宏來定義的,如下所示:
~~~
IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
~~~
IMPLEMENT_META_INTERFACE宏展開后,得到ISurfaceComposerClient類的靜態成員函數asInterface的實現如下所示:
~~~
android::sp<ISurfaceComposerClient> ISurfaceComposerClient::asInterface(const android::sp<android::IBinder>& obj) {
android::sp<ISurfaceComposerClient> intr;
if (obj != NULL) {
intr = static_cast<ISurfaceComposerClient*>(
obj->queryLocalInterface(ISurfaceComposerClient::descriptor).get());
if (intr == NULL) {
intr = new BpSurfaceComposerClient(obj);
}
}
return intr;
}
~~~
參數obj是從BpSurfaceComposer類的成員函數createConnection傳進來的,它指向的實際上是一個BpBinder對象。當我們調用一個BpBinder對象的成員函數queryLocalInterface時,獲得的是一個NULL指針,因此,ISurfaceComposerClient類的靜態成員函數asInterface最后就會將參數obj所指向的一個BpBinder對象封裝成一個BpSurfaceComposerClient對象,并且返回給調用者。
BpSurfaceComposerClient對象的更具體封裝過程可以參考前面淺談Android系統進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路一文中所描述的BpServiceManager對象的封裝過程。
至此,開機動畫應用程序bootanimation就通過SurfaceComposerClient類來與SurfaceFlinger服務建立一個連接了。
在前面Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一文中提到,一個Android應用程序除了需要與SurfaceFlinger服務建立連接之外,還需要有一塊用來傳遞UI元數據的匿名共享內存,即一個SharedClient對象,因此,在接下來的一篇文章中,我們就繼續分析這塊匿名共享內存的創建過程,敬請期待!
- 前言
- Android組件設計思想
- Android源代碼開發和調試環境搭建
- Android源代碼下載和編譯
- Android源代碼情景分析法
- Android源代碼調試分析法
- 手把手教你為手機編譯ROM
- 在Ubuntu上下載、編譯和安裝Android最新源代碼
- 在Ubuntu上下載、編譯和安裝Android最新內核源代碼(Linux Kernel)
- 如何單獨編譯Android源代碼中的模塊
- 在Ubuntu上為Android系統編寫Linux內核驅動程序
- 在Ubuntu上為Android系統內置C可執行程序測試Linux內核驅動程序
- 在Ubuntu上為Android增加硬件抽象層(HAL)模塊訪問Linux內核驅動程序
- 在Ubuntu為Android硬件抽象層(HAL)模塊編寫JNI方法提供Java訪問硬件服務接口
- 在Ubuntu上為Android系統的Application Frameworks層增加硬件訪問服務
- 在Ubuntu上為Android系統內置Java應用程序測試Application Frameworks層的硬件服務
- Android源代碼倉庫及其管理工具Repo分析
- Android編譯系統簡要介紹和學習計劃
- Android編譯系統環境初始化過程分析
- Android源代碼編譯命令m/mm/mmm/make分析
- Android系統鏡像文件的打包過程分析
- 從CM刷機過程和原理分析Android系統結構
- Android系統架構概述
- Android系統整體架構
- android專用驅動
- Android硬件抽象層HAL
- Android應用程序組件
- Android應用程序框架
- Android用戶界面架構
- Android虛擬機之Dalvik虛擬機
- Android硬件抽象層
- Android硬件抽象層(HAL)概要介紹和學習計劃
- Android專用驅動
- Android Logger驅動系統
- Android日志系統驅動程序Logger源代碼分析
- Android應用程序框架層和系統運行庫層日志系統源代碼分析
- Android日志系統Logcat源代碼簡要分析
- Android Binder驅動系統
- Android進程間通信(IPC)機制Binder簡要介紹和學習計劃
- 淺談Service Manager成為Android進程間通信(IPC)機制Binder守護進程之路
- 淺談Android系統進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路
- Android系統進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析
- Android系統進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析
- Android系統進程間通信Binder機制在應用程序框架層的Java接口源代碼分析
- Android Ashmem驅動系統
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)驅動程序源代碼分析
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)在進程間共享的原理分析
- Android系統匿名共享內存(Anonymous Shared Memory)C++調用接口分析
- Android應用程序進程管理
- Android應用程序進程啟動過程的源代碼分析
- Android系統進程Zygote啟動過程的源代碼分析
- Android系統默認Home應用程序(Launcher)的啟動過程源代碼分析
- Android應用程序消息機制
- Android應用程序消息處理機制(Looper、Handler)分析
- Android應用程序線程消息循環模型分析
- Android應用程序輸入事件分發和處理機制
- Android應用程序鍵盤(Keyboard)消息處理機制分析
- Android應用程序UI架構
- Android系統的開機畫面顯示過程分析
- Android幀緩沖區(Frame Buffer)硬件抽象層(HAL)模塊Gralloc的實現原理分析
- SurfaceFlinger
- Android系統Surface機制的SurfaceFlinger服務
- SurfaceFlinger服務簡要介紹和學習計劃
- 啟動過程分析
- 對幀緩沖區(Frame Buffer)的管理分析
- 線程模型分析
- 渲染應用程序UI的過程分析
- Android應用程序與SurfaceFlinger服務的關系
- 概述和學習計劃
- 連接過程分析
- 共享UI元數據(SharedClient)的創建過程分析
- 創建Surface的過程分析
- 渲染Surface的過程分析
- Android應用程序窗口(Activity)
- 實現框架簡要介紹和學習計劃
- 運行上下文環境(Context)的創建過程分析
- 窗口對象(Window)的創建過程分析
- 視圖對象(View)的創建過程分析
- 與WindowManagerService服務的連接過程分析
- 繪圖表面(Surface)的創建過程分析
- 測量(Measure)、布局(Layout)和繪制(Draw)過程分析
- WindowManagerService
- WindowManagerService的簡要介紹和學習計劃
- 計算Activity窗口大小的過程分析
- 對窗口的組織方式分析
- 對輸入法窗口(Input Method Window)的管理分析
- 對壁紙窗口(Wallpaper Window)的管理分析
- 計算窗口Z軸位置的過程分析
- 顯示Activity組件的啟動窗口(Starting Window)的過程分析
- 切換Activity窗口(App Transition)的過程分析
- 顯示窗口動畫的原理分析
- Android控件TextView的實現原理分析
- Android視圖SurfaceView的實現原理分析
- Android應用程序UI硬件加速渲染
- 簡要介紹和學習計劃
- 環境初始化過程分析
- 預加載資源地圖集服務(Asset Atlas Service)分析
- Display List構建過程分析
- Display List渲染過程分析
- 動畫執行過程分析
- Android應用程序資源管理框架
- Android資源管理框架(Asset Manager)
- Asset Manager 簡要介紹和學習計劃
- 編譯和打包過程分析
- Asset Manager的創建過程分析
- 查找過程分析
- Dalvik虛擬機和ART虛擬機
- Dalvik虛擬機
- Dalvik虛擬機簡要介紹和學習計劃
- Dalvik虛擬機的啟動過程分析
- Dalvik虛擬機的運行過程分析
- Dalvik虛擬機JNI方法的注冊過程分析
- Dalvik虛擬機進程和線程的創建過程分析
- Dalvik虛擬機垃圾收集機制簡要介紹和學習計劃
- Dalvik虛擬機Java堆創建過程分析
- Dalvik虛擬機為新創建對象分配內存的過程分析
- Dalvik虛擬機垃圾收集(GC)過程分析
- ART虛擬機
- Android ART運行時無縫替換Dalvik虛擬機的過程分析
- Android運行時ART簡要介紹和學習計劃
- Android運行時ART加載OAT文件的過程分析
- Android運行時ART加載類和方法的過程分析
- Android運行時ART執行類方法的過程分析
- ART運行時垃圾收集機制簡要介紹和學習計劃
- ART運行時Java堆創建過程分析
- ART運行時為新創建對象分配內存的過程分析
- ART運行時垃圾收集(GC)過程分析
- ART運行時Compacting GC簡要介紹和學習計劃
- ART運行時Compacting GC堆創建過程分析
- ART運行時Compacting GC為新創建對象分配內存的過程分析
- ART運行時Semi-Space(SS)和Generational Semi-Space(GSS)GC執行過程分析
- ART運行時Mark-Compact( MC)GC執行過程分析
- ART運行時Foreground GC和Background GC切換過程分析
- Android安全機制
- SEAndroid安全機制簡要介紹和學習計劃
- SEAndroid安全機制框架分析
- SEAndroid安全機制中的文件安全上下文關聯分析
- SEAndroid安全機制中的進程安全上下文關聯分析
- SEAndroid安全機制對Android屬性訪問的保護分析
- SEAndroid安全機制對Binder IPC的保護分析
- 從NDK在非Root手機上的調試原理探討Android的安全機制
- APK防反編譯
- Android視頻硬解穩定性問題探討和處理
- Android系統的智能指針(輕量級指針、強指針和弱指針)的實現原理分析
- Android應用程序安裝過程源代碼分析
- Android應用程序啟動過程源代碼分析
- 四大組件源代碼分析
- Activity
- Android應用程序的Activity啟動過程簡要介紹和學習計劃
- Android應用程序內部啟動Activity過程(startActivity)的源代碼分析
- 解開Android應用程序組件Activity的"singleTask"之謎
- Android應用程序在新的進程中啟動新的Activity的方法和過程分析
- Service
- Android應用程序綁定服務(bindService)的過程源代碼分析
- ContentProvider
- Android應用程序組件Content Provider簡要介紹和學習計劃
- Android應用程序組件Content Provider應用實例
- Android應用程序組件Content Provider的啟動過程源代碼分析
- Android應用程序組件Content Provider在應用程序之間共享數據的原理分析
- Android應用程序組件Content Provider的共享數據更新通知機制分析
- BroadcastReceiver
- Android系統中的廣播(Broadcast)機制簡要介紹和學習計劃
- Android應用程序注冊廣播接收器(registerReceiver)的過程分析
- Android應用程序發送廣播(sendBroadcast)的過程分析