5.3.2 获取servicemanager的代理对象

Client端查询服务或者Server端注册服务,都要首先获取servicemanager的代理对象,然后通过该代理对象与servicemanager通信完成请求。获取servicemanager的代理对象涉及的类层次结构如图5-1所示。

5.3.2 获取servicemanager的代理对象 - 图1

图 5-1 servicemanager的类层次结构

由图中可以看出,servicemanager的类层次结构主要由四大部分组成:

Binder通信接口:提供了通信协议的实现,主要由IBinder、BBinder、BpBinder三个类组成。IBinder定义了Binder通信的接口,其子类BBinder是Service对应的Binder对象;子类BpBinder是Client端访问BBinder的代理对象,负责打开Binder设备与服务端通信。

Binder服务接口:定义了Client端可以访问Server端提供的哪些服务,由IServiceManager提供。

Proxy:主要由BpInterface和BpServiceManager实现。BpServiceManager实现了服务接口中声明的方法,BpInterface继承自BpRefBase,其成员变量mRemote中存储了Client端创建的BpBinder对象。

Stub:主要由BnInterface和BnServiceManager实现,到目前为止,系统中并未使用BnServiceManager,而是直接以servicemanager进程作为Server端。

defaultServiceManager函数用于获取servicemanager的Proxy对象,其位于frameworks/native/libs/binder/IServiceManager.cpp中,代码如下:


sp<IServiceManager>defaultServiceManager()

