现在一起来分析Server端接收(来自APP端)Binder数据的整个过程,还是以ServiceManager这个Server为例进行分析,这是一个至下而上的分析过程。
在分析之前先思考ServiceManager是什么?它其实是一个独立的进程,由init解析init.rc文件并由它创建,要早于zygote进程,ServiceManager的main函数进程文件位于:framework/native/cmds/servicemanager/main.cpp
这个main函数运行意味着系统的SM进程开始运行了。下面是ServiceManager在init.rc中的描述。
下面是ServiceManager.rc文件
上面的rc文件描述说明servicemanager是一个系统的关键服务进程,不能重启的,因为 它一旦重启,将会restart如healthd,zygote, audioserver, surfaceflinger, inputflinger等一系列重要的其它进程。
下面先给出一个非常重要的结论,就是ServiceManager的父类继承关系,最顶层的父类是IServiceManager和BBinder,后面的源码分析的时候这个很有用,否则看不懂代码。
大家知道,每个android系统关键进程或app进程启动时会先创建binder,我们从SM的进程代码进行分析,如下:
main.cpp->main()
-->char* driver="/dev/binder";
//启动初始化binder驱动:普通app进程是通过ProcessState::self()->new ProcessState()来启动进程然后在构造函数中初始化binder,
//与SM启动创建binder一样
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
-->return new ProcessState();//在构造函数中open_driver(driver);
//实例化ServiceManager
sp<ServiceManager> manager = new ServiceManager(std::make_unique(Access));
//设置服务端的BBinder对象
//所以manager就是一个BBinder对象:因为class ServiceManager: public os:BnServiceManager{}
//而BnServiceManager继承关系是: class BnServiceManager: public ::android::BnInterface<IServiceManager>{ }
//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<BBinder> obj):
-->the_context_object = obj;
//设置成为binder驱动的context Manager,成为上下文的管理者,ps代表SM进程
ps->becomeContextManager(nullptr, nullptr);
//重点在下面:
//通过Looper epoll机制处理binder事务
sp<Looper> 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<IBinder> * outBinder);
//返回Binder
*outBinder = tryGetService(name, true);
-->std::map<string16, sp<IBinder>> 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();
}
上面分析的应该比较详细了,下面再总结下整体流程:
总结:
- binder驱动收到请求后, SM的looperCallBack回调会进行处理(BinderCallback- >handleEvent)
- 然后调用IPCThread::self()->handlePolledCommands()解读命令,向上分发
- the_context_object(注意这是一个BBinder对象)即BBinder->transact();
- 转交给BBinder的子类BnServiceManager.onTransact()处理,但这个是AIDL提供的代码,所以真正实现的是ServiceManager.getService();
最后再画一张图描述下整个过程: