问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

android servicemanager 怎么实现service管理

发布网友 发布时间:2022-05-02 08:07

我来回答

1个回答

热心网友 时间:2023-10-13 01:47

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


  主函数(anrdroid4.0/frameworks/base/cmds/servicemanager/service_manager.c)


  从它的主函数代码开始:


  int main(int argc, char **argv)

  {

  struct binder_state *bs;

  void *svcmgr = BINDER_SERVICE_MANAGER;

  bs = binder_open(128*1024);

  if (binder_become_context_manager(bs)) {

  LOGE("cannot become context manager (%s)\n", strerror(errno));

  return -1;

  }

  svcmgr_handle = svcmgr;

  binder_loop(bs, svcmgr_handler);

  return 0;

  }

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


  打开/dev/binder设备,并在内存中映射128K的空间。

  通知Binder设备,把自己变成context_manager

  进入循环,不停的去读Binder设备,看是否有对service的请求,如果有的话,就去调用svcmgr_handler函数回调处理请求。

  服务注册


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


  int svcmgr_handler(struct binder_state *bs,

  struct binder_txn *txn,

  struct binder_io *msg,

  struct binder_io *reply)

  {

  struct svcinfo *si;

  uint16_t *s;

  unsigned len;

  void *ptr;

  uint32_t strict_policy;

  //  LOGI("target=%p code=%d pid=%d uid=%d\n",

  //  txn->target, txn->code, txn->sender_pid, txn->sender_euid);

  if (txn->target != svcmgr_handle)

  return -1;

  // Equivalent to Parcel::enforceInterface(), reading the RPC

  // header with the strict mode policy mask and the interface name.

  // Note that we ignore the strict_policy and don't propagate it

  // further (since we do no outbound RPCs anyway).

  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,"invalid id %s\n", str8(s));

  return -1;

  }

  switch(txn->code) {

  case SVC_MGR_GET_SERVICE:

  case SVC_MGR_CHECK_SERVICE:

  s = bio_get_string16(msg, &len);

  ptr = do_find_service(bs, s, len);

  if (!ptr)

  break;

  bio_put_ref(reply, ptr);

  return 0;

  case SVC_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;

  case SVC_MGR_LIST_SERVICES: {

  unsigned n = bio_get_uint32(msg);

  si = svclist;

  while ((n-- > 0) && si)

  si = si->next;

  if (si) {

  bio_put_string16(reply, si->name);

  return 0;

  }

  return -1;

  }

  default:

  LOGE("unknown code %d\n", txn->code);

  return -1;

  }

  bio_put_uint32(reply, 0);

  return 0;

  }

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


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


  int do_add_service(struct binder_state *bs,

  uint16_t *s, unsigned len,

  void *ptr, unsigned uid)

  {

  struct svcinfo *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 - PERMISSION DENIED\n",

  str8(s), ptr, uid);

  return -1;

  }

  si = find_svc(s, len);

  if (si) {

  if (si->ptr) {

  LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED\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 - OUT OF MEMORY\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);

  return 0;

  }

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


  if (!svc_can_register(uid, s)) {

  LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",

  str8(s), ptr, uid);

  return -1;

  }

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


  si = find_svc(s, len);

  if (si) {

  if (si->ptr) {

  LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED\n",

  str8(s), ptr, uid);

  return -1;

  }

  si->ptr = ptr;

  }

  再判断内存是否足够:


  si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));

  if (!si) {

  LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n",

  str8(s), ptr, uid);

  return -1;

  }

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


  服务获取


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


  case SVC_MGR_CHECK_SERVICE:

  s = bio_get_string16(msg, &len);

  ptr = do_find_service(bs, s, len);

  if (!ptr)

  break;

  bio_put_ref(reply, ptr);

  return 0;


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


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


  void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)

  {

  struct svcinfo *si;

  si = find_svc(s, len);

  //    LOGI("check_service('%s') ptr = %p\n", str8(s), si ? si->ptr : 0);

  if (si && si->ptr) {

  return si->ptr;

  } else {

  return 0;

  }

  }

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

转载

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
怎么样制作个人简历 上海海事大学对外交流多麽出国会不会容易一些 上海海事大学提前批今年要几号才能出来 怎么查找大学家长群 北京慧学堂在线教育学校的老师打电话来说要交3480元钱,给孩子半年的在... 左脸颊长青春痘是什么原因? 某商店上午9:00开始营业全天营业8小时下午几点关门 (2012?泗县模拟)某商店每天10:00-18:00营业,全天营业88小时. 某商店每天9:20-18:00营业,全天营业()小时。老师早上7:30到校,下午4... 商场营业时间是上午8:00-下午6:00,一位顾客向一位老先生嗯打听时间了... service manager是什么意思 service manager有什么作用 那些股票属于猪肉板块 笔记本电脑激活系统? 有跟中国传统文化有关的有声作品吗? 《赳赳说千字文》epub下载在线阅读全文,求百度网盘云资源 请问银耳那种的好?应该怎样挑选?银耳应该用冷水泡还是热水?泡开有*的能吃吗? 《三字经》是我国旧时的启蒙课本?? 想在线看常青藤爸爸《唱学三字经100讲》的百度云免费资源给个链接地址呗 哪里有朗读诗词,三字经,千字文,睡前故事能提供下载的网站 《浩然爸爸:千字文》MP3音频 百度网盘下载epub下载在线阅读全文,求百度网盘云资源 谁有谷建芬《千字文》的音频 跪求大神分享《浩然爸爸:千字文》MP3音频 免费百度网盘资源 360卫士体检提示有高危漏洞,修复失败,该怎么办? 我的360安全卫士一直都是修复失败怎么回事啊? 360安全卫士修复系统漏洞失败怎么办? 360修复失败怎么办 360的各种防护都开启不了了而且修复失败怎么办 360危险项目修复失败是怎么回事啊? 360提示系统漏洞修复失败怎么办 为什么电脑打开网页会跳出来servicemanager 如何在辅助管理服务器上启动 Service Manager 服务 耳膜破了有什么感觉.通常耳膜在什么情况下会破?拜托各位大神 Service Manager到底是什么? sql server service manager 是什么意思 怎样判别耳膜破损 如何把device/vendor目录下的service加入ServiceManager 耳膜破了是什么症状 manager和service的区别 如何解adobe cs6 service manager 已停止工作 耳膜破了有什么症状新旧伤 Adobe CS6 Service Manager是什么 为什么电子体温计开不了机? SQL Server Service Manager已停止工作。 sql server service manager的作用是什么? Microsoft SQL Server Service Manager是什么?起什么做用?为什么电脑工 ... 法人欠信用卡会冻结公司吗 CS6ServiceManager.exe怎么关闭 博朗4250耳温枪为什么开不了机了? 关于SQL server service manager的问题