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

主函数

从它的主函数代码开始:

  1. int main(int argc, char **argv)
  2. {
  3. struct binder_state *bs;
  4. void *svcmgr = BINDER_SERVICE_MANAGER;
  5. bs = binder_open(128*1024);
  6. if (binder_become_context_manager(bs)) {
  7. LOGE("cannot become context manager (%s)\n", strerror(errno));
  8. return -1;
  9. }
  10. svcmgr_handle = svcmgr;
  11. binder_loop(bs, svcmgr_handler);
  12. return 0;
  13. }

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

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

服务注册

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

  1. int svcmgr_handler(struct binder_state *bs,
  2. struct binder_txn *txn,
  3. struct binder_io *msg,
  4. struct binder_io *reply)
  5. {
  6. struct svcinfo *si;
  7. uint16_t *s;
  8. unsigned len;
  9. void *ptr;
  10. uint32_t strict_policy;
  11. //  LOGI("target=%p code=%d pid=%d uid=%d\n",
  12. //  txn->target, txn->code, txn->sender_pid, txn->sender_euid);
  13. if (txn->target != svcmgr_handle)
  14. return -1;
  15. // Equivalent to Parcel::enforceInterface(), reading the RPC
  16. // header with the strict mode policy mask and the interface name.
  17. // Note that we ignore the strict_policy and don't propagate it
  18. // further (since we do no outbound RPCs anyway).
  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,"invalid id %s\n", str8(s));
  24. return -1;
  25. }
  26. switch(txn->code) {
  27. case SVC_MGR_GET_SERVICE:
  28. case SVC_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. return 0;
  35. case SVC_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. case SVC_MGR_LIST_SERVICES: {
  42. unsigned n = 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. return 0;
  49. }
  50. return -1;
  51. }
  52. default:
  53. LOGE("unknown code %d\n", txn->code);
  54. return -1;
  55. }
  56. bio_put_uint32(reply, 0);
  57. return 0;
  58. }

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

  1. case SVC_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中做了什么事情:

  1. int do_add_service(struct binder_state *bs,
  2. uint16_t *s, unsigned len,
  3. void *ptr, unsigned uid)
  4. {
  5. struct svcinfo *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 - PERMISSION DENIED\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 - ALREADY REGISTERED\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 - OUT OF MEMORY\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. return 0;
  41. }

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

  1. if (!svc_can_register(uid, s)) {
  2. LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
  3. str8(s), ptr, uid);
  4. return -1;
  5. }

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

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

再判断内存是否足够:

  1. si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
  2. if (!si) {
  3. LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n",
  4. str8(s), ptr, uid);
  5. return -1;
  6. }

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

服务获取

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

  1. case SVC_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. return 0;

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

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

  1. void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)
  2. {
  3. struct svcinfo *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. return si->ptr;
  8. } else {
  9. return 0;
  10. }
  11. }

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

Android 之 ServiceManager与服务管理的更多相关文章

  1. i.mx6 Android5.1.1 servicemanager本地服务

    接在之前的 i.mx6 Android5.1.1 初始化流程之init进程 i.mx6 Android5.1.1 初始化流程之init.rc解析 servicemanager是由init创建的本地服务 ...

  2. [译]:Xamarin.Android平台功能——位置服务

    返回索引目录 原文链接:Location Services. 译文链接:Xamarin.Android平台功能--位置服务 本部分介绍位置服务以及与如何使用位置提供商服务 Location Servi ...

  3. PC管理端与评委云打分配合步骤及疑难问题汇编,即如何使用PC管理端的云服务管理功能

    一.前期环境及数据准备 A.PC管理端主要流程 1.进入菜单 编辑/选项/服务器 界面,如下图所示,采用我官方所提供的云服务,不采用自己假设的AppWeb服务. 切记:AppWeb服务和云服务只能二选 ...

  4. Android开发-API指南-服务

    Service 英文原文:http://developer.android.com/guide/components/services.html 采集(更新)日期:2014-12-23 原博客:htt ...

  5. [置顶] Android开发之MediaPlayerService服务详解(一)

    前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...

  6. Android中使用HTTP服务

    在Android中,除了使用java.net包下的API访问HTTP服务之外,我们还可以换一种途径去完成工作.Android SDK附带了Apache的HttpClient API.Apache Ht ...

  7. wemall app商城源码中基于JAVA的Android异步加载图片管理器代码

    wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...

  8. [Android][Framework]裁剪SystemServer服务以及关闭SystemFeature

    本文链接 http://wossoneri.github.io/2018/08/30/[Android][Framework]crop-SystemServer-and-SystemFeature/ ...

  9. Android开发--用户定位服务--UserLocation

    Android开发--用户定位服务--UserLocation 2013-01-28 08:32:26     我来说两句      作者:BruceZhang 收藏    我要投稿 [java] & ...

随机推荐

  1. unlinking

    When a file name is deleted from the directory tree, the file name's connection to the inode number ...

  2. Mysql:输出到文件

    mysql>tee /home/a.txt mysql>show processlist; mysql>exit tee命令能重定向输出,同时屏幕会同步显示.

  3. [nginx] 网上最全面nginx教程(近100篇文章整理)

    转载:http://bbs.linuxtone.org/thread-25588-1-1.html Nginx基础 1.  nginx安装 2.  nginx 编译参数详解 3.  nginx安装配置 ...

  4. docker installation on ubuntu

    Ubuntu Docker is supported on these Ubuntu operating systems: Ubuntu Xenial 16.04 (LTS) Ubuntu Trust ...

  5. SQL中的左连接与右连接有什么区别,点解返回值会不同?(转)

    例子,相信你一看就明白,不需要多说 A表(a1,b1,c1) B表(a2,b2) a1 b1 c1 a2 b2 01 数学 95 01 张三 02 语文 90 02 李四 03 英语 80 04 王五 ...

  6. Cormen — The Best Friend Of a Man

    Cormen — The Best Friend Of a Man time limit per test 1 second memory limit per test 256 megabytes i ...

  7. UVALive 3027 并查集

    #include <cstdio> #include <queue> #include <cstring> #include <iostream> #i ...

  8. UIView回调方法(可以在添加子视图等,做一些额外操作)

    didAddSubview didMoveToSuperview willMoveToSuperview didMoveToWindow willMoveToWindow willRemoveSubv ...

  9. this的应用

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  10. ios 概况了解

    iOS的系统架构分为四个层次:( iOS是基于UNIX内核,android是基于Linux内核) 核心操作系统层(Core OS layer).核心服务层(Core Services layer).媒 ...