Android4.4深入浅出之SurfaceFlinger与Client通信框架(一)

来源:互联网 发布:恐怖电影推荐 知乎 编辑:程序博客网 时间:2024/04/29 08:20

SurfaceFlinger框架是基于Binder进程间通信机制搭建的,SF作为一个服务进程,用户程序想要跟它通信必然要经过Binder机制。首先说一下,用户要跟SF通信,那么SF必须出现在ServiceManager中,因为SF也是一个服务,所有的服务都由ServiceManager来进行统一管理。在系统启动的过程中,SF就在ServiceManager中注册好了,注册好之后,SF在后台中监视一些surface的变化从而做出处理。

             而启动之后,用户程序想操作一些跟surface有关的动作,就必须和SF进行交互。而这种交互是基于Binder进程间通信机制的。下面是一张图简单说明了SF的基本框架:

大体结构是这样,有些地方有些小错误用图形不能很好的表达。用文字来说明一下:
当应用程序需要请求SurfaceFlinger服务时,首先需要构造SurfaceComposerClient对象,通过SurfaceComposerClient对象就可以访问SurfaceFlinger服务了。基本的服务流程都是这么走的,我们看一下SurfaceComposerClient的构造函数:
 
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. SurfaceComposerClient::SurfaceComposerClient()  
  2.     : mStatus(NO_INIT), mComposer(Composer::getInstance())  
  3. {  
  4. }  
可想而知没做啥事啊,SurfaceComposerClient 继承于RefBase类,在创建SurfaceComposerClient对象,系统第一次引用SurfaceComposerClient对象时,onFirstRef函数自动调用,我们看一下它的onFirstRef
 
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void SurfaceComposerClient::onFirstRef() {  
  2.     sp<ISurfaceComposer> sm(ComposerService::getComposerService());  
  3.     if (sm != 0) {  
  4.         sp<ISurfaceComposerClient> conn = sm->createConnection();  
  5.         if (conn != 0) {  
  6.             mClient = conn;  
  7.             mStatus = NO_ERROR;  
  8.         }  
  9.     }  
  10. }  

上面代码,第二行的作用是获得SurfaceFlinger这个服务,我们跟踪一下:
 
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. sp<ISurfaceComposer> ComposerService::getComposerService() {  
  2.     ComposerService& instance = ComposerService::getInstance();  
  3.     Mutex::Autolock _l(instance.mLock);  
  4.     if (instance.mComposerService == NULL) {  
  5.         ComposerService::getInstance().connectLocked();  
  6.         assert(instance.mComposerService != NULL);  
  7.         ALOGD("ComposerService reconnected");  
  8.     }  
  9.     return instance.mComposerService;  
  10. }  
第二行得到了ComposerService的对象,是为了下一步访问它的成员变量mComposerService(ISurfaceComposer类的),跟踪到第五行的函数 connectLocked():
 
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void ComposerService::connectLocked() {  
  2.     const String16 name("SurfaceFlinger");  
  3.     while (getService(name, &mComposerService) != NO_ERROR) {  
  4.         usleep(250000);  
  5.     }  
  6.     assert(mComposerService != NULL);                                                                                                         //省略了一些东西。。。  
  7.    
  8.            }  

这里看到第三行getService(),第一个参数是“SurfaceFlinger”,第二个参数是mComposerService,记住它的类型的强引用的ISurfaceComposer,对就是这句得到了一个SurfaceFlinger服务的代理对象,看一下这个的函数的实体:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. template<typename INTERFACE>  
  2. status_t getService(const String16& name, sp<INTERFACE>* outService)  
  3. {  
  4.     const sp<IServiceManager> sm = defaultServiceManager();  
  5.     if (sm != NULL) {  
  6.         *outService = interface_cast<INTERFACE>(sm->getService(name));  
  7.         if ((*outService) != NULL) return NO_ERROR;  
  8.     }  
  9.     return NAME_NOT_FOUND;  
  10. }  
到第四行这里跟之前启动过程中SurfaceFlinger的创建一模一样了,最后outService会被强转化成BpSurfaceComposer类,BpSurfaceComposer就是SurfaceFlinger在客户端这边的Binder代理,与之对应的是BnSurfaceComposer相当于SurfaceFlinger这边与BpSurfaceComposer进行交互的一方。获得了代理之后,我们再回到之前的onFirstRef函数:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void SurfaceComposerClient::onFirstRef() {  
  2.     sp<ISurfaceComposer> sm(ComposerService::getComposerService());  
  3.     if (sm != 0) {  
  4.         sp<ISurfaceComposerClient> conn = sm->createConnection();  
  5.         if (conn != 0) {  
  6.             mClient = conn;  
  7.             mStatus = NO_ERROR;  
  8.         }  
  9.     }  
  10. }  

