天天看點

淺談Android系統程序間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路

在前面一篇文章 淺談Service Manager成為Android程序間通信(IPC)機制Binder守護程序之路中,介紹了Service Manager是如何成為Binder機制的守護程序的。既然作為守護程序,Service Manager的職責當然就是為Server和Client服務了。那麼,Server和Client如何獲得Service Manager接口,進而享受它提供的服務呢?本文将簡要分析Server和Client獲得Service Manager的過程。

        在閱讀本文之前,希望讀者先閱讀Android程序間通信(IPC)機制Binder簡要介紹和學習計劃一文提到的參考資料Android深入淺出之Binder機制,這樣可以加深對本文的了解。

        我們知道,Service Manager在Binder機制中既充當守護程序的角色,同時它也充當着Server角色,然而它又與一般的Server不一樣。對于普通的Server來說,Client如果想要獲得Server的遠端接口,那麼必須通過Service Manager遠端接口提供的getService接口來獲得,這本身就是一個使用Binder機制來進行程序間通信的過程。而對于Service Manager這個Server來說,Client如果想要獲得Service Manager遠端接口,卻不必通過程序間通信機制來獲得,因為Service Manager遠端接口是一個特殊的Binder引用,它的引用句柄一定是0。

        擷取Service Manager遠端接口的函數是defaultServiceManager,這個函數聲明在frameworks/base/include/binder/IServiceManager.h檔案中:

[cpp] view plain copy print ?

  1. sp<IServiceManager> defaultServiceManager();  

sp<IServiceManager> defaultServiceManager();

       實作在frameworks/base/libs/binder/IServiceManager.cpp檔案中:

[cpp] view plain copy print ?

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

sp<IServiceManager> defaultServiceManager()

{

if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

{

AutoMutex _l(gDefaultServiceManagerLock);

if (gDefaultServiceManager == NULL) {

gDefaultServiceManager = interface_cast<IServiceManager>(

ProcessState::self()->getContextObject(NULL));

}

}

return gDefaultServiceManager;

}        gDefaultServiceManagerLock和gDefaultServiceManager是全局變量,定義在frameworks/base/libs/binder/Static.cpp檔案中:

[cpp] view plain copy print ?

  1. Mutex gDefaultServiceManagerLock;  
  2. sp<IServiceManager> gDefaultServiceManager;  

Mutex gDefaultServiceManagerLock;

sp<IServiceManager> gDefaultServiceManager;        從這個函數可以看出,gDefaultServiceManager是單例模式,調用defaultServiceManager函數時,如果gDefaultServiceManager已經建立,則直接傳回,否則通過interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))來建立一個,并儲存在gDefaultServiceManager全局變量中。

       在繼續介紹interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))的實作之前,先來看一個類圖,這能夠幫助我們了解Service Manager遠端接口的建立過程。

淺談Android系統程式間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路

        參考資料Android深入淺出之Binder機制一文的讀者,應該會比較容易了解這個圖。這個圖表明了,BpServiceManager類繼承了BpInterface<IServiceManager>類,BpInterface是一個模闆類,它定義在frameworks/base/include/binder/IInterface.h檔案中:

[cpp] view plain copy print ?

  1. template<typename INTERFACE>  
  2. class BpInterface : public INTERFACE, public BpRefBase  
  3. {  
  4. public:  
  5.     BpInterface(const sp<IBinder>& remote);  
  6. protected:  
  7.     virtual IBinder* onAsBinder();  
  8. };  

template<typename INTERFACE>

class BpInterface : public INTERFACE, public BpRefBase

{

public:

BpInterface(const sp<IBinder>& remote);

protected:

virtual IBinder* onAsBinder();

};        IServiceManager類繼承了IInterface類,而IInterface類和BpRefBase類又分别繼承了RefBase類。在BpRefBase類中,有一個成員變量mRemote,它的類型是IBinder*,實作類為BpBinder,它表示一個Binder引用,引用句柄值儲存在BpBinder類的mHandle成員變量中。BpBinder類通過IPCThreadState類來和Binder驅動程式并互,而IPCThreadState又通過它的成員變量mProcess來打開/dev/binder裝置檔案,mProcess成員變量的類型為ProcessState。ProcessState類打開裝置/dev/binder之後,将打開檔案描述符儲存在mDriverFD成員變量中,以供後續使用。

        了解了這些概念之後,就可以繼續分析建立Service Manager遠端接口的過程了,最終目的是要建立一個BpServiceManager執行個體,并且傳回它的IServiceManager接口。建立Service Manager遠端接口主要是下面語句:

