Binder进程间通信机制在Android系统中无处不在,SurfaceFlinger服务依然采用Binder通信方式,每个应用程序进程在请求SurfaceFlinger服务时,首先需要获取SurfaceFlinger服务的代理对象,通过该 代理对象请求SurfaceFlinger为该应用程序进程在SurfaceFlinger服务端创建一个Client对象,该 对象专门接收处理当前应用程序的请求。Android系统中SurfaceFlinger的设计框架如下:
在Android SurfaceFlinger服务启动过程源码分析中已经介绍了SurfaceFlinger服务可以以服务进程方式启动,也可以以服务线程方式启动,当SurfaceFlinger服务以服务进程启动时,SurfaceFlinger运行在SurfaceFlinger进程中,当SurfaceFlinger服务以服务线程方式启动时,SurfaceFlinger服务运行在SystemServer进程中。Android应用程序也运行在独立的进程中,因此Android应用程序与SurfaceFlinger服务的交互就涉及到了Binder进程间通信。在学习SurfaceFlinger之前,需要先了解Android系统的Binder进程间通信方式,关于Binder进程间通信在Binder通信模块中通过一系列文章进行了详细的分析介绍。下图就是SurfaceFlinger在Binder通信框架下的类关系图:
当应用程序需要请求SurfaceFlinger服务时,首先需要构造SurfaceComposerClient对象,通过SurfaceComposerClient对象就可以访问SurfaceFlinger服务了。
SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT), mComposer(Composer::getInstance()){}SurfaceComposerClient有两个成员变量,一个是BpSurfaceComposerClient,当应用程序连接上SurfaceFlinger服务后,SurfaceFlinger会为应用程序创建一个Client对象,并返回代理对象BpSurfaceComposerClient给应用程序。另一个是Composer,该对象采用单例模式创建。SurfaceComposerClient 继承于RefBase类,在创建SurfaceComposerClient对象,系统第一次引用SurfaceComposerClient对象时,onFirstRef函数自动调用:
void SurfaceComposerClient::onFirstRef() { //得到SurfaceFlinger服务的代理对象 sp<ISurfaceComposer> sm(getComposerService()); if (sm != 0) { //为当前应用程序创建Client对象 sp<ISurfaceComposerClient> conn = sm->createConnection(); if (conn != 0) { mClient = conn; mStatus = NO_ERROR; } }}函数首先通过getComposerService()获取SurfaceFlinger的代理对象BpSurfaceComposer
static inline sp<ISurfaceComposer> getComposerService() { return ComposerService::getComposerService();}调用ComposerService类的getComposerService函数来获取SurfaceFlinger服务的代理对象
sp<ISurfaceComposer> ComposerService::getComposerService() { return ComposerService::getInstance().mComposerService;}通过调用getInstance函数以单例模式构造ComposerService对象,由于ComposerService类的成员变量mComposerService的类型为ISurfaceComposer,在构造ComposerService对象时,获得SurfaceFlinger服务的代理对象,并保存到ComposerService的成员变量mComposerService中,这里只是简单的返回ComposerService的成员变量mComposerService。
ComposerService::ComposerService(): Singleton<ComposerService>() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); } mServerCblkMemory = mComposerService->getCblk(); mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(mServerCblkMemory->getBase());}
SurfaceFlinger代理对象获取
通过调用函数getService来获取SurfaceFlinger服务的代理对象,并保持到成员变量mComposerService中template<typename INTERFACE>status_t getService(const String16& name, sp<INTERFACE>* outService){ const sp<IServiceManager> sm = defaultServiceManager(); if (sm != NULL) { *outService = interface_cast<INTERFACE>(sm->getService(name)); if ((*outService) != NULL) return NO_ERROR; } return NAME_NOT_FOUND;}关于应用程序请求ServiceManager查询服务过程请参考Android服务查询完整过程源码分析。从这里可以知道客户端进程是通过服务查询的方式来获取SurfaceFlinger服务的远程Binder代理对象。
匿名共享内存代理对象获取
在SurfaceFlinger服务启动过程中创建了一块匿名共享内存,这里通过上面获取的SurfaceFlinger代理对象BpSurfaceComposer请求SurfaceFlinger返回该匿名共享内存MemoryHeapBase的远程代理对象BpMemoryHeap,并保存到ComposerService的成员变量mServerCblkMemor中
应用程序请求过程:
frameworks\native\libs\gui\ISurfaceComposer.cpp
mServerCblkMemory = mComposerService->getCblk();virtual sp<IMemoryHeap> getCblk() const{ Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply); return interface_cast<IMemoryHeap>(reply.readStrongBinder());}服务端响应过程:
frameworks\native\libs\gui\ISurfaceComposer.cpp
status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch(code) { case GET_CBLK: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = getCblk()->asBinder(); reply->writeStrongBinder(b); } break; }}函数getCblk()实现在BnSurfaceComposer的子类SurfaceFlinger中。
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
sp<IMemoryHeap> SurfaceFlinger::getCblk() const{ return mServerHeap;}mServerHeap是在SurfaceFlinger启动过程中创建的一块匿名共享内存,用于保存系统显示屏幕信息,并共享给系统中的所有进程访问。关于mServerHeap的创建过程请参看Android SurfaceFlinger服务启动过程源码分析。得到该匿名共享内存的远程代理对象mServerHeap后,通过该代理对象向匿名共享内存的服务端获取匿名共享内存的基地址信息:mServerCblkMemory->getBase(),这部分内容在Android 匿名共享内存C++接口分析中有详细的介绍。
Client代理对象获取
得到了SurfaceFlinger服务的远程代理对象BpSurfaceComposer后,就可以通过该对象请求服务端的SurfaceFlinger为应用程序创建唯一的Client对象,Client对象用于代理当前应用程序向SurfaceFlinger发出的请求,每个应用程序在SurfaceFlinger中有且仅有一个Client对象。Client也是基于Android的Binder通信框架设计的,Client在Binder进程间通信框架下的类图如下:
sp<ISurfaceComposerClient> conn = sm->createConnection();
通过SurfaceFlinger的代理对象BpSurfaceComposer向SurfaceFlinger服务发起连接,在SurfaceFlinger服务端,创建Client对象,并返回代理对象BpSurfaceComposerClient给应用程序。
应用程序请求过程:
frameworks\native\libs\gui\ISurfaceComposer.cpp
virtual sp<ISurfaceComposerClient> createConnection(){ uint32_t n; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply); return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());}服务端响应过程:
frameworks\native\libs\gui\ISurfaceComposer.cpp
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 = createConnection()->asBinder(); reply->writeStrongBinder(b); } break; default: return BBinder::onTransact(code, data, reply, flags); } return NO_ERROR;}函数createConnection()在BnSurfaceComposer的子类SurfaceFlinger中实现
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection(){ sp<ISurfaceComposerClient> bclient; sp<Client> client(new Client(this)); status_t err = client->initCheck(); if (err == NO_ERROR) { bclient = client; } return bclient;}
SurfaceComposerClient获得Client的远程代理对象BpSurfaceComposerClient后,保存到其成员变量mClient中,当需要和SurfaceFlinger服务中的Client通信时,就通过保存在成员变量mClient中的BpSurfaceComposerClient来实现。关于Android应用程序,Client,SurfaceFlinger之间的关系如下图所示:
在SurfaceFlinger服务进程中为每一个应用程序进程创建了对应的Client对象,用于接收应用程序进程的RPC请求,但Client并不处理客户端发送过来的请求,而是转交给SurfaceFlinger来处理。SurfaceFlinger服务中的代理对象到此就介绍完了,应用程序在构造SurfaceComposerClient对象时,获得了SurfaceFlinger服务的远程代理对象BpSurfaceComposer,Client的远程代理对象BpSurfaceComposerClient及匿名共享内存MemoryHeapBase的远程代理对象BpMemoryHeap,他们与SurfaceFlinger的关系如下: