ServiceManager接收APP的跨进程Binder通信流程分析

现在一起来分析Server端接收(来自APP端)Binder数据的整个过程,还是以ServiceManager这个Server为例进行分析,这是一个至下而上的分析过程。

在分析之前先思考ServiceManager是什么?它其实是一个独立的进程,由init解析init.rc文件并由它创建,要早于zygote进程,ServiceManager的main函数进程文件位于:framework/native/cmds/servicemanager/main.cpp
这个main函数运行意味着系统的SM进程开始运行了。下面是ServiceManager在init.rc中的描述。

ServiceManager接收APP的跨进程Binder通信流程分析_第1张图片

下面是ServiceManager.rc文件

ServiceManager接收APP的跨进程Binder通信流程分析_第2张图片 

上面的rc文件描述说明servicemanager是一个系统的关键服务进程,不能重启的,因为 它一旦重启,将会restart如healthd,zygote, audioserver, surfaceflinger, inputflinger等一系列重要的其它进程。

下面先给出一个非常重要的结论,就是ServiceManager的父类继承关系,最顶层的父类是IServiceManager和BBinder,后面的源码分析的时候这个很有用,否则看不懂代码。

ServiceManager接收APP的跨进程Binder通信流程分析_第3张图片 

 

大家知道,每个android系统关键进程或app进程启动时会先创建binder,我们从SM的进程代码进行分析,如下:

main.cpp->main()
  -->char* driver="/dev/binder";
     //启动初始化binder驱动:普通app进程是通过ProcessState::self()->new ProcessState()来启动进程然后在构造函数中初始化binder,
     //与SM启动创建binder一样
       sp ps = ProcessState::initWithDriver(driver);
         -->return new ProcessState();//在构造函数中open_driver(driver);
       //实例化ServiceManager
       sp manager = new ServiceManager(std::make_unique(Access));
       
       //设置服务端的BBinder对象
       //所以manager就是一个BBinder对象:因为class ServiceManager: public os:BnServiceManager{}
       //而BnServiceManager继承关系是: class BnServiceManager: public ::android::BnInterface{ }
       //BnInterface的继承关系(位于Interface.h): class BnInterface: public BBinder{ }
       //综上,manager就是一个BBinder对象。
       //注意BnServerManager.h这个头文件是需要根据IServerManager.aidl文件自己去编译生成的(
       //可以使用AIDL命令去编译)
       IPCThreadState::self()->setTheContextObject(manager); 
         -->IPCThreadState.cpp->self():
               -->return new IPCThreadState(); //创建线程对象
            IPCThreadState.cpp->setTheContextObject(sp obj):
               -->the_context_object = obj;
       //设置成为binder驱动的context Manager,成为上下文的管理者,ps代表SM进程
       ps->becomeContextManager(nullptr, nullptr);

       //重点在下面:
       //通过Looper epoll机制处理binder事务
       sp looper = Looper::prepare(false);
       //设置callback
       BinderCallback::setupTo(looper);
         //向Binder驱动发送BC_ENTER_LOOPER事务请求,并获得binder设备的文件描述符
         //监听binder_fd文件描述符的数据变化
         -->IPCThreadState::self()->setupPolling(&binder_fd);
            looper->addFd(binder_fd, Looper::POLL_CALLBACK,
                          Looper::EVENT_INPUT, cb, nullptr);
            -->//当binder驱动发来消息后:调用下面的回调事件处理:
                int handleEvent(int fd int event){
                    //从binder驱动接收到消息并处理。
                    IPCThreadState::self()->handlePolledCommands();
                      -->do //当读 缓存中数据未消费完时,持续循环读
                         {
                             result = getAndExecuteCommand();
                               -->result = talkWithDriver();//从Binder驱动读入数据mIn
                               -->cmd = mIn.readInt32(); //从数据中读取BR响应码
                               -->executeCommand(cmd);
                                  -->case BR_TRANSACTION: //走这个分支
                                       //对SM来说,使用the_context_object这个BBinder对象
                                       //而transact应该在SM的父类中定义即BBinder
                                       -->the_context_object->transact(tr.code,buffer,&reply,tr.flags);
                                            -->BBinder.cpp->transact():
                                                //这里注意,下面调用的其实是子类的onTransact(即BnServiceManager.h中定义,但这只是一个头文件)
                                                //更进一步分析,其实是调用由IServiceManager.aidl生成的Bn端的cpp文件中(需要自己编译)
                                                --> onTransact();
                                                      -->IServiceManager.cpp->BnServiceManager::onTransact():
                                                            -->getService(); //其实是它的孩子即ServiceManager的接口
                                                                 -->ServiceManager.cpp->getService(name, sp * outBinder);
                                                                       //返回Binder
                                                                       *outBinder = tryGetService(name, true);
                                                                          -->std::map> mNameToService; //维持一张表
                                                                                --> auto it = mNameToService.find(name);
                                                                                    service = &(it->second); //取出Service;
                                                                                    out = service->binder;
                                                                                    return out;
                                                                          
                                                                       
                         }while(mIn.dataPosition() < mIn.dataSize());  
                         //当我们清空执行完所有的命令后,最后处理BR_DECREFS和BR_RELEASE
                         ProcessPendingDerefs();
                         FlushCommands();  
                            
                    
                }

上面分析的应该比较详细了,下面再总结下整体流程:

总结:

  1. binder驱动收到请求后, SM的looperCallBack回调会进行处理(BinderCallback- >handleEvent)
  2. 然后调用IPCThread::self()->handlePolledCommands()解读命令,向上分发
  3. the_context_object(注意这是一个BBinder对象)即BBinder->transact();
  4. 转交给BBinder的子类BnServiceManager.onTransact()处理,但这个是AIDL提供的代码,所以真正实现的是ServiceManager.getService();

最后再画一张图描述下整个过程:

ServiceManager接收APP的跨进程Binder通信流程分析_第4张图片

 

你可能感兴趣的:(Android系统,android,binder)