这时候走到if,sm有值了,所以往下走,看名字可以得出这是客户端在请求连接到SurfaceFlinger服务。我们跟踪一下createConnection:
 
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. virtual sp<ISurfaceComposerClient> createConnection()  
  2.     {  
  3.         uint32_t n;  
  4.         Parcel data, reply;  
  5.         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());  
  6.         remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);  
  7.         return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());  
  8.     }  

函数的大概意思是把一些连接信息写到数据包data里,然后通过transact这个函数传出去,remote()之前有研究过他是IBinder类的,这里重点看transact这个函数,他是IBinder类的成员函数故它的实现必定在BpBinder类里,我们跳到这个函数的实体:
 
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. status_t BpBinder::transact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     // Once a binder has died, it will never come back to life.  
  5.     if (mAlive) {  
  6.         status_t status = IPCThreadState::self()->transact(  
  7.             mHandle, code, data, reply, flags);  
  8.         if (status == DEAD_OBJECT) mAlive = 0;  
  9.         return status;  
  10.     }  
  11.   
  12.     return DEAD_OBJECT;  
  13. }  

发现他又调用了transact这个函数,不同的是 是在IPCThreadState类中的 我们继续跟踪:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. status_t IPCThreadState::transact(int32_t handle,  
  2.                                   uint32_t code, const Parcel& data,  
  3.                                   Parcel* reply, uint32_t flags)  
  4. {  
  5.     status_t err = data.errorCheck();  
  6.   
  7.     flags |= TF_ACCEPT_FDS;  
  8.   
  9.     IF_LOG_TRANSACTIONS() {  
  10.         TextOutput::Bundle _b(alog);  
  11.         alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "  
  12.             << handle << " / code " << TypeCode(code) << ": "  
  13.             << indent << data << dedent << endl;  
  14.     }  
  15.       
  16.     if (err == NO_ERROR) {  
  17.         LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),  
  18.             (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");  
  19.         err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);  
  20.     }  
  21.       
  22.     if (err != NO_ERROR) {  
  23.         if (reply) reply->setError(err);  
  24.         return (mLastError = err);  
  25.     }  
  26.       
  27.     if ((flags & TF_ONE_WAY) == 0) {  
  28.         #if 0  
  29.         if (code == 4) { // relayout  
  30.             ALOGI(">>>>>> CALLING transaction 4");  
  31.         } else {  
  32.             ALOGI(">>>>>> CALLING transaction %d", code);  
  33.         }  
  34.         #endif  
  35.         if (reply) {  
  36.             err = waitForResponse(reply);  
  37.         } else {  
  38.             Parcel fakeReply;  
  39.             err = waitForResponse(&fakeReply);  
  40.         }  
  41.         #if 0  
  42.         if (code == 4) { // relayout  
  43.             ALOGI("<<<<<< RETURNING transaction 4");  
  44.         } else {  
  45.             ALOGI("<<<<<< RETURNING transaction %d", code);  
  46.         }  
  47.         #endif  
  48.           
  49.         IF_LOG_TRANSACTIONS() {  
  50.             TextOutput::Bundle _b(alog);  
  51.             alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "  
  52.                 << handle << ": ";  
  53.             if (reply) alog << indent << *reply << dedent << endl;  
  54.             else alog << "(none requested)" << endl;  
  55.         }  
  56.     } else {  
  57.         err = waitForResponse(NULL, NULL);  
  58.     }  
  59.       
  60.     return err;  
  61. }  

这里已经扯到Binder机制的基本原理了,简单说就是客户端的SF代理通过BpBinder跟/dev/binder设备进行交互,向binder里写东西,函数err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);就是实现了这个功能,写完后他又等待服务端(SurfaceFlinger)那端的回应,err = waitForResponse(reply);当然服务端那边同样有人跟他进行交互。到这里,如果服务端收到消息并且返回了一个消息给客户端,这说明客户端请求连接成功。

     请求成功后conn就不为0了,回到onFirstRef,成功后把coon赋给mClient。

