SurfaceFlinger系列01--Android應用與SurfaceFlinger的連接過程
每一個有UI的Android應用程序都需要與SurfaceFlinger服務建立一個連接,以便可以通過這個連接來請求SurfaceFlinger服務為它創建和渲染Surface。本文將詳細描述Android應用程序是如何與SurfaceFlinger服務建立連接的。
以開機動畫為示例進行講解有下面幾個好處:
- 實現開機動畫的應用程序bootanimation也是一個Android應用程序,只不過它是用C++語言來開發的;
- 應用程序bootanimation是與UI相關的,即它與使用Java語言來開發的標準Android應用程序一樣,都需要使用SurfaceFlinger服務來創建和渲染自己的Surface,即開機動畫;
- 第三,由於應用程序bootanimation不涉及用戶輸入,即不需要與用戶進行交互(觸摸屏、鍵盤等),因此它能夠以最簡潔的方式來體現Android應用程序與SurfaceFlinger服務的關系。
Android系統的開機動畫是主要一個BootAnimation對象來實現,這個BootAnimation對象在構造的時候,會在內部創建一個SurfaceComposerClient對象來負責創建一個到SurfaceFlinger服務的連接。
BootAnimation的實現位於frameworks\base\cmds\bootanimation\BootAnimation.cpp文件中,它在構造函數中創建了一個SurfaceComposerClient對象,mSession是BootAnimation類的成員變量,它是一個類型為SurfaceComposerClient的強指針,即sp<SurfaceComposerClient>:
BootAnimation::BootAnimation(sp<Callbacks> callbacks) : Thread(false), mClockEnabled(true), mTimeIsAccurate(false), mTimeFormat12Hour(false), mTimeCheckThread(NULL), mCallbacks(callbacks) { mSession = new SurfaceComposerClient(); ······ }
SurfaceComposerClient類定義位於frameworks\native\libs\gui\include\gui\SurfaceComposerClient.h中,它繼承於RefBase類,因此,當BootAnimation類在構造函數創建了一個SurfaceComposerClient對象,並且將這個對象賦值給類型為sp<SurfaceComposerClient>的智能指針mSession時,就會導致SurfaceComposerClient類的成員函數onFirstRef被調用,onFirstRef的實現如下:
void SurfaceComposerClient::onFirstRef() { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); if (sf != 0 && mStatus == NO_INIT) { auto rootProducer = mParent.promote(); sp<ISurfaceComposerClient> conn; conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) : sf->createConnection(); if (conn != 0) { mClient = conn; mStatus = NO_ERROR; } } }
ComposerService是一個單例類,它的主要功能就是用來保持與SurfaceFlinger的連接。來看getComposerService的具體實現:
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() { ComposerService& instance = ComposerService::getInstance(); Mutex::Autolock _l(instance.mLock); if (instance.mComposerService == NULL) { ComposerService::getInstance().connectLocked(); assert(instance.mComposerService != NULL); ALOGD("ComposerService reconnected"); } return instance.mComposerService; }
getComposerService方法中,先通過setInstance方法拿到了ComposerService類的唯一實例,然後調用connectLocked方法來與SurfaceFlinger建立連接,在connectLocked方法,通過IServiceManager::getService方法獲取了一個名為SurfaceFlinger的服務,這個就是SurfaceFlinger服務在啟動的時候向系統中註冊的服務名。
void ComposerService::connectLocked() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); } assert(mComposerService != NULL); …… }
跟蹤getService函數,發現是先調用了defaultServiceManager()函數返回了BpServiceManager對象,然後通過BpServiceManager::getService()方法拿到指定的服務
template<typename INTERFACE> status_t getService(const String16& name, sp<INTERFACE>* outService) { const sp<IServiceManager> sm = defaultServiceManager(); if (sm != nullptr) { *outService = interface_cast<INTERFACE>(sm->getService(name)); if ((*outService) != NULL) return NO_ERROR; } return NAME_NOT_FOUND; }
這樣,應用就與拿到的SurfaceFlinger服務。根據Binder通信相關的內容,可以知道這裏拿到其實是BpSurfaceComposer,即拿到的SurfaceFlinger系統服務的Bp端。
再到SurfaceComposerClient::onFirstRef函數中,拿到BpSurfaceComposer服務後,然後通過BpSurfaceComposer::createScopedConnection或BpSurfaceComposer::createConnection嘗試與服務建立連接。
下面我們來看,SurfaceFlinger是如何響應這一動作的。因為前面已經拿到了BpSurfaceComposer,所以我們以跟蹤BpSurfaceComposer的createConnection函數為例進行說明。這裏通過Bp端的remote()->transact接口向Bn(即SurfaceFlinger)端發起connect動作。remote()->transact實際最後調用的就是BpBinder::transact(…)接口。
class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { virtual sp<ISurfaceComposerClient> createConnection() { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply); return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } virtual sp<ISurfaceComposerClient> createScopedConnection( const sp<IGraphicBufferProducer>& parent) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(parent)); remote()->transact(BnSurfaceComposer::CREATE_SCOPED_CONNECTION, data, &reply); return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } }
SurfaceFlinger端通過onTransact接口收到CREATE_CONNECTION或CREATE_SCOPED_CONNECTION消息後,實際調用了父類BnSurfaceComposer::onTransact接口進行動作分發,這裏會再調到SurfaceFlinger的createConnection或createScopedConnection方法
status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case CREATE_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = IInterface::asBinder(createConnection());//回調SurfaceFlinger的createConnection接口 reply->writeStrongBinder(b); return NO_ERROR; } case CREATE_SCOPED_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IGraphicBufferProducer> bufferProducer = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); sp<IBinder> b = IInterface::asBinder(createScopedConnection(bufferProducer));//回調SurfaceFlinger的createConnection接口 reply->writeStrongBinder(b); return NO_ERROR; } …… } }
下面是SurfaceFlinger中兩個connect函數的實現。可以看到,這裏直接創建了一個Client對象,Client實現了BnSurfaceComposerClient類。
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() { return initClient(new Client(this)); } sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection( const sp<IGraphicBufferProducer>& gbp) { if (authenticateSurfaceTexture(gbp) == false) { return nullptr; } const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); if (layer == nullptr) { return nullptr; } return initClient(new Client(this, layer)); }
這裏將Client以ISurfaceComposerClient的形式返回給了BpSurfaceComposer。
再回到BpSurfaceComposer::createConnection函數中,SurfaceFlinger返回過來值是以reply的形式反映的。而reply.readStrongBinder()返回的其實就是BpBinder(handle)(詳見https://www.cnblogs.com/palance/p/5538562.html 分析)。
BpSurfaceComposer通過調用其interface_cast接口,將SurfaceFlinger返回來的ISurfaceComposerClient對象(實際就是Client對象)通過interface_cast<ISurfaceComposerClient>(Client對象)或interface_cast<ISurfaceComposerClient>(reply.readStrongBinder())進行處理,即拿到了SurfaceFlinger系統服務的Bp Client端,即BpSurfaceComposerClient。
ISurfaceComposerClient類對應的interface_cast接口如下
::android::sp<ISurfaceComposerClient> ISurfaceComposerClient::asInterface( const ::android::sp<::android::IBinder>& obj) { ::android::sp<ISurfaceComposerClient> intr; if (obj != nullptr) { intr = static_cast<ISurfaceComposerClient*>( obj->queryLocalInterface( ISurfaceComposerClient::descriptor).get()); if (intr == nullptr) { intr = new BpSurfaceComposerClient(obj); } } return intr; }
上面的過程總結如下幾個步驟:
- 應用創建SurfaceComposerClient對象,準備向SurfaceFlinger系統服務發起動作,由於SurfaceComposerClient繼承自RefBase,因此會觸發SurfaceComposerClient::onFirstRef函數。
- 在onFirstRef函數中,SurfaceComposerClient通過IServiceManager::getService方法拿到了SurfaceFlinger系統的代理端BpSurfaceComposer。接口馬上通過BpSurfaceComposer向SurfaceFlinger發起connect請求(Bp向Bn發起請求動作)。
- SurfaceFlinger接收到請求後,在本地創建一個本地代理對象Client(這是ClientBnSurfaceComposerClient端的),然後將該對象以ISrufaceComposerClient的形式返回給BpSurfaceComposer;
- BpSurfaceComposer接收到SurfaceFlinger返回過來的Client對象後,通過ISurfaceComposerClient::asInterface函數將Client對象轉換成BpSurfaceComposerClient對象。
- SurfaceComposerClient::onFirstRef函數執行完後,APP就與SurfaceFlinger服務成功建立連接了,後面就可以通過這個SurfaceFlinger的Client Proxy與SurfaceFlinger進行正常的通信。
借用其他博客的圖片:
Android系統中,app與SurfaceFlinger之間的通信全部使用的是Binder通信,SurfaceFlinger部分Binder相關的類關系簡單如下圖所示:
類型為Client的Binder本地對象是由SurfaceFlinger服務來負責創建的,並且運行在SurfaceFlinger服務中,用來代表使用SurfaceFlinger服務的一個客戶端,即一個與UI相關的Android應用程序。
由於Client類和BpSurfaceComposerClient類分別是一個Binder本地對象類和一個Binder代理對象類,它們都是根據Android系統在應用程序框架層提供的Binder進程間通信庫來實現的,它們的實現結構圖分別如下圖所示
參與資料:
- 開機動畫詳解: https://blog.csdn.net/luoshengyang/article/details/7691321
- 應用程序與SurfaceFlinger連接: https://blog.csdn.net/luoshengyang/article/details/7857163
- Android Binder通信: https://blog.csdn.net/luoshengyang/article/details/6618363
SurfaceFlinger系列01--Android應用與SurfaceFlinger的連接過程