1. 程式人生 > >SurfaceFlinger系列01--Android應用與SurfaceFlinger的連接過程

SurfaceFlinger系列01--Android應用與SurfaceFlinger的連接過程

ech base instance ret 一個 函數 結構 center 對象賦值

  每一個有UI的Android應用程序都需要與SurfaceFlinger服務建立一個連接,以便可以通過這個連接來請求SurfaceFlinger服務為它創建和渲染Surface。本文將詳細描述Android應用程序是如何與SurfaceFlinger服務建立連接的。

以開機動畫為示例進行講解有下面幾個好處:

  1. 實現開機動畫的應用程序bootanimation也是一個Android應用程序,只不過它是用C++語言來開發的;
  2. 應用程序bootanimation是與UI相關的,即它與使用Java語言來開發的標準Android應用程序一樣,都需要使用SurfaceFlinger服務來創建和渲染自己的Surface,即開機動畫;
  3. 第三,由於應用程序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;                                                        }

上面的過程總結如下幾個步驟:

  1. 應用創建SurfaceComposerClient對象,準備向SurfaceFlinger系統服務發起動作,由於SurfaceComposerClient繼承自RefBase,因此會觸發SurfaceComposerClient::onFirstRef函數。
  2. 在onFirstRef函數中,SurfaceComposerClient通過IServiceManager::getService方法拿到了SurfaceFlinger系統的代理端BpSurfaceComposer。接口馬上通過BpSurfaceComposer向SurfaceFlinger發起connect請求(Bp向Bn發起請求動作)。
    1. SurfaceFlinger接收到請求後,在本地創建一個本地代理對象Client(這是ClientBnSurfaceComposerClient端的),然後將該對象以ISrufaceComposerClient的形式返回給BpSurfaceComposer;
    2. BpSurfaceComposer接收到SurfaceFlinger返回過來的Client對象後,通過ISurfaceComposerClient::asInterface函數將Client對象轉換成BpSurfaceComposerClient對象。
  3. 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進程間通信庫來實現的,它們的實現結構圖分別如下圖所示

技術分享圖片

技術分享圖片

參與資料:

  1. 開機動畫詳解: https://blog.csdn.net/luoshengyang/article/details/7691321
  2. 應用程序與SurfaceFlinger連接: https://blog.csdn.net/luoshengyang/article/details/7857163
  3. Android Binder通信: https://blog.csdn.net/luoshengyang/article/details/6618363

SurfaceFlinger系列01--Android應用與SurfaceFlinger的連接過程