ServiceMananger是android中比较重要的一个进程,它是在init进程启动之后启动,从名字上就可以看出来它是用来管理系统中的service。比如:InputMethodService、ActivityManagerService等。在ServiceManager中有两个比较重要的方法:add_service、check_service。系统的service需要通过add_service把自己的信息注册到ServiceManager中,当需要使用时,通过check_service检查该service是否存在。

    主函数

    从它的主函数代码开始:

    [java] view plain copy
    1. intmain(intargc,char**argv)
    2. {
    3. structbinder_state*bs;
    4. void*svcmgr=BINDER_SERVICE_MANAGER;
    5. bs=binder_open(128*1024);
    6. if(binder_become_context_manager(bs)){
    7. LOGE("cannotbecomecontextmanager(%s)\n",strerror(errno));
    8. return-1;
    9. }
    10. svcmgr_handle=svcmgr;
    11. binder_loop(bs,svcmgr_handler);
    12. return0;
    13. }

    从main函数中可以看出,它主要做了三件事情:

  1. 打开/dev/binder设备,并在内存中映射128K的空间。
  2. 通知Binder设备,把自己变成context_manager
  3. 进入循环,不停的去读Binder设备,看是否有对service的请求,如果有的话,就去调用svcmgr_handler函数回调处理请求。

    服务注册

    再来看看ServiceManager中是怎么样去注册服务的。先来看先,当有对service的请求时,调用的回调函数svcmgr_handler:

    [java] view plain copy
    1. intsvcmgr_handler(structbinder_state*bs,
    2. structbinder_txn*txn,
    3. structbinder_io*msg,
    4. structbinder_io*reply)
    5. {
    6. structsvcinfo*si;
    7. uint16_t*s;
    8. unsignedlen;
    9. void*ptr;
    10. uint32_tstrict_policy;
    11. //LOGI("target=%pcode=%dpid=%duid=%d\n",
    12. //txn->target,txn->code,txn->sender_pid,txn->sender_euid);
    13. if(txn->target!=svcmgr_handle)
    14. return-1;
    15. //EquivalenttoParcel::enforceInterface(),readingtheRPC
    16. //headerwiththestrictmodepolicymaskandtheinterfacename.
    17. //Notethatweignorethestrict_policyanddon'tpropagateit
    18. //further(sincewedonooutboundRPCsanyway).
    19. strict_policy=bio_get_uint32(msg);
    20. s=bio_get_string16(msg,&len);
    21. if((len!=(sizeof(svcmgr_id)/2))||
    22. memcmp(svcmgr_id,s,sizeof(svcmgr_id))){
    23. fprintf(stderr,"invalidid%s\n",str8(s));
    24. return-1;
    25. }
    26. switch(txn->code){
    27. caseSVC_MGR_GET_SERVICE:
    28. caseSVC_MGR_CHECK_SERVICE:
    29. s=bio_get_string16(msg,&len);
    30. ptr=do_find_service(bs,s,len);
    31. if(!ptr)
    32. break;
    33. bio_put_ref(reply,ptr);
    34. return0;
    35. caseSVC_MGR_ADD_SERVICE:
    36. s=bio_get_string16(msg,&len);
    37. ptr=bio_get_ref(msg);
    38. if(do_add_service(bs,s,len,ptr,txn->sender_euid))
    39. return-1;
    40. break
    41. caseSVC_MGR_LIST_SERVICES:{
    42. unsignedn=bio_get_uint32(msg);
    43. si=svclist;
    44. while((n-->0)&&si)
    45. si=si->next;
    46. if(si){
    47. bio_put_string16(reply,si->name);
    48. return0;
    49. }
    50. return-1;
    51. }
    52. default:
    53. LOGE("unknowncode%d\n",txn->code);
    54. return-1;
    55. }
    56. bio_put_uint32(reply,0);
    57. return0;
    58. }

    在该回调函数中会判断Service有什么需要,如果是请求注册service,那么久执行:

    [java] view plain copy
    1. caseSVC_MGR_ADD_SERVICE:
    2. s=bio_get_string16(msg,&len);
    3. ptr=bio_get_ref(msg);
    4. if(do_add_service(bs,s,len,ptr,txn->sender_euid))
    5. return-1;
    6. break;

    我们再来看看do_add_service中做了什么事情:

    [java] view plain copy
    1. intdo_add_service(structbinder_state*bs,
    2. uint16_t*s,unsignedlen,
    3. void*ptr,unsigneduid)
    4. {
    5. structsvcinfo*si;
    6. //LOGI("add_service('%s',%p)uid=%d\n",str8(s),ptr,uid);
    7. if(!ptr||(len==0)||(len>127))
    8. return-1
    9. if(!svc_can_register(uid,s)){
    10. LOGE("add_service('%s',%p)uid=%d-PERMISSIONDENIED\n",
    11. str8(s),ptr,uid);
    12. return-1;
    13. }
    14. si=find_svc(s,len);
    15. if(si){
    16. if(si->ptr){
    17. LOGE("add_service('%s',%p)uid=%d-ALREADYREGISTERED\n",
    18. str8(s),ptr,uid);
    19. return-1;
    20. }
    21. si->ptr=ptr;
    22. }else{
    23. si=malloc(sizeof(*si)+(len+1)*sizeof(uint16_t));
    24. if(!si){
    25. LOGE("add_service('%s',%p)uid=%d-OUTOFMEMORY\n",
    26. str8(s),ptr,uid);
    27. return-1;
    28. }
    29. si->ptr=ptr;
    30. si->len=len;
    31. memcpy(si->name,s,(len+1)*sizeof(uint16_t));
    32. si->name[len]='\0';
    33. si->death.func=svcinfo_death;
    34. si->death.ptr=si;
    35. si->next=svclist;
    36. svclist=si;
    37. }
    38. binder_acquire(bs,ptr);
    39. binder_link_to_death(bs,ptr,&si->death);
    40. return0;
    41. }

    在该函数中,首先会去检查是否有权限注册service,如果没有权限就直接返回,不能注册。

    [java] view plain copy
    1. if(!svc_can_register(uid,s)){
    2. LOGE("add_service('%s',%p)uid=%d-PERMISSIONDENIED\n",
    3. str8(s),ptr,uid);
    4. return-1;
    5. }

    然后会去检查该service是否已经注册过了,如果已经注册过,那么就不能再注册了:

    [java] view plain copy
    1. si=find_svc(s,len);
    2. if(si){
    3. if(si->ptr){
    4. LOGE("add_service('%s',%p)uid=%d-ALREADYREGISTERED\n",
    5. str8(s),ptr,uid);
    6. return-1;
    7. }
    8. si->ptr=ptr;
    9. }

    再判断内存是否足够:

    [java] view plain copy
    1. si=malloc(sizeof(*si)+(len+1)*sizeof(uint16_t));
    2. if(!si){
    3. LOGE("add_service('%s',%p)uid=%d-OUTOFMEMORY\n",
    4. str8(s),ptr,uid);
    5. return-1;
    6. }

    如果都没什么问题,会注册该service,加入到svcList中来。注意,在ServiceManager中维护service信息的地方就是svclist。里面存了service的name和handler。

    服务获取

    通过以上几个步骤,service就算注册成功了。那么当要获得该service的时候又是怎么去处理的。还是来看下回调函数中的判断:

    [java] view plain copy
    1. caseSVC_MGR_CHECK_SERVICE:
    2. s=bio_get_string16(msg,&len);
    3. ptr=do_find_service(bs,s,len);
    4. if(!ptr)
    5. break;
    6. bio_put_ref(reply,ptr);
    7. return0

    如果是获取service,那么执行SVC_MGR_CHECK_SERVICE,并把返回的数据写入reply,返回给客户端。

    do_find_service函数中主要执行service的查找。

    [java] view plain copy
    1. void*do_find_service(structbinder_state*bs,uint16_t*s,unsignedlen)
    2. {
    3. structsvcinfo*si;
    4. si=find_svc(s,len);
    5. //LOGI("check_service('%s')ptr=%p\n",str8(s),si?si->ptr:0);
    6. if(si&&si->ptr){
    7. returnsi->ptr;
    8. }else{
    9. return0;
    10. }
    11. }

    这样在ServiceManager中就完成了服务的注册和查找。来看下ServiceManager的功能图:



更多相关文章

  1. Android(安卓)自定义View(二)函数分析
  2. android netd和kernel&frameworks的通信逻辑
  3. Android(安卓)使用Socket实现服务器与手机客户端的长连接四:使用
  4. android Java 提交数据到服务器的两种方式中四种方法
  5. android VelocityTracker类
  6. android中volley框架实现图片加载
  7. Android7.0 PhoneApp的启动
  8. android网格连接
  9. Android中Media Framework浅析(二)——MediaServer

随机推荐

  1. Android(安卓)学习笔记4---签名Android的
  2. Android调试工具adb的高逼格使用方式
  3. Android帧布局
  4. Android获取屏幕分辨率及DisplayMetrics
  5. Android(安卓)- This Handler class shou
  6. Android(安卓)Java包
  7. 提升基于英特尔®架构的 Android* 模拟器
  8. Android之Handler
  9. Kivy A to Z -- Kivycatalog例子无法在An
  10. android Handler