Android Binder - service proxy

来源:互联网 发布:淘宝站外推广有哪些 编辑:程序博客网 时间:2024/05/21 12:14

Service Manager)我们学习了Service Manager(服务管家)在Android Binder中的作用——服务(Service)注册,服务(Service)查询和获取等功能。

        我们知道Service Manager既是服务的管理对象,又是一个系统级的服务server(通过向驱动发送设置命令,使自己成为服务管家),它用来管理系统服务,也用于向客户端体统服务。那么Service Manager的客户端(包括我们通常所说的其它系统服务和系统服务的客户端)如何同它进行通讯呢?客户端不可能凭空发送请求吧!那么在android系统中的binder肯定有实现客户端和服务端联系的机制。

        本文我们一起学习服务(Service)在客户端中的代理机制,服务代理对象就是服务端和客户端的这个联络员。在详细介绍服务代理之前,让我们先来了解一下服务代理在应用中的模型。

(一)服务代理应用模型

        下面是客户端(这里的客户端是泛指请求服务的一方,自然有时候也包括System Server,比如当System Server向Service Manager请求添加服务的时候)通过服务代理,向服务器端请求服务的模型:

(1)首先客户端向Service manager查找相应的Service。这在前一篇文中有比较详细的介绍,这里不做赘述。

(2)Android系统的binder机制将会为客户端进程中创建一个Service代理,这个创建过程是本文的重点,下面会详细介绍。

(3)客户端视角只有Service代理,他所有对Service的请求都发往Service代理,然后由Service代理把用户请求转发给Service本身。

(4)Service处理完成之后,把结果返回给Service代理,Service代理负责把处理结果返回给客户端。

     注意客户端对Service代理的调用都是同步调用(调用挂起,直到调用返回为止),这样客户端视角来看调用远端Service的服务和调用本地的函数没有任何区别。这就是我之前说的Binder机制的一个特点—线程迁移,这使得一个线程就像进入另一个线程执行并待会执行结果。

 

(二)MediaService

        要想说明白服务代理的创建过程,还真不是那么容易的,最好的办法就是参照android中的源码,一步步走下去,这里我们还是选择MediaService的应用为例吧(看过一些资料也是以MS为例介绍的)。

        MediaService是android系统中的一个应用程序,和其他普通的应用程序没什么不同,源码如下:

framework\base\Media\MediaServer\Main_mediaserver.cpp

 int main(int argc, char** argv)
 {
     sp proc(ProcessState::self());
     sp sm = defaultServiceManager();
     LOGI("ServiceManager: %p", sm.get());
     AudioFlinger::instantiate();
     MediaPlayerService::instantiate();
     CameraService::instantiate();
     AudioPolicyService::instantiate();
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
 }

        怎么样?看到这个文件的代码是不是很迷惑啊!那么多陌生的东东,怎么理解啊!那么多的难关,那么厚的面纱,看来,要想见到服务代理的创建,还得过五关斩六将啊!下面我们就来层层剥开她神秘的面纱。

(1)ProcessState

    在Android系统中任何进程,要想使用Binder机制,必须要创建一个ProcessState对象和IPCThreadState对象(不要急,这个对象我们将在后面介绍)。

        我们知道,一个客户端进程可能有多个Service的服务,这样就会创建多个Service代理(BpBinder对象,当然上面还会有封装的),那么这个进程就需要一个东东来管理这些服务代理。ProcessState就是这么个东东,它的作用就是维护当前进程中所有Service代理

        ProcessState是一个singleton类型(关于这个类型,你可以查阅相关资料),一个进程只能创建一个他的对象。客户端进程中的ProcessState对象将会负责维护这些Service代理。那既然这样,Service代理是不是就是这个ProcessState创建的呢?呵呵,你猜对了,Service代理正是在这里被创建的,不过我可没打算现在就来分析服务代理的创建过程,你的一步一步脚踏实地地才能走向“光明”哦!

       上面的main函数中的第一句是什么?不就是这个ProcessState嘛,这里我们暂且记住一点,她就是一个管理服务代理的对象就好。先来看看她的创建过程,那就看看她的构造函数,咦,怎会回事?这个构造函数是私有成员那!

 private:
   ProcessState();

        嗯,你没有看错,它的确是被声明成私有成员了,那就意味着在类的外部无法直接通过其构造函数,生成自己的一个对象,所以上面Main函数里面用了另一个公有成员函数ProcessState::self(),来调用其构造函数,生成ProcessState对象:

 sp ProcessState::self()
 {
     if (gProcess != NULL) return gProcess;//如果已经创建了,//则直接返回这个全局的ProcessState对象
     AutoMutex _l(gProcessMutex);
 //如果第一次创建,调用其构造函数
     if (gProcess == NULL) gProcess = new ProcessState;
     return gProcess;
 }