既然客户端有请求了,那么服务端肯定有东西会去留意这个消息,回到更以前,做出向服务端请求连接这件事其实是SurfaceFlinger在客户端这边的代理BpSurfaceComposer完成的,那么之前说过,与之对应的就是BnSurfaceComposer。我们看一下他类的定义:

 

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {  
  2. public:  
  3.     enum {  
  4.         // Note: BOOT_FINISHED must remain this value, it is called from  
  5.         // Java by ActivityManagerService.  
  6.         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,  
  7.         CREATE_CONNECTION,  
  8.         CREATE_GRAPHIC_BUFFER_ALLOC,  
  9.         CREATE_DISPLAY_EVENT_CONNECTION,  
  10.         CREATE_DISPLAY,  
  11.         DESTROY_DISPLAY,  
  12.         GET_BUILT_IN_DISPLAY,  
  13.         SET_TRANSACTION_STATE,  
  14.         AUTHENTICATE_SURFACE,  
  15.         BLANK,  
  16.         UNBLANK,  
  17.         GET_DISPLAY_INFO,  
  18.         CONNECT_DISPLAY,  
  19.         CAPTURE_SCREEN,  
  20.     };  
  21.   
  22.     virtual status_t onTransact(uint32_t code, const Parcel& data,  
  23.             Parcel* reply, uint32_t flags = 0);  
  24.  }  

发现他没有构造函数只有一个成员函数 onTransact。跟踪一下:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. status_t BnSurfaceComposer::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     switch(code) {  
  5.         case CREATE_CONNECTION: {  
  6.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  7.             sp<IBinder> b = createConnection()->asBinder();  
  8.             reply->writeStrongBinder(b);  
  9.             return NO_ERROR;  
  10.         }  
  11.         case CREATE_GRAPHIC_BUFFER_ALLOC: {  
  12.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  13.             sp<IBinder> b = createGraphicBufferAlloc()->asBinder();  
  14.             reply->writeStrongBinder(b);  
  15.             return NO_ERROR;  
  16.         }  
  17.         case SET_TRANSACTION_STATE: {  
  18.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  19.             size_t count = data.readInt32();  
  20.             ComposerState s;  
  21.             Vector<ComposerState> state;  
  22.             state.setCapacity(count);  
  23.             for (size_t i=0 ; i<count ; i++) {  
  24.                 s.read(data);  
  25.                 state.add(s);  
  26.             }  
  27.             count = data.readInt32();  
  28.             DisplayState d;  
  29.             Vector<DisplayState> displays;  
  30.             displays.setCapacity(count);  
  31.             for (size_t i=0 ; i<count ; i++) {  
  32.                 d.read(data);  
  33.                 displays.add(d);  
  34.             }  
  35.             uint32_t flags = data.readInt32();  
  36.             setTransactionState(state, displays, flags);  
  37.             return NO_ERROR;  
  38.         }  
  39.         case BOOT_FINISHED: {  
  40.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  41.             bootFinished();  
  42.             return NO_ERROR;  
  43.         }  
  44.         case CAPTURE_SCREEN: {  
  45.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  46.             sp<IBinder> display = data.readStrongBinder();  
  47.             sp<IGraphicBufferProducer> producer =  
  48.                     interface_cast<IGraphicBufferProducer>(data.readStrongBinder());  
  49.             uint32_t reqWidth = data.readInt32();  
  50.             uint32_t reqHeight = data.readInt32();  
  51.             uint32_t minLayerZ = data.readInt32();  
  52.             uint32_t maxLayerZ = data.readInt32();  
  53.             status_t res = captureScreen(display, producer,  
  54.                     reqWidth, reqHeight, minLayerZ, maxLayerZ);  
  55.             reply->writeInt32(res);  
  56.             return NO_ERROR;  
  57.         }  
  58.         case AUTHENTICATE_SURFACE: {  
  59.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  60.             sp<IGraphicBufferProducer> bufferProducer =  
  61.                     interface_cast<IGraphicBufferProducer>(data.readStrongBinder());  
  62.             int32_t result = authenticateSurfaceTexture(bufferProducer) ? 1 : 0;  
  63.             reply->writeInt32(result);  
  64.             return NO_ERROR;  
  65.         }  
  66.         case CREATE_DISPLAY_EVENT_CONNECTION: {  
  67.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  68.             sp<IDisplayEventConnection> connection(createDisplayEventConnection());  
  69.             reply->writeStrongBinder(connection->asBinder());  
  70.             return NO_ERROR;  
  71.         }  
  72.         case CREATE_DISPLAY: {  
  73.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  74.             String8 displayName = data.readString8();  
  75.             bool secure = bool(data.readInt32());  
  76.             sp<IBinder> display(createDisplay(displayName, secure));  
  77.             reply->writeStrongBinder(display);  
  78.             return NO_ERROR;  
  79.         }  
  80.         case DESTROY_DISPLAY: {  
  81.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  82.             sp<IBinder> display = data.readStrongBinder();  
  83.             destroyDisplay(display);  
  84.             return NO_ERROR;  
  85.         }  
  86.         case GET_BUILT_IN_DISPLAY: {  
  87.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  88.             int32_t id = data.readInt32();  
  89.             sp<IBinder> display(getBuiltInDisplay(id));  
  90.             reply->writeStrongBinder(display);  
  91.             return NO_ERROR;  
  92.         }  
  93.         case BLANK: {  
  94.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  95.             sp<IBinder> display = data.readStrongBinder();  
  96.             blank(display);  
  97.             return NO_ERROR;  
  98.         }  
  99.         case UNBLANK: {  
  100.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  101.             sp<IBinder> display = data.readStrongBinder();  
  102.             unblank(display);  
  103.             return NO_ERROR;  
  104.         }  
  105.         case GET_DISPLAY_INFO: {  
  106.             CHECK_INTERFACE(ISurfaceComposer, data, reply);  
  107.             DisplayInfo info;  
  108.             sp<IBinder> display = data.readStrongBinder();  
  109.             status_t result = getDisplayInfo(display, &info);  
  110.             memcpy(reply->writeInplace(sizeof(DisplayInfo)), &info, sizeof(DisplayInfo));  
  111.             reply->writeInt32(result);  
  112.             return NO_ERROR;  
  113.         }  
  114.         default: {  
  115.             return BBinder::onTransact(code, data, reply, flags);  
  116.         }  
  117.     }  
  118.     // should be unreachable  
  119.     return NO_ERROR;  
  120. }  

