我将用API IAudioFlinger:::setMode的调用过程来演示Android IPC的运作,AudioFinger 是程序media_server的一个Service.
(1)Service Manager 的启动(service_manager.c)
service_manager 为其它进程提供service管理,它必须在其他服务运行之前启动。
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;
}
首先打开设备"/dev/binder",然后调用 ioctl(BINDER_SET_CONTEXT_MGR,..)使binder内核驱动知道它是一个service manager,最后进入loop等待其他进程的数据。
void binder_loop(struct binder_state *bs, binder_handler func)
{
int res;
struct binder_write_read bwr;
unsigned readbuf[32];
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
readbuf[0] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(unsigned));
for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (unsigned) readbuf;
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
break;
}
res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
if (res == 0) {
LOGE("binder_loop: unexpected reply?!\n");
break;
}
if (res < 0) {
LOGE("binder_loop: io error %d %s\n", res, strerror(errno));
break;
}
}
}
注意宏定义 BINDER_SERVICE_MANAGER.
/* the one magic object */
#define BINDER_SERVICE_MANAGER ((void*) 0)
BINDER_SERVICE_MANAGER是service_manager的注册句柄,其它进程必须使用它与service_manager进行通信。
(2)获取 IServiceManager
获取 IServiceManager的唯一方法是调用defaultServiceManager(IServiceManager.cpp)
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
gDefaultServiceManager定义在libutil,所以任何包含libutil的程序或库都有它的定义,它在每个进程是唯一的,第一次调用的时候变量gDefaultServiceManager为空,所以它会首先通过ProcessState::self()得到一个ProcessState对象,一个进程也只有一个ProcessState对象,ProcessState会打开"/dev/binder"驱动供IPCThreadState使用。
ProcessState::ProcessState()
: mDriverFD(open_driver())
Now we have an instance of ProcessState, let’s look at the getContextObject.
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
if (supportsProcesses()) {
return getStrongProxyForHandle(0);
} else {
return getContextObject(String16("default"), caller);
}
}
如果支持ibinder驱动, 就会调用 getStrongProxyForHandle. (Handle为0是为 service manager保留的值, 稍后解释.)
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}