还记得Main函数中的第一句:

 sp proc(ProcessState::self());

        不是说不能在外部直接调用其构造函数的吗?其实这也不是我们讨论的重点,不过既然说了,就解释一下吧。熟悉C++的朋友应该都知道,当你定义的类中,没有显示定义一个复制构造函数的话,系统会帮你添加一个默认的复制构造函数,上面的就是调用这个复制构造函数。

 ProcessState::ProcessState()定义如下:
 ProcessState::ProcessState()
     : mDriverFD(open_driver())   
     , mVMStart(MAP_FAILED)
     , mManagesContexts(false)
     , mBinderContextCheckFunc(NULL)
     , mBinderContextUserData(NULL)
     , mThreadPoolStarted(false)
     , mThreadPoolSeq(1)
 {
     ……
         mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);//映射内 
         ……
 }

        这样就生成了一个ProcessState对象proc,用来管理本进程中所有的服务代理,当程序运行结束,proc会自动delete内部的内容,自动释放了先前分配的资源。

这里ProcessState对象打开了/dev/binder设备,并保留了文件描述符,那么打开设备文件,自然是要用它进行通讯了,不过在ProcessState中你还真的很难找到,使用这个文件描述符进行通讯的代码。那么它在什么地方使用呢?我们会在后面介绍IPCThreadState时候在有说明。

(2)defaultServiceManager()

     ……
 sp sm = defaultServiceManager();

        这里生成了一个IserviceManager的对象sm,IserviceManager是什么?还记得上一篇文中的内容吧,serviceManager是服务管家,它负责系统服务的管理。你当然不会简单的认为有了serviceManager这个程序就万事OK了,这个守护进程做这么伟大的事,怎么可能孤军奋战,每一个成功的男人背后都有一个支持他的女人,这是谁说的,不记得了,呵呵!serviceManager也不例外,IserviceManager就提供了这样的一个机制,给了serviceManager管理服务的能力。

       那么这个sm究竟什么呢?说的明白点,上面那行代码就是生成了一个服务代理啦!不要惊奇,MS进程就是通过这个代理对象sm和Service Manager通讯的,下面我们就来重点分析这个IserviceManager对象sm的创建过程。 

Frameworks\base\libs\binder\IserviceManager.cpp

 p defaultServiceManager()
 {
     if (gDefaultServiceManager != NULL)
 return gDefaultServiceManager;  //如果已经创建过,//直接返回
     {
         AutoMutex _l(gDefaultServiceManagerLock);
         if (gDefaultServiceManager == NULL) {
           gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL));     //创建代理对象 
         }
     }
     return gDefaultServiceManager;
 }

这个函数中调用了下面的语句:

gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL))    //创建代理对象

       这是创建代理对象的地方,这句代码比较复杂一些,先来看看它的参数吧,ProcessState::self()我们现在已经很熟悉了,getContextObject()函数是干什么的:

 sp ProcessState::getContextObject(const sp& caller)
 {
     if (supportsProcesses()) {
 
         return getStrongProxyForHandle(0);
     } else {
         return getContextObject(String16("default"), caller);
     }
     

       这个getStrongProxyForHandle(int32_t handle)函数才是真正创建服务代理的地方,上面都是对其的封装罢了,看看这段代码:

 sp ProcessState::getStrongProxyForHandle(int32_t handle)
 {
     sp 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;
 }

   

        当前进程首先调用lookupHandleLocked函数去查看当前进程维护的Service代理对象的列表,该待创建Service代理对象是否已经在当前进程中创建,如果已经创建过了,则直接返回其引用就可以了。否则将会在Service代理对象的列表增加相应的位置,保存将要创建的代理对象。lookupHandleLocked的源码这里就不贴出来了,自己查阅吧!

        如果Service代理对象已经创建过了,直接增加引用计数就行了。若没有创建过,则需要创建一个新的Service代理对象。下面是BpBinder的构造函数:

 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); 
 

        注意:上面创建服务代理对象时,传递的是handle,handle是一个表示符,用来标志不同的服务类型,这里的handle其实是0,上面已经有所说明,可以回头看看。Binder机制中,binder驱动每个服务维护一个服务句柄(这是Windows中的概念),上层创建服务代理对象时,传入一个唯一标志服务句柄handle,就可以获得这个特定服务句柄的代理对象。0号服务句柄就是Service Mananger服务的,这是著名句柄,众所周知的。

       这里多少两句,我们刚才应该看到了,代码生产了一个BpBinder对象,并赋给了sp指针,说明BpBinder是Ibinder的一个继承类。Ibinder类是android系统对binder机制的一个抽象定义,其实就是一个抽象类,所有要实现binder机制的客户,服务端都要继承这个抽象类。 这时程序又返回到了这里:

   gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL))    //创建代理对象

        这个调用ProcessState::self()->getContextObject(NULL)返回的是sp类型,而gDefaultServiceManager是一个sp对象,这两者有嘛关系啊,为何能够转换呢?先不管这些,先来看看这个interface_cast如何定义的吧!

