Android 12(S) 圖形顯示系統 – 應用建立和SurfaceFlinger的溝通橋樑(三)
- 2022 年 1 月 21 日
- 筆記
- Android 圖形圖像, Android圖形
1 前言
上一篇文章中我們已經創建了一個Native示例應用,從使用者的角度了解了圖形顯示系統API的基本使用,從這篇文章開始我們將基於這個示例應用深入圖形顯示系統API的內部實現邏輯,分析運作流程。
本篇將聚焦應用和SurfaceFlinger的活動,即應用是如何與SurfaceFlinger這個服務建立連接並進行通信的。讓我們開始吧!
註:本篇涉及的代碼位置:
/frameworks/native/libs/gui/include/gui/
/frameworks/native/libs/gui/include/private/gui/
/frameworks/native/services/surfaceflinger/
2 應用和SurfaceFlinger的通信
應用運行一開始便首先要去創建一個Native Surface,此時即開始了與SurfaceFlinger的互動,分步來看創建Surface的過程:
- SurfaceFlinger系統服務的Binder RPC架構
在分析詳細的代碼前,我想先展示一下 SurfaceFlinger系統服務的Binder RPC架構,其中涉及哪些類?哪些接口?它們之間的關係如何?在宏觀上去對這些對象的關係做了解,有助於我們理解具體的代碼分析。
先看一張基本的類圖:

