现在的位置: 首页 > 综合 > 正文

Binder机制之Server端—defaultServiceManager()

2018年02月10日 ⁄ 综合 ⁄ 共 3526字 ⁄ 字号 评论关闭

分析这句代码:sp<IServiceManager>defaultServiceManager()

这句代码的最终目的是获取“应用程序中的0号引用”,即服务中的服务管理器的引用,即服务管理器接口,用来同服务管理器通信。

defaultServiceManager位置在framework\base\libs\binder\IServiceManager.cpp中,代码如下:

sp<IServiceManager> defaultServiceManager()
{
     //又是一个单例,设计模式中叫 singleton。
   if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
  {
     AutoMutex _l(gDefaultServiceManagerLock);

     if (gDefaultServiceManager == NULL)
     {
     //真正的gDefaultServiceManager是在这里创建的喔
     gDefaultServiceManager = interface_cast<IServiceManager>(
                     ProcessState::self()->getContextObject(NULL));
     }
  }
   return gDefaultServiceManager;
}

看这个这句ProcessState::self()->getContextObject(NULL));
ProcessState::self,肯定返回的是刚才创建的gProcess,然后调用它的getContextObject,注意,传进去的是NULL,即0
回到ProcessState类,看getContextObject(),代码如下:

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
    if (supportsProcesses()) 
    {
        return getStrongProxyForHandle(0);//注意,这里传入0
    }
}

进入到getStrongProxyForHandle,函数名字怪怪的,经常严重阻碍大脑运转,注意这个参数的命名,handle。搞过windows的应该比较熟悉这个名字,

这是对资源的一种标示,其实说白了就是某个数据结构,保存在数组中,然后handle是它在这个数组中的索引。就是这么一个玩意儿。

实际上就是根据引用号,获取该进程中的0号binder引用,即服务管理器引用。代码如下:

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
    
    //哈哈,果然,要从引用数组中查找对应索引的资源
    handle_entry* e = lookupHandleLocked(handle);-

   /*lookupHandleLocked这个就不说了,内部会返回一个handle_entry 
    下面是 handle_entry 的结构
    struct handle_entry 
    {
       IBinder* binder;--->Binder
       RefBase::weakref_type* refs;
    };
   */

    if (e != NULL) 
    {
        IBinder* b = e->binder;
        //第一次进来,肯定为空
        if (b == NULL || !e->refs->attemptIncWeak(this)) 
        {
            b = new BpBinder(handle);//看见了吧,创建了一个新的BpBinder
            e->binder = b;
            result = b;

        }....
    }
    return result;//返回刚才创建的BpBinder。
}

到这里,是不是有点乱了?对,当人脑分析的函数调用太深的时候,就容易忘记。
我们是从gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL));
开始搞的,现在,这个函数调用将变成gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
BpBinder又是个什么玩意儿,就是binder代理,此处为服务管理器在应用程序里的代理。
看BpBinder代码,BpBinder位置在framework\base\libs\binder\BpBinder.cpp中,暂时先不研究。

 再来看函数interface_cast<IServiceManager>的实现,它是一个模板函数,定义在framework/base/include/binder/IInterface.h文件中:

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

这里的INTERFACE是IServiceManager,于是调用了IServiceManager::asInterface函数。

上面等价于:

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

看来,只能跟到IServiceManager了。

class IServiceManager : public IInterface
{
  //ServiceManager,字面上理解就是Service管理类,管理什么?增加服务,查询服务等
  //这里仅列出增加服务addService函数
public:
   DECLARE_META_INTERFACE(ServiceManager);
   virtual status_t   addService( const String16& name,const sp<IBinder>& service) = 0;
};

这个宏DECLARE_META_INTERFACE(ServiceManager)定义:

#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文件中,我们只关注IServiceManager::asInterface的实现:

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

回到defaultServiceManager函数中,最终结果为:

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

这样,Service Manager远程接口就创建完成了,它本质上是一个BpServiceManager,包含了一个句柄值为0的Binder引用

抱歉!评论已关闭.