考察內容:
- 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調用;(參數:服務名稱)