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