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

博观而约取,厚积而薄发。这篇文章主要讲述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的实现位于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进行正常的通信。
借用其他博客的图片:
SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程

文章图片

【SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程】Android系统中,app与SurfaceFlinger之间的通信全部使用的是Binder通信,SurfaceFlinger部分Binder相关的类关系简单如下图所示:
 
SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程

文章图片

类型为Client的Binder本地对象是由SurfaceFlinger服务来负责创建的,并且运行在SurfaceFlinger服务中,用来代表使用SurfaceFlinger服务的一个客户端,即一个与UI相关的Android应用程序。 
由于Client类和BpSurfaceComposerClient类分别是一个Binder本地对象类和一个Binder代理对象类,它们都是根据Android系统在应用程序框架层提供的Binder进程间通信库来实现的,它们的实现结构图分别如下图所示
 
SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程

文章图片

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

文章图片

 
 
参与资料:
  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
 

    推荐阅读