【Android话题-2.5系统服务】ServiceManager启动和工作原理是怎样的

考察内容:

  • ServiceManager的启动和工作原理

看以下几个问题:

  • ServiceManager启动流程是怎样的?
  • 怎么获取ServiceManager的binder对象
  • 怎么向ServiceManager添加服务?
  • 怎么从ServiceManager获取服务?

ServiceManager的启动

  • 启动进程
  • 启动Binder机制
  • 发布自己的服务
  • 等待并响应请求

启动配置文件:init.rc

service servicemenager /system/bin/servicemanager
  class core
  user system
  group system
  critical

入口函数:frameworks\native\cmds\servicemanager\service_manager.c::main

int main(int argc, char **argv){
  struct binder_state *bs;
  //打开binder驱动
  bs = binder_open(128*1024);
  //把自己注册成上下文管理者
  binder_become_context_manager(bs);
  //进入loop循环,等待并响应请求
  binder_loop(bs, svcmgr_handler);
  return 0;
}
  • 打开binder驱动:frameworks\native\cmds\servicemanager\binder.c::binder_open
struct binder_state *binder_open(size_t mapsize){
  struct binder_state *bs;
  bs = malloc(sizeof(*bs));
  //打开binder驱动
  bs->fd = open("/dev/binder", O_RDWR);
  bs->mapsize = mapsize;
  //用mmap把bs->fd映射到一块内存
  bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
  return bs;
}
  • 把自己注册成上下文管理者:
    frameworks\native\cmds\servicemanager\binder.c::binder_become_context_manager
int binder_become_context_manager(struct binder_state *bs){
  return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

这个函数的意思是:告诉binder驱动:管理者已经就绪了。

frameworks\native\cmds\servicemanager\binder.c::binder_become_context_manager

void binder_loop(struct binder_state *bs, binder_handler func){
  uint32_t readbuff[32];
  //告诉驱动:当前线程是处理binder请求的线程
  readbuff[0] = BC_ENTER_LOOPER;
  binder_write(bs, readbuff, sizeof(uint32_t));
  
  for(;;){
    bwr.read_size = sizeof(readbuf);
    bwr.read_buffer = (uintptr_t)readbuff;
    ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    binder_parse(bs, 0, (uintptr_t)readbuf, bwr.read_consumed, func);
  }
}

int binder_write(struct binder_state *bs, void *data, size_t len){
  struct binder_write_read bwr;
  bwr.write_size = len;
  bwr.write_consumed = 0;
  bwr.write_buffer = (uintptr_t)data;
  bwr.read_size = 0;
  res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
  return res;
}

如何获取ServiceManager?

如SurfaceFlinger的启动:
frameworks\native\services\surfaceflinger\main_surfaceflinger.cpp::main

int main(int, char**){
  sp<ProcessState> ps(ProcessState::self());
  ps->startThreadPool();

  sp<SuffaceFlinger> flinger = new SurfaceFlinger();
  flinger->init();

  sp<IServiceManager> sm(defaultServiceManager());
  //P1
  sm->addService(String16(SurfaceFlinger::getServiceManagerName()), flinger, false);

  flinger->run();
  return 0;
}

P1展开:
frameworks\native\libs\binder\IServiceManager.cpp::defaultServiceManager

sp<IServiceManager> defaultServiceManager()
{
  if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
  {
    AutoMutex _l(gDefaultServiceManagerLock);
    while (gDefaultServiceManager == NULL) {
      gDefaultServiceManager = interface_cast<IServiceManager>(
        //P2
        ProcessState::self()->getContextObject(NULL));
      if (gDefaultServiceManager == NULL)
        sleep(1);
    }
  }

  return gDefaultServiceManager;
}

P2展开:
frameworks\native\libs\binder\ProcessState.cpp::getContextObject

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
  handle_entry* e = lookupHandleLocked(handle);

  IBinder* b = e->binder;
  if(b == NULL){
    b = new BpBinder(handle);
    e->binder = b;
  }
  return b
}

怎么添加Service?

frameworks\native\libs\binder\IServiceManager.cpp::addService

status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated){
  ……
  status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
}

frameworks\native\libs\binder\BpBinder.cpp::transact

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
  //IPCThreadState是线程的单例,负责跟binder驱动交互
  IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
}

ServiceManager是怎么处理请求的:

int svcmgr_handler(struct binder_state *bs, struct binder_transaction_data *txn,...)
{
  switch(txn->code) {
    ……
    case SVC_MGR_ADD_SERVICE:
      ……
      do_add_service(bs, s, len, handle, ...)
      break;
  }
  ……
}

怎么获取Service?

frameworks\base\core\java\android\os\ServiceManager.java::getService

public static IBinder getService(String name){
  IBinder service = sCache.get(name);
  if(service != null){
    return service;
  }else{
    return getIServiceManager().getServcie(name);
  }
  return null;
}

ServiceManager是怎么处理请求的:
frameworks\native\cmds\servicemanager\service_manager.c

int svcmgr_handler(struct binder_state *bs, struct binder_transaction_data *txn,...)
{
  uint32_t handle
  switch(txn->code) {
    ……
    case SVC_MGR_GET_SERVICE:
      s = bio_get_string16(msg, &len);
      handle = do_find_service(bs, s, len, ...);
      bio_put_ref(reply, handle);
      return 0;
  }
  ……
}

总结

  • ServiceManager启动流程是怎样的?
    a)启动进程;
    b)启动binder机制(打开binder驱动,映射内存,注册binder线程);
    c)向binder驱动注册(成为管理者);
    d)进入loop循环(等待并处理请求)
  • 怎么获取ServiceManager的binder对象
    a)根据0号binder用了一个BpBinder
  • 怎么向ServiceManager添加服务?
    a)首先获取ServiceManager的binder对象;
    b)然后发起一个addService的binder调用;(参数:服务名称、binder服务对象)
  • 怎么从ServiceManager获取服务?
    a)首先获取ServiceManager的binder对象;
    b)然后发起一个getService的binder调用;(参数:服务名称)
发布了106 篇原创文章 · 获赞 27 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/menghaocheng/article/details/104330277