http://wycwang.blogspot.tw/2012/09/android-surface.html
01 static sp<ISurfaceComposer> getComposerService() 02 { 03 sp<ISurfaceComposer> sc; 04 Mutex::Autolock _l(gLock); 05 if (gSurfaceManager != 0) { 06 sc = gSurfaceManager; 07 } else { 08 // release the lock while we're waiting... 09 gLock.unlock(); 10 11 sp<IBinder> binder; 12 sp<IServiceManager> sm = defaultServiceManager(); 13 do { 14 binder = sm->getService(String16("SurfaceFlinger")); 15 if (binder == 0) { 16 LOGW("SurfaceFlinger not published, waiting..."); 17 usleep(500000); // 0.5 s 18 } 19 } while(binder == 0); 20 21 // grab the lock again for updating gSurfaceManager 22 gLock.lock(); 23 if (gSurfaceManager == 0) { 24 sc = interface_cast<ISurfaceComposer>(binder); 25 gSurfaceManager = sc; 26 } else { 27 sc = gSurfaceManager; 28 } 29 } 30 return sc; 31 }sp<IServiceManager> defaultServiceManager()Android 圖形系統使用的是 client-server 的架構, client 與 server 位在不同的 process,彼此之間透過 binder 通信, 除了 client 與 server, Android 另外有一個全域的 service manager 用來管理各種 service. defaultServiceManager() 函式的功能就在獲得和 service manager 的通信管道, 程式代碼如下:
01 sp<IServiceManager> defaultServiceManager() 02 { 03 if (gDefaultServiceManager != NULL) return gDefaultServiceManager; 04 { 05 AutoMutex _l(gDefaultServiceManagerLock); 06 if (gDefaultServiceManager == NULL) { 07 gDefaultServiceManager = interface_cast<IServiceManager>( 08 ProcessState::self()->getContextObject(NULL)); 09 } 10 } 11 return gDefaultServiceManager; 12 }
看來每個 process, gDefaultServiceManager 只會有一份instance. 若是 gDefaultServiceManager 尚未建立, 則以下程式代碼會被執行:
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
ProcessState::self() 函式程式代碼如下
\frameworks\base\libs\binder\ProcessState.cpp
01 sp<ProcessState> ProcessState::self() 02 { 03 if (gProcess != NULL) return gProcess; 04 05 AutoMutex _l(gProcessMutex); 06 if (gProcess == NULL) gProcess = new ProcessState; 07 return gProcess; 08 }
和 gDefaultServiceManager 一樣, 一個 process 中, gProcess 也只有一份instance, ProcessState 的建構式負責開啟binder 驅動 (/dev/binder), 並且將 binder 的記憶體空間 mapping 到 virtual memory space.
讀者可以自行跟一下 ProcessState 的建構式代碼.
讀者可以自行跟一下 ProcessState 的建構式代碼.
回到
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
其中 調用getContextObject(NULL); 得到和 services manager 之間的 binder(此處為 BpBinder), 這裡的interface_cast 蠻關鍵的, interface_cast 是一個 template,定義如下:
01 template<typename INTERFACE> 02 inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) 03 { 04 return INTERFACE::asInterface(obj); 05 }
由以上 interface_cast 的定義, 下面這一段程式碼
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
等同於
gDefaultServiceManager = IServiceManager::asInterface( const sp<IBinder>& obj);
現在關鍵來到IServiceManager:: asInterface(). 但是在 IServiceManager 這個 class 中找不到 asInterface () 函式的定義和宣告. IServiceManager 的父類別是 IInterface, 在IServiceManager.h 中引用了 IInterface.h , 在 IInterface.h找到了以下兩個巨集定義, 巨集定義中的符號 “##” 是”連接”的意思:
01 #define DECLARE_META_INTERFACE(INTERFACE) \ 02 static const String16 descriptor; \ 03 static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \ 04 virtual const String16& getInterfaceDescriptor() const; \ 05 I##INTERFACE(); \ 06 virtual ~I##INTERFACE(); \
01 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ 02 const String16 I##INTERFACE::descriptor(NAME); \ 03 const String16& I##INTERFACE::getInterfaceDescriptor() const { \ 04 return I##INTERFACE::descriptor; \ 05 } \ 06 sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \ 07 { \ 08 sp<I##INTERFACE> intr; \ 09 if (obj != NULL) { \ 10 intr = static_cast<I##INTERFACE*>( \ 11 obj->queryLocalInterface( \ 12 I##INTERFACE::descriptor).get()); \ 13 if (intr == NULL) { \ 14 intr = new Bp##INTERFACE(obj); \ 15 } \ 16 } \ 17 return intr; \ 18 } \ 19 I##INTERFACE::I##INTERFACE() { } \ 20 I##INTERFACE::~I##INTERFACE() { } \
在 IServiceManager.h , 使用到的是DECLARE_META_INTERFACE巨集如下
01 DECLARE_META_INTERFACE(ServiceManager);
巨集展開後的程式代碼:
01 static const String16 descriptor; 02 static sp<IServiceManager > asInterface(const sp<IBinder>& obj); 03 virtual const String16& getInterfaceDescriptor() const; 04 IServiceManager (); 05 virtual ~ IServiceManager ();在 IServiceManager.cpp 則是使用到IMPLEMENT_META_INTERFACE巨集:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
巨集展開後程式代碼如下:
01 const String16 IServiceManager::descriptor("android.os.IServiceManager"); 02 const String16& IServiceManager::getInterfaceDescriptor() const { 03 return IServiceManager::descriptor; 04 } 05 sp<IServiceManager> IServiceManager::asInterface(const sp<IBinder>& obj) { 06 sp<IServiceManager> intr; 07 if(obj!=NULL) { 08 intr=static_cast<IServiceManager*>( 09 obj->queryLocalInterface(IServiceManager::descriptor).get()); 10 if (intr == NULL) { 11 intr = new BpServiceManager(obj); 12 } 13 } 14 return intr; 15 } 16 IServiceManager::IServiceManager() { } 17 IServiceManager::~IServiceManager() { }
整個IServiceManager::asInterface()函式的關鍵是 new BpServiceManager(obj); 這一行程式代碼. 要注意, 這裡產生的是BpServiceManager 類別的物件. 類別BpServiceManager繼承自 IServiceManager, BpServiceManager建構式傳入的參數是 BpBinder 型態物件.提醒一下, 此 BpBinder 型態物件 是和 service manager 之間的 IPC. 在BpServiceManager物件中的mRemote 就是此BpBinder物件.
回到getComposerService() 函式, 取得 IServiceManager 介面(BpServiceManager物件)後,接下來要透過BpServiceManager的getService()函式取得 SurfaceFlinger service 的資訊, 程式片段如下
01 binder = sm->getService(String16("SurfaceFlinger"));
關鍵在 getService() 這個函式, 看看程式碼:
/frameworks/base/libs/binder/IServiceManager.cpp
01 virtual sp<IBinder> getService(const String16& name) const 02 { 03 unsigned n; 04 for (n = 0; n < 5; n++){ 05 sp<IBinder> svc = checkService(name); 06 if (svc != NULL) return svc; 07 LOGI("Waiting for sevice %s...\n", String8(name).string()); 08 sleep(1); 09 } 10 return NULL; 11 }
調用checkService() 函式, 若返回為NULL, 則 process sleep 一秒鐘後繼續嘗試獲取, 最多嘗試五次. 這是為了防止SurfaceFlinger service 在嘗試獲取的當下還沒有啟動起來.
看看checkService()函式做了什麼:
/frameworks/base/libs/binder/IServiceManager.cpp
01 virtual sp<IBinder> checkService( const String16& name) const 02 { 03 Parcel data, reply; 04 data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); 05 data.writeString16(name); 06 remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); 07 return reply.readStrongBinder(); 08 }
宣告兩個Parcel 變數data, reply, 分別做為binder傳送和接收時的資料容器使用. 接下來
沒有留言:
張貼留言