Framework\base\include\binder\Iiterface.h

 template
 inline sp interface_cast(const sp& obj)
 {
     return INTERFACE::asInterface(obj);
 }

       这是个模版类,C++特有的东东,刚才的我们看到的是用IserviceManager来对模版进行实例化的,那我们还原一下代码:

 template
 inline sp< IserviceManager > interface_cast(const sp& obj)
 {
     return IserviceManager::asInterface(obj);
 }

        那么这个IserviceManager::asInterface()在哪儿呢?我找遍源码也没发现它定义的地方,后来发现不是那么回事,要想理清这层关系还要从IserviceManager类说起,下面是它的定义:

Framework\base\include\binder\IserviceManager.h

 class IServiceManager : public IInterface
 {
 public:
 DECLARE_META_INTERFACE(ServiceManager);
 ……
     virtual status_t  addService( const String16& name,
                                             const sp& service) = 0;
 ……
 };

  

        这个类继承了IIterface类,并出现一个貌似宏的东东DECLARE_META_INTERFACE(ServiceManager);这是什么玩意呢?不太喜欢这个东东,所以一开始看代码时就没太注意这东西,可后来才发现这是类型转换的关键所在,看看定义:

Framework\base\include\binder\Iiterface.h

 #define DECLARE_META_INTERFACE(INTERFACE)                               \
     static const String16 descriptor;                                   \
     static sp asInterface(const sp& obj);        \ 
     virtual const String16& getInterfaceDescriptor() const;             \
     I##INTERFACE();                                                     \
     virtual ~I##INTERFACE();                                            \

       这里可没有注释啊,那些“\”玩意都是控制换行连接的,这个定义一大堆的,都什么玩意,看的头痛,咱也不管它是什么,我们先来个顺藤摸瓜,既然上面IserviceManager类定义时,传递了一个ServiceManager参数,那就给他兑换出来看看得了,我把“\”去掉,就当是一个函数了,方便观察。

 #define DECLARE_META_INTERFACE(serviceManager)
 {                               
     static const String16 descriptor;                                    
     static sp asInterface(const sp& obj);        
     virtual const String16& getInterfaceDescriptor() const;             
     IserviceManager();                                                      
     virtual ~IserviceManager();     
 }                                       

        呵呵,这下就一目了然了吧,不就是声明了一个字符串描述符和一个返回描述符的接口函数,还有构造和析构函数嘛! 当然,这里出现了我们想要的东西asInterface()的定义,那这样我们上面的函数调用就有着落啦!嗯,现在是看看它定义的时候了!

       既然它声明这么横空,那定义怎么着也得打扮一下吧!瞧瞧,在IserviceManager.cpp文件中有这么一句代码:

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

      真是双胞胎啊,长的那么像,看看这个孪生胞弟:

 #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::asInterface(const sp& obj)  \ 
                                                                      \
         sp intr;                                          \ 
         if (obj != NULL) {                                              \
             intr = static_cast                         \ 
                 obj->queryLocalInterface(                               \
                         I##INTERFACE::descriptor).get());               \
             if (intr == NULL) {                                         \
                 intr = new Bp##INTERFACE(obj);                          \
                                                                      \
                                                                      \
         return intr;                                                    \
                                                                      \
     I##INTERFACE::I##INTERFACE() { }                                    \
     I##INTERFACE::~I##INTERFACE() { }                                

       还是看不下去了,先兑现先:

 #define IMPLEMENT_META_INTERFACE(serviceManager, "android.os.IServiceManager")                       
     const String16 IserviceManager::descriptor("android.os.IServiceManager");       
                 
     const String16& IserviceManager::getInterfaceDescriptor() const {      
         return IserviceManager::descriptor;                                 
         
                                                                
     sp IserviceManager::asInterface(const sp& obj)  
                                                                       
         sp intr;                                           
         if (obj != NULL) {                                               
             intr = static_cast(                          
                 obj->queryLocalInterface(IserviceManager::descriptor).get());               
             if (intr == NULL) {                                          
                 intr = new BpserviceManager (obj);                          
                                                                       
                                                                       
         return intr;                                                     
                 
                                                        
     I##INTERFACE::IserviceManager () { }               
                        
     I##INTERFACE::~IserviceManager () { }                                 

        这下终于清楚了,最后就是将一个BpServiceManager对象返回给sm,那么你也看出来了,BpServiceManager是IserviceManager的一个继承类,而这个对象sm就是MS进程获得的Service Manager服务的代理了,MS就可以通过sm这个代理对象发送添加服务等请求了。

        代码走到这里,服务代理对象的生成过程就结束了,总之一句话,defaultServiceManager()函数返回了一个Service Manager的服务代理对象,提供给本进程的其他服务器端或客户端访问Service Manager的接口。

(三)服务器端初始化

framework\base\Media\MediaServer\Main_mediaserver.cpp

 int main(int argc, char** argv)
 {
     ……
     AudioFlinger::instantiate();
     MediaPlayerService::instantiate();
     CameraService::instantiate();
     AudioPolicyService::instantiate();
     ……
 }

        这四行代码就是android系统中,SM进程驱动的四个系统服务的初始化代码。每个服务都调用自己的instantiate()实例化函数,向Service Manager注册自己,以为之前做过Camera模块,比较熟悉点,呵呵,所以我们以CameraServce::instantiate()为例来说明服务器端实例化的过程:

Framework\base\camera\libcameraservice\cameraservice.cpp

 void CameraService::instantiate() {
     defaultServiceManager()->addService(
             String16("media.camera"), new CameraService());
 }

 

        其实就是这么简单,首先创建一个自己的实例,然后调用defaultServiceManager()函数,获得Service Manager的服务代理对象,再通过这个代理对象调用添加服务函数,将自己注册到服务管理器,个过程中的每一步,前面我们都已经分析过了,可以回头看看。其他的服务实例化过程和这个过程相同。

(四)ThreadState:: startThreadPool()

 Void Main()    
 {
 ……
 ……
 ProcessState::self()->startThreadPool();
 IPCThreadState::self()->joinThreadPool();
 }

       上面的代码已经说过了,这里就不列出来了,当MS执行到这里时,本进程完成了如下工作:

(1)创建了ProcessState对象,用来管理本进程中获取的服务代理对象。注意:每一个进程只能创建一个该对象。

(2) 获取了Service Manager的服务代理对象,可以通过这个对象和服务管家通讯了。

(3)实例化了一些服务,并向服务管家成功添加了这些服务。

       既然服务端准备好了,就应该进入循环状态,以便接收来自客户端的请求,没错,那么,下面我们继续分析上面两句代码:

 void ProcessState::startThreadPool()
 {
     AutoMutex _l(mLock);
     if (!mThreadPoolStarted) {
         mThreadPoolStarted = true;
         spawnPooledThread(true);
     }
 }

  

 void ProcessState::spawnPooledThread(bool isMain)
 {
     if (mThreadPoolStarted) {
         ……
         sp t = new PoolThread(isMain);
 //创建线程池,然后跑起来
         t->run(buf);
     }
 }

         PoolThread继承自Thread,这里的PoolThread()构造函数,其实什么都没做,就连run()函数都没有重载,创建该对象后直接调用run()函数。真正的线程创建在其父类Thread的run()中被创建:

 status_t Thread::run(const char* name, int32_t priority, size_t stack)
 {
    ……
     if (mCanCallJava) {
         res = createThreadEtc(_threadLoop,
                 this, name, priority, stack, &mThread);
    //这里创建了一个_threadLoop线程函数,这时候线程运行起来
     } else {
         res = androidCreateRawThreadEtc(_threadLoop,
                 this, name, priority, stack, &mThread);
     }
     ……
 }

 

 int Thread::_threadLoop(void* user)
 {
     Thread* const self = static_cast(user);
   
     do {
             if (first) {
             first = false;
             self->mStatus = self->readyToRun();
             ……         
         } else {
             result = self->threadLoop();//调用PoolThread的threadLoop()
         }
   
         ……
       } while(strong != 0);
     
     return 0;
 }

 

Framework\base\libs\binder\ProcessThread.cpp

 virtual bool threadLoop()
 {
         IPCThreadState::self()->joinThreadPool(mIsMain);
         return false;
 }

 

        到了这里,发现很奇怪啊,也是调用的IPCThreadState::joinThreadPool()函数,好吧,既然两句都是调用这个函数,而且这里都再次引入了一个不可忽视的对象IPCThreadState,下面先来了解一下什么是IPCThreadState,然后在分析这个joinThreadPoll()函数。

 

(五)IPCThreadState

        前面我们有提过,在ProcessState中打开了一个binder设备文件,并返回了一个文件描述符,在ProcessState中并没有使用这个文件描述符的地方,那么这个文件描述符到底被谁使用了呢?对,就是IPCThreadState对象。

       IPCThreadState也是一个singleton的类型,一个进程中也只能有一个这样的对象。它在android的binder机制中扮演什么样的角色呢?到了这里,你也可能已经猜到了,IPCThreadState主要负责信息的传递,所有要到达binder驱动和驱动中出来的信息都要由IPCThreadState来传递。IPCThreadState有一个传输函数transact():

 status_t IPCThreadState::transact(int32_t handle,
                                   uint32_t code, const Parcel& data,
                                   Parcel* reply, uint32_t flags)
 {
     ……
     if ((flags & TF_ONE_WAY) == 0) {
         if (reply) {
             err = waitForResponse(reply); 
         } else {
             Parcel fakeReply;
             err = waitForResponse(&fakeReply);
         }
         
     } else {
         err = waitForResponse(NULL, NULL);
     }
     
     return err;
 }
   
   
 status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
 {
     int32_t cmd;
     int32_t err;
   
     while (1) {
         if ((err=talkWithDriver()) < NO_ERROR) break; 
         err = mIn.errorCheck();
         
         cmd = mIn.readInt32();
   
         switch (cmd) {
         case BR_TRANSACTION_COMPLETE:
             if (!reply && !acquireResult) goto finish;
             break;
           ……
     }
     
     return err;
 }

 

 status_t IPCThreadState::talkWithDriver(bool doReceive)
 {
     ……
     do {
         
         if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) 
         ……
     } while (err == -EINTR);
     
     ……
 }

         这里出现ioctl()函数了,这可是binder驱动的接口啊,下面就不再跟踪了,总之,上层的信息就是通过这个途径发送的binder驱动的。这样我们再来总结一下IPCThreadState对象的作用:

(1)维护当前进程中所有对/dev/binder的读写。换句话说当前进程通过binder机制进行跨进程调用都是通过IPCThreadState对象来完成的

(2)IPCThreadState也可以理解成/dev/binder设备的封装,用户可以不直接通过ioctl来操作binder设备,都通过IPCThreadState对象来代理即可。

         说了半天,这里还是通过mDriverFD文件描述符,向binder设备文件写入数据。可是这个mDriverFD不是ProcessState的东东吗,怎么在这里被引用了呢?看看ProcessSate类定义就知道了。

 private:
     friend class IPCThreadState;  

         哦,原来IPCThreadState是ProcessState的一个友元类,这样IPCThreadSate就可以名正言顺地使用mDriverFD了。好了,下面我们继续来分析joinThreadPool()函数吧!

  void IPCThreadState::joinThreadPool(bool isMain)
 {
     
     androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
     status_t result;
     do {
         int32_t cmd;
         result = talkWithDriver(); 
         result = executeCommand(cmd); 
         }
         
     } while (result != -ECONNREFUSED && result != -EBADF);
     
     mOut.writeInt32(BC_EXIT_LOOPER); 
     talkWithDriver(false); 
 }

        看到了吧,这里是一个循环,循环调用talkWithDriver()从binder设备文件中读取信息,然后调用executeCommand()函数处理信息。这就是系统服务的循环体,不断重复地响应客户端的请求。

    不管是客户端进程和Service进程都是需要用IPCThreadState来和binder设备通讯的。那么现在我们从客户端和服务器端分别来总结一下IPCThreadState对象的作用。

  (1)如果是客户端进程,则通过服务代理BpBinder对象调用transact函数,该函数作用就是把客户端的请求写入binder设备另一端的Service进程,详细的内容我们放在下一篇文章介绍。

  (2)作为Service进程,当他完成初始化工作之后,他们需要进入循环状态等待客户端的请求,Service进程调用它的IPCThreadState对象的joinThreadPool方法,开始轮询binder设备,等待客户端请求的到来。

(六)总结

        本文中我们通过MS程序,分析了Service Manager服务代理的创建过程,以及服务线程启动循环监听消息的过程,当然还有服务代理的概念,服务代理的管理对象ProcessState和消息传递对象IPCThreadState。

        后面我们会从客户端请求服务端的服务的视角,来分析binder机制在android系统中的实际应用。


0 0
原创粉丝点击