一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Android-IPC-Binder(1)

 mandrave 2012-01-06

本文以IAudioFlinger::setMode函數(shù)為例,展示Android IPC是如何工作的。AudioFlinger是Android多媒體服務(wù)器程序中一個(gè)服務(wù)。

Service Manager Run

service_manager為其他進(jìn)程提供了服務(wù)管理的服務(wù),必須在所有服務(wù)運(yùn)行之前啟動。

  1. // frameworks/base/cmds/servicemanager/service_manager.c   
  2. int main(int argc, char **argv)  
  3. {  
  4.   struct binder_state *bs;  
  5.   void *svcmgr = BINDER_SERVICE_MANAGER;  
  6.   bs = binder_open(128*1024);  
  7.   if (binder_become_context_manager(bs)) {  
  8.     LOGE("cannot become context manager (%s)/n", strerror(errno));     
  9.     return -1;  
  10.   }  
  11.   svcmgr_handle = svcmgr;  
  12.   binder_loop(bs, svcmgr_handler);  
  13.   return 0;  
  14. }  
 

它首先打開了/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ù)。

  1. // frameworks/base/cmds/servicemanager/binder.c   
  2. void binder_loop(struct binder_state *bs, binder_handler func)  
  3. {  
  4.   int res;  
  5.   struct binder_write_read bwr;  
  6.   unsigned readbuf[32];  
  7.   bwr.write_size = 0;  
  8.   bwr.write_consumed = 0;  
  9.   bwr.write_buffer = 0;  
  10.     
  11.   readbuf[0] = BC_ENTER_LOOPER;  
  12.   binder_write(bs, readbuf, sizeof(unsigned));  
  13.   for (;;) {  
  14.     bwr.read_size = sizeof(readbuf);  
  15.     bwr.read_consumed = 0;  
  16.     bwr.read_buffer = (unsigned) readbuf;  
  17.     res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);  
  18.     if (res < 0) {  
  19.       LOGE("binder_loop: ioctl failed (%s)/n", strerror(errno));  
  20.       break;  
  21.     }  
  22.     res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);  
  23.     if (res == 0) {  
  24.       LOGE("binder_loop: unexpected reply?!/n");  
  25.       break;  
  26.     }  
  27.     if (res < 0) {  
  28.       LOGE("binder_loop: io error %d %s/n", res, strerror(errno));  
  29.       break;  
  30.     }  
  31.   }  
  32. }  
 

注意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)。

  1. // frameworks/base/libs/binder/IServiceManager.cpp   
  2. sp<IServiceManager> defaultServiceManager()  
  3. {  
  4.   if (gDefaultServiceManager != NULL)   
  5. return gDefaultServiceManager;  
  6.   {  
  7.     AutoMutex _l(gDefaultServiceManagerLock);  
  8.     if (gDefaultServiceManager == NULL) {  
  9.       gDefaultServiceManager = interface_cast<IServiceManager>(  
  10.             ProcessState::self()->getContextObject(NULL));  
  11.     }  
  12.   }  
  13.     
  14.   return gDefaultServiceManager;  
  15. }  
 

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使用。

  1. // frameworks/base/libs/binder/ ProcessState.cpp   
  2. ProcessState::ProcessState()  
  3.     : mDriverFD(open_driver())  
 

現(xiàn)在,我們有了一個(gè)ProcessState實(shí)例,讓我們看看getContextObject()函數(shù)都做了什么。

  1. // frameworks/base/libs/binder/ProcessState.cpp   
  2. sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)  
  3. {  
  4.   if (supportsProcesses()) {  
  5.     return getStrongProxyForHandle(0);  
  6.   } else {  
  7.     return getContextObject(String16("default"), caller);  
  8.   }  
  9. }  
 

因?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)一步解釋。)

  1. // frameworks/base/libs/binder/ProcessState.cpp   
  2. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)  
  3. {  
  4.   sp<IBinder> result;  
  5.   AutoMutex _l(mLock);  
  6.   handle_entry* e = lookupHandleLocked(handle);  
  7.   if (e != NULL) {  
  8.     // We need to create a new BpBinder if there isn't currently one, OR we   
  9.     // are unable to acquire a weak reference on this current one.  See comment   
  10.     // in getWeakProxyForHandle() for more info about this.   
  11.     IBinder* b = e->binder;  
  12.     if (b == NULL || !e->refs->attemptIncWeak(this)) {  
  13.       b = new BpBinder(handle);   
  14.       e->binder = b;  
  15.       if (b) e->refs = b->getWeakRefs();  
  16.       result = b;  
  17.     } else {  
  18.       // This little bit of nastyness is to allow us to add a primary   
  19.       // reference to the remote proxy when this team doesn't have one   
  20.       // but another team is sending the handle to us.   
  21.       result.force_set(b);  
  22.       e->refs->decWeak(this);  
  23.     }  
  24.   }  
  25.   return result;  
  26. }  
 

在第一次調(diào)用時(shí),b為NULL,因此會先創(chuàng)建一個(gè)BpBinder實(shí)例。BpBinder is a base proxy class for remote binder object.

  1. // frameworks/base/libs/binder/BpBinder.cpp   
  2. BpBinder::BpBinder(int32_t handle)  
  3.     : mHandle(handle)  
  4.     , mAlive(1)  
  5.     , mObitsSent(0)  
  6.     , mObituaries(NULL)  
  7. {  
  8.   LOGV("Creating BpBinder %p handle %d/n"this, mHandle);  
  9.   extendObjectLifetime(OBJECT_LIFETIME_WEAK);  
  10.   IPCThreadState::self()->incWeakHandle(handle);  
  11. }  
 

