考察内容:
看以下几个问题:
启动配置文件: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;
}
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;
}
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;
}
如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
}
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;
}
……
}
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;
}
……
}