• SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程


      每一个有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的实现位于frameworksasecmdsootanimationBootAnimation.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 ativelibsguiincludeguiSurfaceComposerClient.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
  • 相关阅读:
    三范式
    作用域
    函数传参
    js数据类型
    纯css小图标
    js生成div
    js模拟微信聊天窗口
    js图片切换
    js this指向
    常用实体字符
  • 原文地址:https://www.cnblogs.com/tsts/p/9748042.html
Copyright © 2020-2023  润新知