码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2018-10-06 18:57:04      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:mon   建立   assert   本地   image   详细   case   cloc   set   

  每一个有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的连接过程

标签:mon   建立   assert   本地   image   详细   case   cloc   set   

原文地址:https://www.cnblogs.com/tsts/p/9748042.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!