[cpp] view plain copy print ?

  1. gDefaultServiceManager = interface_cast<IServiceManager>(  
  2.     ProcessState::self()->getContextObject(NULL));  

gDefaultServiceManager = interface_cast<IServiceManager>(

ProcessState::self()->getContextObject(NULL));        看起來簡短,卻暗藏玄機,具體可閱讀 Android深入淺出之Binder機制這篇參考資料,這裡作簡要描述。

        首先是調用ProcessState::self函數,self函數是ProcessState的靜态成員函數,它的作用是傳回一個全局唯一的ProcessState執行個體變量,就是單例模式了,這個變量名為gProcess。如果gProcess尚未建立,就會執行建立操作,在ProcessState的構造函數中,會通過open檔案操作函數打開裝置檔案/dev/binder,并且傳回來的裝置檔案描述符儲存在成員變量mDriverFD中。

        接着調用gProcess->getContextObject函數來獲得一個句柄值為0的Binder引用,即BpBinder了,于是建立Service Manager遠端接口的語句可以簡化為:

[cpp] view plain copy print ?

  1. gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));  

gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));        再來看函數interface_cast<IServiceManager>的實作,它是一個模闆函數,定義在framework/base/include/binder/IInterface.h檔案中:

[cpp] view plain copy print ?

  1. template<typename INTERFACE>  
  2. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
  3. {  
  4.     return INTERFACE::asInterface(obj);  
  5. }  

template<typename INTERFACE>

inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)

{

return INTERFACE::asInterface(obj);

}        這裡的INTERFACE是IServiceManager,于是調用了IServiceManager::asInterface函數。IServiceManager::asInterface是通過DECLARE_META_INTERFACE(ServiceManager)宏在IServiceManager類中聲明的,它位于framework/base/include/binder/IServiceManager.h檔案中:

[cpp] view plain copy print ?

  1. DECLARE_META_INTERFACE(ServiceManager);  

DECLARE_META_INTERFACE(ServiceManager);

        展開即為:

[cpp] view plain copy print ?

  1. #define DECLARE_META_INTERFACE(ServiceManager)                              \   
  2.     static const android::String16 descriptor;                          \  
  3.     static android::sp<IServiceManager> asInterface(                    \  
  4.     const android::sp<android::IBinder>& obj);                          \  
  5.     virtual const android::String16& getInterfaceDescriptor() const;    \  
  6.     IServiceManager();                                                  \  
  7.     virtual ~IServiceManager();                                           

#define DECLARE_META_INTERFACE(ServiceManager) \

static const android::String16 descriptor; \

static android::sp<IServiceManager> asInterface( \

const android::sp<android::IBinder>& obj); \

virtual const android::String16& getInterfaceDescriptor() const; \

IServiceManager(); \

virtual ~IServiceManager();

       IServiceManager::asInterface的實作是通過IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")宏定義的,它位于framework/base/libs/binder/IServiceManager.cpp檔案中:

[cpp] view plain copy print ?

  1. IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");  

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");       展開即為:

[cpp] view plain copy print ?

  1. #define IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")                 \   
  2.     const android::String16 IServiceManager::descriptor("android.os.IServiceManager");     \  
  3.     const android::String16&                                   \  
  4.     IServiceManager::getInterfaceDescriptor() const {                                      \  
  5.     return IServiceManager::descriptor;                                                    \  
  6.     }                                                                                      \  
  7.     android::sp<IServiceManager> IServiceManager::asInterface(                             \  
  8.     const android::sp<android::IBinder>& obj)                                              \  
  9.     {                                                                                      \  
  10.     android::sp<IServiceManager> intr;                                                     \  
  11.     if (obj != NULL) {                                                                     \  
  12.     intr = static_cast<IServiceManager*>(                                                  \  
  13.     obj->queryLocalInterface(                                                              \  
  14.     IServiceManager::descriptor).get());                                                   \  
  15.     if (intr == NULL) {                                                                    \  
  16.     intr = new BpServiceManager(obj);                                                      \  
  17.     }                                                                                      \  
  18.     }                                                                                      \  
  19.     return intr;                                                                           \  
  20.     }                                                                                      \  
  21.     IServiceManager::IServiceManager() { }                                                 \  
  22.     IServiceManager::~IServiceManager() { }        

