Android入门进阶教程(13)-ServiceManager服务管理详解
- intmain(intargc,char**argv)
- {
- structbinder_state*bs;
- void*svcmgr=BINDER_SERVICE_MANAGER;
- bs=binder_open(128*1024);
- if(binder_become_context_manager(bs)){
- LOGE("cannotbecomecontextmanager(%s)\n",strerror(errno));
- return-1;
- }
- svcmgr_handle=svcmgr;
- binder_loop(bs,svcmgr_handler);
- return0;
- }
- 打开/dev/binder设备,并在内存中映射128K的空间。
- 通知Binder设备,把自己变成context_manager
- 进入循环,不停的去读Binder设备,看是否有对service的请求,如果有的话,就去调用svcmgr_handler函数回调处理请求。
服务注册
再来看看ServiceManager中是怎么样去注册服务的。先来看先,当有对service的请求时,调用的回调函数svcmgr_handler:
[java] view plain copy- intsvcmgr_handler(structbinder_state*bs,
- structbinder_txn*txn,
- structbinder_io*msg,
- structbinder_io*reply)
- {
- structsvcinfo*si;
- uint16_t*s;
- unsignedlen;
- void*ptr;
- uint32_tstrict_policy;
- //LOGI("target=%pcode=%dpid=%duid=%d\n",
- //txn->target,txn->code,txn->sender_pid,txn->sender_euid);
- if(txn->target!=svcmgr_handle)
- return-1;
- //EquivalenttoParcel::enforceInterface(),readingtheRPC
- //headerwiththestrictmodepolicymaskandtheinterfacename.
- //Notethatweignorethestrict_policyanddon'tpropagateit
- //further(sincewedonooutboundRPCsanyway).
- strict_policy=bio_get_uint32(msg);
- s=bio_get_string16(msg,&len);
- if((len!=(sizeof(svcmgr_id)/2))||
- memcmp(svcmgr_id,s,sizeof(svcmgr_id))){
- fprintf(stderr,"invalidid%s\n",str8(s));
- return-1;
- }
- switch(txn->code){
- caseSVC_MGR_GET_SERVICE:
- caseSVC_MGR_CHECK_SERVICE:
- s=bio_get_string16(msg,&len);
- ptr=do_find_service(bs,s,len);
- if(!ptr)
- break;
- bio_put_ref(reply,ptr);
- return0;
- caseSVC_MGR_ADD_SERVICE:
- s=bio_get_string16(msg,&len);
- ptr=bio_get_ref(msg);
- if(do_add_service(bs,s,len,ptr,txn->sender_euid))
- return-1;
- break;
- caseSVC_MGR_LIST_SERVICES:{
- unsignedn=bio_get_uint32(msg);
- si=svclist;
- while((n-->0)&&si)
- si=si->next;
- if(si){
- bio_put_string16(reply,si->name);
- return0;
- }
- return-1;
- }
- default:
- LOGE("unknowncode%d\n",txn->code);
- return-1;
- }
- bio_put_uint32(reply,0);
- return0;
- }
在该回调函数中会判断Service有什么需要,如果是请求注册service,那么久执行:
[java] view plain copy
- caseSVC_MGR_ADD_SERVICE:
- s=bio_get_string16(msg,&len);
- ptr=bio_get_ref(msg);
- if(do_add_service(bs,s,len,ptr,txn->sender_euid))
- return-1;
- break;
我们再来看看do_add_service中做了什么事情:
[java] view plain copy- intdo_add_service(structbinder_state*bs,
- uint16_t*s,unsignedlen,
- void*ptr,unsigneduid)
- {
- structsvcinfo*si;
- //LOGI("add_service('%s',%p)uid=%d\n",str8(s),ptr,uid);
- if(!ptr||(len==0)||(len>127))
- return-1;
- if(!svc_can_register(uid,s)){
- LOGE("add_service('%s',%p)uid=%d-PERMISSIONDENIED\n",
- str8(s),ptr,uid);
- return-1;
- }
- si=find_svc(s,len);
- if(si){
- if(si->ptr){
- LOGE("add_service('%s',%p)uid=%d-ALREADYREGISTERED\n",
- str8(s),ptr,uid);
- return-1;
- }
- si->ptr=ptr;
- }else{
- si=malloc(sizeof(*si)+(len+1)*sizeof(uint16_t));
- if(!si){
- LOGE("add_service('%s',%p)uid=%d-OUTOFMEMORY\n",
- str8(s),ptr,uid);
- return-1;
- }
- si->ptr=ptr;
- si->len=len;
- memcpy(si->name,s,(len+1)*sizeof(uint16_t));
- si->name[len]='\0';
- si->death.func=svcinfo_death;
- si->death.ptr=si;
- si->next=svclist;
- svclist=si;
- }
- binder_acquire(bs,ptr);
- binder_link_to_death(bs,ptr,&si->death);
- return0;
- }
在该函数中,首先会去检查是否有权限注册service,如果没有权限就直接返回,不能注册。
[java] view plain copy
- if(!svc_can_register(uid,s)){
- LOGE("add_service('%s',%p)uid=%d-PERMISSIONDENIED\n",
- str8(s),ptr,uid);
- return-1;
- }
然后会去检查该service是否已经注册过了,如果已经注册过,那么就不能再注册了:
[java] view plain copy- si=find_svc(s,len);
- if(si){
- if(si->ptr){
- LOGE("add_service('%s',%p)uid=%d-ALREADYREGISTERED\n",
- str8(s),ptr,uid);
- return-1;
- }
- si->ptr=ptr;
- }
再判断内存是否足够:
[java] view plain copy- si=malloc(sizeof(*si)+(len+1)*sizeof(uint16_t));
- if(!si){
- LOGE("add_service('%s',%p)uid=%d-OUTOFMEMORY\n",
- str8(s),ptr,uid);
- return-1;
- }
如果都没什么问题,会注册该service,加入到svcList中来。注意,在ServiceManager中维护service信息的地方就是svclist。里面存了service的name和handler。
服务获取
通过以上几个步骤,service就算注册成功了。那么当要获得该service的时候又是怎么去处理的。还是来看下回调函数中的判断:
[java] view plain copy
- caseSVC_MGR_CHECK_SERVICE:
- s=bio_get_string16(msg,&len);
- ptr=do_find_service(bs,s,len);
- if(!ptr)
- break;
- bio_put_ref(reply,ptr);
- return0;
如果是获取service,那么执行SVC_MGR_CHECK_SERVICE,并把返回的数据写入reply,返回给客户端。
do_find_service函数中主要执行service的查找。
[java] view plain copy- void*do_find_service(structbinder_state*bs,uint16_t*s,unsignedlen)
- {
- structsvcinfo*si;
- si=find_svc(s,len);
- //LOGI("check_service('%s')ptr=%p\n",str8(s),si?si->ptr:0);
- if(si&&si->ptr){
- returnsi->ptr;
- }else{
- return0;
- }
- }
这样在ServiceManager中就完成了服务的注册和查找。来看下ServiceManager的功能图:
ServiceMananger是android中比较重要的一个进程,它是在init进程启动之后启动,从名字上就可以看出来它是用来管理系统中的service。比如:InputMethodService、ActivityManagerService等。在ServiceManager中有两个比较重要的方法:add_service、check_service。系统的service需要通过add_service把自己的信息注册到ServiceManager中,当需要使用时,通过check_service检查该service是否存在。
主函数
从它的主函数代码开始:
[java] view plain copy从main函数中可以看出,它主要做了三件事情:
更多相关文章
- Android(安卓)自定义View(二)函数分析
- android netd和kernel&frameworks的通信逻辑
- Android(安卓)使用Socket实现服务器与手机客户端的长连接四:使用
- android Java 提交数据到服务器的两种方式中四种方法
- android VelocityTracker类
- android中volley框架实现图片加载
- Android7.0 PhoneApp的启动
- android网格连接
- Android中Media Framework浅析(二)——MediaServer