本文以IAudioFlinger::setMode函數(shù)為例,展示Android IPC是如何工作的。AudioFlinger是Android多媒體服務(wù)器程序中一個(gè)服務(wù)。
Service Manager Run
service_manager為其他進(jìn)程提供了服務(wù)管理的服務(wù),必須在所有服務(wù)運(yùn)行之前啟動。
-
- 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驅(qū)動,然后調(diào)用binder_become_context_manager()函數(shù)(其本質(zhì)是調(diào)用ioctl設(shè)置BINDER_SET_CONTEXT_MGR)來通知binder內(nèi)核驅(qū)動它是管理者。然后,進(jìn)入循環(huán),等待其他進(jìn)程傳入的數(shù)據(jù)。
-
- 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注冊的handle。其他進(jìn)程必須使用它來與service_manager進(jìn)行對話。
Get IserviceManager
只能通過調(diào)用defaultServiceManager()函數(shù)來獲取一個(gè)IserviceManager實(shí)例。該函數(shù)在IServiceManager.cpp中實(shí)現(xiàn)。
-
- 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庫都會有該符號,它在一個(gè)進(jìn)程中唯一。起初gDefaultServiceManager為NULL,于是先調(diào)用ProcessState::self()獲取一個(gè)ProcessState實(shí)例。一個(gè)進(jìn)程只有一個(gè)ProcessState實(shí)例。該P(yáng)rocessState會打開/dev/binder驅(qū)動供IPCThreadState使用。
-
- ProcessState::ProcessState()
- : mDriverFD(open_driver())
現(xiàn)在,我們有了一個(gè)ProcessState實(shí)例,讓我們看看getContextObject()函數(shù)都做了什么。
-
- sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
- {
- if (supportsProcesses()) {
- return getStrongProxyForHandle(0);
- } else {
- return getContextObject(String16("default"), caller);
- }
- }
因?yàn)橹С謆inder驅(qū)動(supportsProcesses()函數(shù)會判斷binder驅(qū)動是否打開,以此來檢驗(yàn)是否支持binder),所以會執(zhí)行g(shù)etStrongProxyForHandle(0)。(Handle 0就是service manager,之前已經(jīng)提到過的BINDER_SERVICE_MANAGER,后面會進(jìn)一步解釋。)
-
- sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
- {
- sp<IBinder> result;
- AutoMutex _l(mLock);
- handle_entry* e = lookupHandleLocked(handle);
- if (e != NULL) {
-
-
-
- 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 {
-
-
-
- result.force_set(b);
- e->refs->decWeak(this);
- }
- }
- return result;
- }
在第一次調(diào)用時(shí),b為NULL,因此會先創(chuàng)建一個(gè)BpBinder實(shí)例。BpBinder is a base proxy class for remote binder object.
-
- BpBinder::BpBinder(int32_t handle)
- : mHandle(handle)
- , mAlive(1)
- , mObitsSent(0)
- , mObituaries(NULL)
- {
- LOGV("Creating BpBinder %p handle %d/n", this, mHandle);
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
- IPCThreadState::self()->incWeakHandle(handle);
- }
IPCThreadState::incWeakHandle將會在輸出緩沖區(qū)(一個(gè)Parcel)中添加一個(gè)BC_INCREFS命令。
-
- void IPCThreadState::incWeakHandle(int32_t handle)
- {
- LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)/n", handle);
- mOut.writeInt32(BC_INCREFS);
- mOut.writeInt32(handle);
- }
現(xiàn)在getContextObject回返回一個(gè)BpBinder實(shí)例,改BpBinder實(shí)例會通過interface_cast轉(zhuǎn)換為IserviceManager類型。interface_cast定義在IInterface.h頭文件中。定義如下:
-
- template<typename INTERFACE>
- inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
- {
- return INTERFACE::asInterface(obj);
- }
現(xiàn)在讓我們看一下IServiceManager的定義。
-
- class IServiceManager : public Iinterface
- {
- public:
- DECLARE_META_INTERFACE(ServiceManager);
-
-
-
-
- virtual sp<IBinder> getService( const String16& name) const = 0;
-
-
-
- virtual sp<IBinder> checkService( const String16& name) const = 0;
-
-
-
- virtual status_t addService( const String16& name,
- const sp<IBinder>& service) = 0;
-
-
-
- virtual Vector<String16> listServices() = 0;
- enum {
- GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
- CHECK_SERVICE_TRANSACTION,
- ADD_SERVICE_TRANSACTION,
- LIST_SERVICES_TRANSACTION,
- };
- };
DECLARE_META_INTERFACE宏在IInterface.h頭文件中定義如下:
-
- #define DECLARE_META_INTERFACE(INTERFACE) /
- static const String16 descriptor; /
- static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); /
- virtual const String16& getInterfaceDescriptor() const; /
- I##INTERFACE(); /
- virtual ~I##INTERFACE();
DECLARE_META_INTERFACE宏聲明了兩個(gè)函數(shù),這兩個(gè)函數(shù)通過在IServiceManager.cpp文件中調(diào)用IMPLEMENT_META_INTERFACE宏來實(shí)現(xiàn)。
-
- IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
IMPLEMENT_META_INTERFACE宏定義如下:
-
- #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) /
- const String16 I##INTERFACE::descriptor(NAME); /
- const String16& I##INTERFACE::getInterfaceDescriptor() const { /
- return I##INTERFACE::descriptor; /
- } /
- sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) /
- { /
- sp<I##INTERFACE> intr; /
- if (obj != NULL) { /
- intr = static_cast<I##INTERFACE*>( /
- obj->queryLocalInterface( /
- I##INTERFACE::descriptor).get()); /
- if (intr == NULL) { /
- intr = new Bp##INTERFACE(obj); /
- } /
- } /
- return intr; /
- } /
- I##INTERFACE::I##INTERFACE() { } /
- I##INTERFACE::~I##INTERFACE() { } /
IServiceManager::asInterface()函數(shù)最終會創(chuàng)建一個(gè)BpServiceManager實(shí)例,并將它返回給用戶。BpServiceManager是遠(yuǎn)程BnServiceManager的一個(gè)代理。任何針對IServiceManager的操作最終都會調(diào)用BpServiceManager中相應(yīng)虛函數(shù)。
小結(jié):
本節(jié)給出了如何獲取一個(gè)遠(yuǎn)程對象的代理對象。
假設(shè)你要實(shí)現(xiàn)你自己的服務(wù)IfunnyTest,你需要做以下工作:
- 將DECLARE_META_INTERFACE(FunnyTest)宏放進(jìn)interface的頭文件
- 將IMPLEMENT_META_INTERFACE(Funnytest, “your unique name”)宏放入interface的源文件
- 實(shí)現(xiàn)你自己的BpFunnyTest類