IPCThreadState::incWeakHandle將會在輸出緩沖區(qū)(一個(gè)Parcel)中添加一個(gè)BC_INCREFS命令。

  1. // frameworks/base/libs/binder/IPCThreadState.cpp   
  2. void IPCThreadState::incWeakHandle(int32_t handle)  
  3. {  
  4.   LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)/n", handle);  
  5.   mOut.writeInt32(BC_INCREFS);  
  6.   mOut.writeInt32(handle);  
  7. }  
 

現(xiàn)在getContextObject回返回一個(gè)BpBinder實(shí)例,改BpBinder實(shí)例會通過interface_cast轉(zhuǎn)換為IserviceManager類型。interface_cast定義在IInterface.h頭文件中。定義如下:

  1. // frameworks/base/include/binder/IInterface.h   
  2. template<typename INTERFACE>  
  3. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
  4. {  
  5.   return INTERFACE::asInterface(obj);  
  6. }  
 

現(xiàn)在讓我們看一下IServiceManager的定義。

  1. // frameworks/base/include/binder/IServiceManager.h   
  2. class IServiceManager : public Iinterface  
  3. {  
  4. public:  
  5.   DECLARE_META_INTERFACE(ServiceManager);  
  6.   /** 
  7.    * Retrieve an existing service, blocking for a few seconds 
  8.    * if it doesn't yet exist. 
  9.    */  
  10.   virtual sp<IBinder>         getService( const String16& name) const = 0;  
  11.   /** 
  12.    * Retrieve an existing service, non-blocking. 
  13.    */  
  14.   virtual sp<IBinder>         checkService( const String16& name) const = 0;  
  15.   /** 
  16.    * Register a service. 
  17.    */  
  18.   virtual status_t            addService( const String16& name,  
  19.                                     const sp<IBinder>& service) = 0;  
  20.   /** 
  21.    * Return list of all existing services. 
  22.    */  
  23.   virtual Vector<String16>    listServices() = 0;  
  24.   enum {  
  25.         GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,  
  26.         CHECK_SERVICE_TRANSACTION,  
  27.         ADD_SERVICE_TRANSACTION,  
  28.         LIST_SERVICES_TRANSACTION,  
  29.   };  
  30. };  
 

DECLARE_META_INTERFACE宏在IInterface.h頭文件中定義如下:

  1. // frameworks/base/include/binder/IInterface.h   
  2. #define DECLARE_META_INTERFACE(INTERFACE)              /   
  3.   static const String16 descriptor;                                  /  
  4.   static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);      /  
  5.   virtual const String16& getInterfaceDescriptor() const;               /  
  6.   I##INTERFACE();                                            /  
  7.   virtual ~I##INTERFACE();  
 

DECLARE_META_INTERFACE宏聲明了兩個(gè)函數(shù),這兩個(gè)函數(shù)通過在IServiceManager.cpp文件中調(diào)用IMPLEMENT_META_INTERFACE宏來實(shí)現(xiàn)。

  1. // frameworks/base/libs/binder/IServiceManager.cpp   
  2. IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");  
 

IMPLEMENT_META_INTERFACE宏定義如下:

  1. // frameworks/base/include/binder/IInterface.h   
  2. #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)           /   
  3.   const String16 I##INTERFACE::descriptor(NAME);                      /  
  4.   const String16& I##INTERFACE::getInterfaceDescriptor() const {           /  
  5.       return I##INTERFACE::descriptor;                                /  
  6.   }                                                                /  
  7.   sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)   /  
  8.   {                                                                /  
  9.     sp<I##INTERFACE> intr;                                          /  
  10.     if (obj != NULL) {                                                /  
  11.       intr = static_cast<I##INTERFACE*>(                              /  
  12.            obj->queryLocalInterface(                                   /  
  13.                   I##INTERFACE::descriptor).get());                    /  
  14.       if (intr == NULL) {                                             /  
  15.         intr = new Bp##INTERFACE(obj);                              /  
  16.       }                                                            /  
  17.     }                                                              /  
  18.     return intr;                                                      /  
  19.   }                                                                /  
  20.   I##INTERFACE::I##INTERFACE() { }                                 /  
  21.   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類

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    少妇被粗大进猛进出处故事| 欧美乱视频一区二区三区| 日韩美成人免费在线视频| 亚洲最新中文字幕一区| 免费黄色一区二区三区| 福利新区一区二区人口| 91在线爽的少妇嗷嗷叫| 国产一级不卡视频在线观看| 91亚洲人人在字幕国产| 午夜传媒视频免费在线观看| 亚洲专区一区中文字幕| 国产永久免费高清在线精品| 国产精品白丝久久av| 日本不卡在线视频中文国产| 老司机精品一区二区三区| 亚洲精品一二三区不卡| 亚洲日本韩国一区二区三区| 欧美一区二区口爆吞精| 精品女同一区二区三区| 真实国产乱子伦对白视频不卡| 国产欧美一区二区另类精品| 深夜视频在线观看免费你懂| 国产亚洲系列91精品| 日韩三极片在线免费播放| 亚洲最新一区二区三区| 亚洲男女性生活免费视频| 国产高清一区二区不卡| 五月天丁香婷婷狠狠爱| 日本熟妇熟女久久综合| 欧美人妻少妇精品久久性色| 亚洲一区二区欧美在线| 久久综合日韩精品免费观看| 国产对白老熟女正在播放| 伊人网免费在线观看高清版| 日韩性生活片免费观看| 国产真人无遮挡免费视频一区| 亚洲综合色婷婷七月丁香| 亚洲中文字幕在线观看四区| 亚洲国产成人爱av在线播放下载| 亚洲国产成人精品一区刚刚| 俄罗斯胖女人性生活视频|