代码虽然有点长,但是整体框架就是一个swith语句,看到第一个分支,马上就能看出来这是一个对请求连接信号的处理,这里大概能知道这个onTransact的功能就是判断收到的消息即参数code是哪种类型从而做出相应的处理。在server测,一开始创建SF服务的时候,在线城池创建的时候就已经开启线程去监听binder设备了我们来跟踪下:

 从最开始SF服务启动的源文件开始:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int main(int argc, char** argv) {  
  2.     // When SF is launched in its own process, limit the number of  
  3.     // binder threads to 4.  
  4.     ProcessState::self()->setThreadPoolMaxThreadCount(4);  
  5.   
  6.     // start the thread pool  
  7.     sp<ProcessState> ps(ProcessState::self());  
  8.     ps->startThreadPool();  

是一个片段,最后一句就是开始线程池。跟踪其代码:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void ProcessState::startThreadPool()  
  2. {  
  3.     AutoMutex _l(mLock);  
  4.     if (!mThreadPoolStarted) {  
  5.         mThreadPoolStarted = true;  
  6.         spawnPooledThread(true);  
  7.     }  
  8. }  

核心也在最后一句,

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void ProcessState::spawnPooledThread(bool isMain)  
  2. {  
  3.     if (mThreadPoolStarted) {  
  4.         String8 name = makeBinderThreadName();  
  5.         ALOGV("Spawning new pooled thread, name=%s\n", name.string());  
  6.         sp<Thread> t = new PoolThread(isMain);  
  7.         t->run(name.string());  
  8.     }  
  9. }  


到这里,可以看到实质的线程创建和开始运行。接下来我用一张图来表示他的函数调用的走向:

这里一旦检测到有连接请求消息就会跳到executeCommand的switch分支BR_TRANSACTION,去执行BBinder的transact,transact函数会调用onTransact函数,这个onTransact由其子类实现,在这里由BnSurfaceComposer完成,即调用的是BnSurfaceComposer::onTransact(),函数的具体内容在上面已贴出,就是处理不同的请求。

     到此为止,客户端已经与SF进行连接,也就是交手过了,那么自然连接了,一定要做些事情比如客户端请求渲染一个surface,或者等等其他的。接下去的工作就是SurfaceFlinger的事,对客户端不同的请求而进行不同的处理,这才是SF核心工作所在。当然所有的通信机制都是基于binder机制,而求也有负责这个方面的客户端这边的binder代理BpSurfaceComposerClient和服务端这边的本地对象 BnSurfaceComposerClient,而这里有点不一样的是BnSurfaceComposerClient派生出Client所以事情都交与Client做了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

0 0
原创粉丝点击