{

/*这里又是一个单例,gDefaultServiceManager是定义在Static.h中的全局变

量,其定义为:extern sp<IServiceManager>gDefaultServiceManager;/

if(gDefaultServiceManager!=NULL)return gDefaultServiceManager;

{

AutoMutex_l(gDefaultServiceManagerLock);

if(gDefaultServiceManager==NULL){

gDefaultServiceManager=interface_cast<IServiceManager>(

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

}

}

return gDefaultServiceManager;

}


defaultServiceManager函数的工作可以分为两部分:

1)调用ProcessState的getContextObject方法,参数为null。这部分工作返回上下文管理者对应的BpBinder,该对象是一个服务代理对象。

2)以上一步的返回值为参数调用interface_cast方法,将BpBinder封装成Client端易于使用的BpServiceManager对象。

1.getContextObject


getContextObject方法的代码如下:

sp<IBinder>ProcessState:getContextObject(const sp<IBinder>&caller)

{

return getStrongProxyForHandle(0);

}


getContextObject函数将请求转发给getStrongProxyForHandle,该函数并没有使用getCo-ntextObject传入的caller参数,而是直接将参数赋值为0,代码如下:


sp<IBinder>ProcessState:getStrongProxyForHandle(int32_t handle)

{

sp<IBinder>result;

AutoMutex_l(mLock);

//根据传入的handle,查找其是否已经存在相应的handle_entry

handle_entry*e=lookupHandleLocked(handle);

if(e!=NULL){

IBinder*b=e->binder;

if(b==NULL||!e->refs->attemptIncWeak(this)){

//以handle为参数创建BpBinder,此处是BpBinder(0)

b=new BpBinder(handle);

e->binder=b;//将BpBinder存入handle_entry的binder成员

if(b)e->refs=b->getWeakRefs();//将b的弱引用存入refs成员

result=b;//b本身作为返回结果

}else{

result.force_set(b);

e->refs->decWeak(this);

}

}

return result;

}

getStrongProxyForHandle(0)返回的是BpBinder(0),因此getContextObject函数返回的结

果也是BpBinder(0)。

接下来分析BpBinder的构造函数,位于frameworks/native/libs/binder/BpBinder.cpp中,

代码如下:

BpBinder:BpBinder(int32_t handle)

:mHandle(handle)//以handle初始化私有变量mHandle

,mAlive(1)

,mObitsSent(0)

,mObituaries(NULL)

{

extendObjectLifetime(OBJECT_LIFETIME_WEAK);

//调用了IPCThreadState的incWeakHandle函数,参数为0

IPCThreadState:self()->incWeakHandle(handle);

}

BpBinder首先在初始化列表中将传入的参数0赋值到私有成员变量mHandle中,然后调

用IPCThreadState上的方法,代码如下:

IPCThreadState*IPCThreadState:self()

{

if(gHaveTLS){//gHaveTLS的初始值为false

restart:

//用于记录TLS的key值

const pthread_key_t k=gTLS;

//返回线程局部存储的IPCThreadState

IPCThreadStatest=(IPCThreadState)pthread_getspecific(k);

if(st)return st;

return new IPCThreadState;

}

if(gShutdown)return NULL;

pthread_mutex_lock(&gTLSMutex);

if(!gHaveTLS){

//创建pthread_key_t,用于设置和检索TLS

if(pthread_key_create(&gTLS, threadDestructor)!=0){

pthread_mutex_unlock(&gTLSMutex);

return NULL;

}

gHaveTLS=true;

}

pthread_mutex_unlock(&gTLSMutex);

goto restart;

}


IPCThreadState的self方法中涉及TLS(Thread Local Storage,线程局部存储)的内容。在Linux的进程和线程模型中,同一个进程内的多个线程共享进程的地址空间,因此不同线程可以共享同一个全局变量和静态变量,这样虽然提高了线程间数据交换的效率,但是却对数据同步带来了额外的工作量。如果需要一个在当前线程内可以访问、其他线程不能访问的变量,就需要用到TLS。TLS的实现通常是提供一个全局索引表存储线程局部数据的地址,通过当前线程的pthread_key_t去查询其局部数据。在Linux下,TLS的实现依赖于以下两个函数:


void*pthread_getspecific(pthread_key_t key);

int pthread_setspecific(pthread_key_t key, const void*value);


由以上分析可知,IPCThreadState:self函数返回的是一个线程唯一的IPCThreadState对象。上述代码中,我们只看到了对pthread_getspecific函数的调用,该函数用于获取TLS变量,那么又是在哪里设置TLS变量的?

接下来分析IPCThreadState的构造函数,代码如下:


IPCThreadState:IPCThreadState()

:mProcess(ProcessState:self()),//关联到ProcessState

mMyThreadId(androidGetTid()),

mStrictModePolicy(0),

mLastTransactionBinderFlags(0)

{

pthread_setspecific(gTLS, this);//设置当前对象为TLS,键为gTLS

clearCaller();

mOrigCallingUid=mCallingUid;

//mIn和mOut是定义在IPCThreadState中的私有变量,类型为Parcel

mIn.setDataCapacity(256);

mOut.setDataCapacity(256);

}


在IPCThreadState的构造函数中,主要做了以下三部分工作:

1)将进程唯一的ProcesState存入其mProcess变量中。

2)通过pthread_setspecific将当前对象设为线程私有。

3)设置输入输出缓冲区mIn和mOut的大小。

IPCThreadState创建后,接着调用了incWeakHandle(0),代码如下:


void IPCThreadState:incWeakHandle(int32_t handle)

{

//向输出缓冲区中写入BC_INCREFS指令和handle的值0

mOut.writeInt32(BC_INCREFS);

mOut.writeInt32(handle);

}


incWeakHandle的代码很简单,在输出缓冲区中添加了BC_INCREFS指令和handle值。到这里,getContextObject方法就分析完了。读者可能发现,这个方法除了返回BpBinder外,似乎并没有参与Binder通信。接下来分析返回BpBinder后做了哪些操作。

2.interface_cast

getContextObject返回BpBinder后,需要以该返回值为参数调用interface_cast<IService-Manager>,因此以下代码是等价的:


interface_cast<IServiceManager>(

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


可以表示为:


interface_cast<IServiceManager>(

new BpBinder(0));


interface_cast方法定义在frameworks/native/include/binder/IInterface.h中,其代码如下:


template<typename INTERFACE>

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

{

return INTERFACE:asInterface(obj);

}


将INTERFACE泛型替换为IServiceManager,可以得到以下代码:


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

{

return IServiceManager:asInterface(obj);

}

最终可以得出以下等价关系:

interface_cast<IServiceManager>(

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


等价于:


IServiceManager:asInterface(new BpBinder(0))


接下来定位到IServiceManager的asInterface方法,代码如下:


class IServiceManager:public IInterface

{

public:

DECLARE_META_INTERFACE(ServiceManager);

//以下是IServiceManager提供给Client的接口

virtual sp<IBinder>getService(const String16&name)const=0;

virtual sp<IBinder>checkService(const String16&name)const=0;

virtual status_t addService(const String16&name,

const sp<IBinder>&service,

bool allowIsolated=false)=0;

virtual Vector<String16>

listServices()=0;

enum{

GET_SERVICE_TRANSACTION=IBinder:FIRST_CALL_TRANSACTION,

CHECK_SERVICE_TRANSACTION,

ADD_SERVICE_TRANSACTION,

LIST_SERVICES_TRANSACTION,

};

};


可见,IServiceManager中并未定义asInterface方法,并且其父类IInterface也未定义。那么asInterface来自何处?答案是:DECLARE_META_INTERFACE宏。该宏定义于IInterface.h中,代码如下:


define DECLARE_META_INTERFACE(INTERFACE)

static const android:String16 descriptor;

static android:sp<I##INTERFACE>asInterface(

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

virtual const android:String16&getInterfaceDescriptor()const;

I##INTERFACE();

virtual~I##INTERFACE();


以上宏定义中“\”符号表示换行符,“##”表示字符串连接符。

将INTERFACE替换为ServiceManager,代码如下:


//定义字符串常量descriptor

static const android:String16 descriptor;

//定义asInterface函数

static android:sp<IServiceManager>asInterface(

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

//获取descriptor的值

virtual const android:String16&getInterfaceDescriptor()const;

//定义构造和析构函数

IServiceManager();

virtual~IServiceManager();


DECLARE_META_INTERFACE宏定义了一些函数和常量,那么这些函数在哪里实现呢?答案是:IMPLEMENT_META_INTERFACE宏。该宏同样定义于IInterface.h中,代码如下:


define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)

const android:String16 I##INTERFACE:descriptor(NAME);

const android:String16&

I##INTERFACE:getInterfaceDescriptor()const{

return I##INTERFACE:descriptor;

}

android:sp<I##INTERFACE>I##INTERFACE:asInterface(

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

{

android:sp<I##INTERFACE>intr;

if(obj!=NULL){

intr=static_cast<I##INTERFACE*>(

obj->queryLocalInterface(

I##INTERFACE:descriptor).get());

if(intr==NULL){

intr=new Bp##INTERFACE(obj);

}

}

return intr;

}

I##INTERFACE:I##INTERFACE(){}

I##INTERFACE:~I##INTERFACE(){}

在IServiceManager中有如下代码使用该宏:

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;

//obj为BpBinder(0)

if(obj!=NULL){

intr=static_cast<IServiceManager*>(

obj->queryLocalInterface(//该方法返回NULL

IServiceManager:descriptor).get());

if(intr==NULL){

//将BpBinder封装成BpServiceManager

intr=new BpServiceManager(obj);

}

}

return intr;

}

IServiceManager:IServiceManager(){}

IServiceManager:~IServiceManager(){}


已知obj为BpBinder,其queryLocalInterface方法继承自IBinder,位于frameworks/native/libs/binder/Binder.cpp中,代码如下:


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

{

return NULL;

}


queryLocalInterface直接返回NULL,因此这里以BpBinder为参数创建BpServiceManager。该类位于frameworks/native/libs/binder/IServiceManager.cpp中,代码如下:


class BpServiceManager:public BpInterface<IServiceManager>

{

public:

/impl即BpBinder,这里调用了父类BpInterface的构造函数/

BpServiceManager(const sp<IBinder>&impl)

:BpInterface<IServiceManager>(impl)

{}

virtual sp<IBinder>getService(const String16&name)const

{……}

virtual sp<IBinder>checkService(const String16&name)const

{……}

virtual status_t addService(const String16&name,

const sp<IBinder>&service, bool allowIsolated)

{……}

virtual Vector<String16>listServices()

{……}

};


BpServiceManager把传入其构造函数的BpBinder,传给了其父类BpInterface的构造函数。BpInterface位于frameworks/native/include/binder/IInterface.h中,代码如下:


template<typename INTERFACE>

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

:BpRefBase(remote)

{

}


在BpInterface的构造函数中,再一次以传入的BpBinder为参数调用其父类BpRefBase的构造方法。BpInterface继承自IServiceManager和BpRefBase, BpRefBase位于frameworks/native/include/binder/Binder.h中,代码如下:


class BpRefBase:public virtual RefBase

{

……

inline IBinder*remote(){return mRemote;}

inline IBinder*remote()const{return mRemote;}

private:

BpRefBase(const BpRefBase&o);

BpRefBase&operator=(const BpRefBase&o);

IBinder*const mRemote;//将BpBinder存入mRemote

RefBase:weakref_type*mRefs;

volatile int32_t mState;

};


由以上分析可知,IServiceManager:asInterface(new BpBinder(0))最终将BpBinder存入了BpServiceManager的父类BpRefBase的私有变量mRemote中。父类提供了remote方法用于返回该变量。