David.Ko

          Follow my heart!
          posts - 100, comments - 11, trackbacks - 0, articles - 0
             :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          [轉載]Android平臺——Binder機制

          Posted on 2010-11-18 17:15 David.Ko 閱讀(1108) 評論(0)  編輯  收藏 所屬分類: Android

          由代碼來補充部分:

          int main(int argc, char** argv)

          {

              sp<ProcessState> proc(ProcessState::self());

              sp<IServiceManager> sm = defaultServiceManager();

              LOGI("ServiceManager: %p", sm.get());

              AudioFlinger::instantiate();

              MediaPlayerService::instantiate();

              CameraService::instantiate();

              ProcessState::self()->startThreadPool();

              IPCThreadState::self()->joinThreadPool();

          }

          sp<ProcessState> proc(ProcessState::self()),這一行代碼會建立ProcessState對象,一個進程只有唯一的一個ProcessState對象,而ProcessState類的作用是來打開/dev/binder設備。這也就說明了一個問題,一個進程只不可能同時存在多個對/dev/binder的操作。

          sp<IServiceManager> sm = defaultServiceManager(),這一行代碼要做的事情參見上圖。1、創建一個BpBinder2、由BpBinder對象創建BpServiceManger對象。(為什么要采取如此不自然的方式,可以看一下這兩個對象繼承的基類)。完成這一步驟的最重要的作用在于以后對于IServiceManager對象的方法的調用,都將會由其子類BpServiceManger的方法來實現(這樣做的意義何在?這樣的作用僅僅在于我們可以重用IServiceManager的代碼,別忘了我們還有一個類似的繼承自IServiceManager的類,它叫做BnServiceManger)。這樣說起來似乎過于抽象,好在我們可以舉一個例子,接下去的代碼就會有例子出現。

          CameraService::instantiate(),這一行的代碼(前面還有兩行?相信我,他們絕對是幾乎一樣的實現,當然我是指從Binder層來說,而不是指與硬件相關的交互)。我們仍然先畫出結構圖:

          我們需要一點代碼來輔助我們的分析,CameraService::instantiate的代碼如下:

          void CameraService::instantiate() {

              defaultServiceManager()->addService(

                      String16("media.camera"), new CameraService());

          }。

          仍然是由defaultServiceManager函數開始,但是我們此時已經擁有了對象,而這樣做的目的僅僅在于我們調用的會是BpServiceManger類中的addService方法,而不是IServiceManager基類的addService方法。我們試著去尋找BpServiceManger類中的addService函數。在此之前有個需要我們注意的地方new CameraService,這里實例化了一個CameraService對象,他的基類們是我們要注意的,因為之后我們將不得不關注于整套虛函數調用的機制。CameraService類的繼承關系我在圖中已經畫出:IBinder->BBinder(ICmaerService兩個基類)->BnInterface->BnCamerService->CamerService,看起來足夠復雜,不幸的是這個繼承模式是有意義的。

          我們將思路再拉回來,接著看BpServiceManger類中addService的實現:

          virtual status_t addService(const String16& name, const sp<IBinder>& service)

          {

                  Parcel data, reply;

                  data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

                  data.writeString16(name);

                  data.writeStrongBinder(service);

                  status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

                  return err == NO_ERROR ? reply.readInt32() : err;

          }

          Data.writeInterfaceTokendata.writeString這兩行我們無需關注,因為它們完成一些接口命名之類的事情。來看看data.writeStrongBinder會做些什么:

          status_t Parcel::writeStrongBinder(const sp<IBinder>& val)

          {

              return flatten_binder(ProcessState::self(), val, this);

          }

          flatten_binder代碼如下:

          status_t flatten_binder(const sp<ProcessState>& proc,

              const sp<IBinder>& binder, Parcel* out)

          {

              flat_binder_object obj;

             

              obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

              if (binder != NULL) {

                  IBinder *local = binder->localBinder();

                  if (!local) {

                      BpBinder *proxy = binder->remoteBinder();

                      if (proxy == NULL) {

                          LOGE("null proxy");

                      }

                      const int32_t handle = proxy ? proxy->handle() : 0;

                      obj.type = BINDER_TYPE_HANDLE;

                      obj.handle = handle;

                      obj.cookie = NULL;

                  } else {

                      obj.type = BINDER_TYPE_BINDER;

                      obj.binder = local->getWeakRefs();

                      obj.cookie = local;

                  }

              } else {

                  obj.type = BINDER_TYPE_BINDER;

                  obj.binder = NULL;

                  obj.cookie = NULL;

              }

             

              return finish_flatten_binder(binder, obj, out);

          }

          我們先來關注IBinder *local = binder->localBinder()這一行代碼,binder變量是一個IBinder類的指針,那么是否是說我們要調用的是IBinder類的localBinder函數呢?我去查看代碼,發現它是一個虛函數,說明我們將會調用的是指針指向的對象的localBinder函數。還沒忘記我們剛才特別提到的地方吧?defaultServiceManager()->addService(String16("media.camera"), new CameraService());它是一個CamerService對象,理論上來說我們應該是按照沿基類向上的方式查找實現,CamerService-> BnCamerService->BnInterface->ICmaerService,BBinder兩個基類-> IBinder這樣的查找順序。我們在BBinder類的實現中找到了這個localBinder這個函數,那么這里將會調用的就是BBinder對象的實現:

          BBinder* BBinder::localBinder()

          {

              return this;

          }很明顯代碼接著會走到橙色部分。

          那么finish_flatten_binder又會做些什么呢?代碼我就不貼了,它的作用是更新相應的數據偏移量指針。但是寫到這里,我們似乎越看越糊涂,這些步驟有什么意義?Parcel類為什么又突然出現了?我們來做一下補充,首先是Parcel類的作用,它是用來完成數據的序列化的,也就是完成數據投遞之前的準備工作的。投遞的數據都會放在這個類的一個實例中。我去查找Parcel類的定義的時候發現它沒有虛函數,也就是說關于投遞數據序列化的操作都會在這個類及其實現中完成。我們終于可以暫時的擺脫那些虛函數們了。

          我們的工作還遠沒有結束,我們還沒有看到數據是如何投遞的?那么我們接著來看addService函數中的最后一個函數調用remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply),它明顯是用來投遞數據的,如何投遞?這里我們要弄清楚兩個問題:1remote函數返回的是什么?也就是transcat是哪個對象的方法。2、transcat如何與底層交互。

          我們先來看看第一個問題。先前已經討論過,addService方法的調用是來自BpServiceManager對象,我們忘了給出另一套類繼承的機制:RefBase->IServiceManager,BpRefBase兩個基類->BpInterface->BpServiceManager。 那么這里的remote方法(與addService一樣均屬于BpServiceManager),將會調用BpServiceManager的基類BpRefBaseremote方法。其實現時:inline  IBinder*   remote()   { return mRemote; }。問題在于這里的mRemote會是BBinder呢還是BpBinder?這個討論使得我們不得不又再次回到之前的代碼中去(確實復雜,但還不至于會使人疑惑。)答案在很早以前的defaultServiceManager函數中,之前我們并沒有分析過這個函數,是因為我們之前并不需要知道這個函數太多的細節,我們只用知道它是為了完成BpServiceManger對象的建立,但實際上,它還完成了另一個功能,將BpRefBased對象的mRemote成員初始化為BpBinder對象。來看代碼:

          sp<IServiceManager> defaultServiceManager()

          {

              if (gDefaultServiceManager != NULLreturn gDefaultServiceManager;

             

              {

                  AutoMutex _l(gDefaultServiceManagerLock);

                  if (gDefaultServiceManager == NULL) {

                      gDefaultServiceManager = interface_cast<IServiceManager>(

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

                  }

              }

             

              return gDefaultServiceManager;

          }

          ProcessState::self()->getContextObject 此函數返回一個BpBinder對象,當然這個對象的指針是其基類指針IBander。然后由interface_cast再次調用,而為mRemote成員的賦值也同樣發生在BpServiceManger對象的建立之時,調用BpServiceManger類的構造函數:    BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl),再次調用BpInterface類的構造函數

          template<typename INTERFACE>

          inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)

              : BpRefBase(remote)

          就在綠色的代碼部分了,具體的分析請看另一篇文檔,這里只是補充。

          第一個問題,為我們指明了方向,也就是通訊的時候會采用BpBinder對象的transact函數。這樣我們來繼續看一下第二個問題,現在我們直奔BpBinder類中的transact函數的實現:

          status_t BpBinder::transact(

              uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

          {

              // Once a binder has died, it will never come back to life.

              if (mAlive) {

                  status_t status = IPCThreadState::self()->transact(

                      mHandle, code, data, reply, flags);

                  if (status == DEAD_OBJECT) mAlive = 0;

                  return status;

              }

           

              return DEAD_OBJECT;

          }

           

          今天只能寫這么多,binder機制的路還很長很長!

          http://wsqhs.spaces.live.com/blog/cns!94F639580F58209C!642.entry

          主站蜘蛛池模板: 马边| 安新县| 前郭尔| 东平县| 安泽县| 宜川县| 奎屯市| 德钦县| 大兴区| 苍南县| 明溪县| 嘉善县| 石楼县| 美姑县| 抚州市| 大同县| 遂宁市| 宜都市| 翁牛特旗| 梨树县| 襄樊市| 阿尔山市| 武邑县| 泸西县| 新余市| 台东市| 大丰市| 彭州市| 潞西市| 临城县| 安阳市| 康马县| 迁安市| 维西| 桦甸市| 新宾| 延川县| 钟山县| 怀远县| 鹤岗市| 阿荣旗|