【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調用;(參數:服務名稱)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章