SurfaceFlinger作為典型的Binder系統服務,遵循Binder服務設計的一般原則:
Interface接口:ISurfaceComposer 、ISurfaceComposerClient
Bp客戶端:BpSurfaceComposer、BpSurfaceComposerClient
Bn服務端:BnSurfaceComposer、BnSurfaceComposerClient
服務實現:SurfaceFlinger、Client
具體Binder的原理在此就不展開講了,相信你在網絡上可以搜索到很多優秀的講解文章。
這裡請先留意兩點:
- ComposerService中有成員mComposerService,它代表了SurfaceFlinger服務的代理客戶端;
- SurfaceComposerClient中有成員mClient,它代表了SurfaceFlinger服務進程中的Client的代理客戶端(這裡應該是涉及所謂的匿名Binder的概念)
推薦兩篇博文://blog.csdn.net/lewif/article/details/50696510
//my.oschina.net/u/3897543/blog/4750360
- 創建SurfaceComposerClient並建立與SurfaceFlinger的連接
應用首先去創建SurfaceComposerClient對象,透過這個對象建立和SurfaceFlinger的連接並進行後續的互動:
sp<SurfaceComposerClient> surfaceComposerClient = new SurfaceComposerClient;
status_t err = surfaceComposerClient->initCheck();
if (err != NO_ERROR) {
ALOGD("SurfaceComposerClient::initCheck error: %#x\n", err);
return;
}
SurfaceComposerClient 的定義非常簡單,繼承RefBase,其中成員mClient持有遠程服務的代理客戶端,基本操作都是以它作為橋樑傳遞到SurfaceFlinger的,如下:
// /frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h
class SurfaceComposerClient : public RefBase
{
public:
SurfaceComposerClient();
SurfaceComposerClient(const sp<ISurfaceComposerClient>& client);
virtual ~SurfaceComposerClient();
......
private:
sp<ISurfaceComposerClient> mClient;
}
SurfaceComposerClient 的構造函數也十分簡單,進行mStatus的初始化,其中mClient也可以外部傳遞進來初始值,或在onFirstRef的時候進行設置:
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT)
{
}
SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
: mStatus(NO_ERROR), mClient(client)
{
}
對象第一次引用onFirstRef的時候,才真正的去建立和SurfaceFlinger的連接:
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
先看一下ComposerService的定義,這是一個Singleton,它持有SurfaceFlinger服務的代理客戶端:sp<ISurfaceComposer> mComposerService
// /frameworks/native/libs/gui/include/private/gui/ComposerService.h
// This holds our connection to the composer service (i.e. SurfaceFlinger).
class ComposerService : public Singleton<ComposerService>
{
sp<ISurfaceComposer> mComposerService; // composer service的代理端
sp<IBinder::DeathRecipient> mDeathObserver;
Mutex mLock;
ComposerService();
bool connectLocked();
void composerServiceDied();
friend class Singleton<ComposerService>;
public:
// Get a connection to the Composer Service. This will block until
// a connection is established. Returns null if permission is denied.
static sp<ISurfaceComposer> getComposerService();
};
ComposerService在構建時,調用connectLocked獲取SurfaceFlinger(composer service)服務的代理客戶端:
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
// ComposerService的構造函數,調用到connectLocked去創建和SurfaceFlinger的連接
ComposerService::ComposerService()
: Singleton<ComposerService>() {
Mutex::Autolock _l(mLock);
connectLocked();
}
bool ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
mComposerService = waitForService<ISurfaceComposer>(name); // 通過ServiceManager去獲取SurfaceFlinger這個系統服務
if (mComposerService == nullptr) {
return false; // fatal error or permission problem
}
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService& mComposerService;
virtual void binderDied(const wp<IBinder>& who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get());
mComposerService.composerServiceDied();
}
public:
explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
};
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
return true;
}
上面connectLocked方法可以看到調用waitForService去向ServiceManager請求名稱為SurfaceFlinger的系統服務,成功後就取得了SurfaceFlinger這個系統服務的遠程代理客戶端,之後就可以透過這個代理跨進程與SurfaceFlinger進行互動了。
DeathObserver是一個監聽器,用於監聽遠程服務的狀態,當遠程服務異常退出Died,觸發該監聽器,進而呼叫到mComposerService.composerServiceDied()做一些清理保護
void ComposerService::composerServiceDied()
{
Mutex::Autolock _l(mLock);
mComposerService = nullptr;
mDeathObserver = nullptr;
}
再回到SurfaceComposerClient::onFirstRef方法中,透過ComposerService::getComposerService()獲取到SurfaceFlinger服務的代理客戶端後,接下來就是去初始化mClient了
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
sp<ISurfaceComposerClient> conn;
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
進而調用到了
// /frameworks/native/libs/gui/include/gui/ISurfaceComposer.h
/*
* Create a connection with SurfaceFlinger.
*/
virtual sp<ISurfaceComposerClient> createConnection() = 0;
createConnection是一個典型的Binder C/S架構下的跨進程調用,傻瓜式的理解調用流程:
// 客戶端端發送信息
BpSurfaceComposer::createConnection() {
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
==>
// 服務端接收到信息
status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
status_t credentialCheck = CheckTransactCodeCredentials(code);
if (credentialCheck != OK) {
return credentialCheck;
}
status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
....
}
BnSurfaceComposer::onTransact() {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> b = IInterface::asBinder(createConnection());
reply->writeStrongBinder(b);
return NO_ERROR;
}
}
==>
// 服務具體實現
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
const sp<Client> client = new Client(this);
return client->initCheck() == NO_ERROR ? client : nullptr;
}
SurfaceFlinger::createConnection方法中創建一個Client對象,Client繼承自BnSurfaceComposerClient實現ISurfaceComposerClient接口,可以利用Binder機制傳遞迴客戶端。而且Client對象中含有SurfaceFlinger成員,這樣SurfaceComposerClient::mClient就和SurfaceFlinger建立了連接。
Tips:
SurfaceFlinger進程中創建的Client對象,透過Binder IPC機制返回到了應用進程中,這裡的具體原理感興趣的可以研究下IInterface::asBinder / writeStrongBinder / readStrongBinder / interface_cast 這些方法。這裡我們就傻瓜式的理解為SurfaceComposerClient::mClient是SurfaceFlinger進程中Client對象的代理客戶端,使用SurfaceComposerClient::mClient就可以呼叫到SurfaceFlinger進程中Client對象的方法。
前面的講解看起來紛紛擾擾,簡單的,抽象的概括就是:
- 創建SurfaceComposerClient對象;
- SurfaceComposerClient::onFirstRef方法中透過ComposerService::getComposerService()獲取到SurfaceFlinger服務的代理客戶端;
- 調用SurfaceFlinger服務的代理客戶端的createConnection方法,進而跨進程調用到SurfaceFlinger::createConnection方法;
- SurfaceFlinger::createConnection方法中創建一個Client對象,並透過Binder返回給SurfaceComposerClient::mClient;
之後再調用SurfaceComposerClient中的方法時就可以通過mClient這個客戶端去呼叫到SurfaceFlinger服務的功能了
結合上面的類圖和下面的時序圖,大概總結如下

3 小結
這一篇文章中講解了應用進程中如何建立和SurfaceFlinger溝通的橋樑,即得到SurfaceFlinger的遠程代理客戶端,之後就通過這個代理客戶端向SurfaceFlinger發送請求或獲取信息。
必讀:
Android 12(S) 圖形顯示系統 – 開篇