#define IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager") \

const android::String16 IServiceManager::descriptor("android.os.IServiceManager"); \

const android::String16& \

IServiceManager::getInterfaceDescriptor() const { \

return IServiceManager::descriptor; \

} \

android::sp<IServiceManager> IServiceManager::asInterface( \

const android::sp<android::IBinder>& obj) \

{ \

android::sp<IServiceManager> intr; \

if (obj != NULL) { \

intr = static_cast<IServiceManager*>( \

obj->queryLocalInterface( \

IServiceManager::descriptor).get()); \

if (intr == NULL) { \

intr = new BpServiceManager(obj); \

} \

} \

return intr; \

} \

IServiceManager::IServiceManager() { } \

IServiceManager::~IServiceManager() { }          估計寫這段代碼的員工是從Microsoft跳槽到Google的。這裡我們關注IServiceManager::asInterface的實作:

[cpp] view plain copy print ?

  1. android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)                                                
  2. {                                                                                       
  3.     android::sp<IServiceManager> intr;                                                      
  4.     if (obj != NULL) {                                                                       
  5.         intr = static_cast<IServiceManager*>(                                                    
  6.                     obj->queryLocalInterface(IServiceManager::descriptor).get());  
  7.         if (intr == NULL) {                  
  8.             intr = new BpServiceManager(obj);                                          
  9.         }                                            
  10.     }  
  11.     return intr;                                    
  12. }     

android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)

{

android::sp<IServiceManager> intr;

if (obj != NULL) {

intr = static_cast<IServiceManager*>(

obj->queryLocalInterface(IServiceManager::descriptor).get());

if (intr == NULL) {

intr = new BpServiceManager(obj);

}

return intr;

}          這裡傳進來的參數obj就則剛才建立的new BpBinder(0)了,BpBinder類中的成員函數queryLocalInterface繼承自基類IBinder,IBinder::queryLocalInterface函數位于framework/base/libs/binder/Binder.cpp檔案中:

[cpp] view plain copy print ?

  1. sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)  
  2. {  
  3.     return NULL;  
  4. }  

sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor)

{

return NULL;

}         由此可見,在IServiceManager::asInterface函數中,最終會調用下面語句:

[cpp] view plain copy print ?

  1. intr = new BpServiceManager(obj);   

intr = new BpServiceManager(obj);          即為:

[cpp] view plain copy print ?

  1. intr = new BpServiceManager(new BpBinder(0));   

intr = new BpServiceManager(new BpBinder(0));         回到defaultServiceManager函數中,最終結果為:

[cpp] view plain copy print ?

  1. gDefaultServiceManager = new BpServiceManager(new BpBinder(0));  

gDefaultServiceManager = new BpServiceManager(new BpBinder(0));        這樣,Service Manager遠端接口就建立完成了,它本質上是一個BpServiceManager,包含了一個句柄值為0的Binder引用。

        在Android系統的Binder機制中,Server和Client拿到這個Service Manager遠端接口之後怎麼用呢?

        對Server來說,就是調用IServiceManager::addService這個接口來和Binder驅動程式互動了,即調用BpServiceManager::addService 。而BpServiceManager::addService又會調用通過其基類BpRefBase的成員函數remote獲得原先建立的BpBinder執行個體,接着調用BpBinder::transact成員函數。在BpBinder::transact函數中,又會調用IPCThreadState::transact成員函數,這裡就是最終與Binder驅動程式互動的地方了。回憶一下前面的類圖,IPCThreadState有一個PorcessState類型的成中變量mProcess,而mProcess有一個成員變量mDriverFD,它是裝置檔案/dev/binder的打開檔案描述符,是以,IPCThreadState就相當于間接在擁有了裝置檔案/dev/binder的打開檔案描述符,于是,便可以與Binder驅動程式互動了。

       對Client來說,就是調用IServiceManager::getService這個接口來和Binder驅動程式互動了。具體過程上述Server使用Service Manager的方法是一樣的,這裡就不再累述了。

      IServiceManager::addService和IServiceManager::getService這兩個函數的具體實作,在下面兩篇文章中,會深入到Binder驅動程式這一層,進行詳細的源代碼分析,以便更好地了解Binder程序間通信機制,敬請關注。