5.3.2 获取servicemanager的代理对象
Client端查询服务或者Server端注册服务,都要首先获取servicemanager的代理对象,然后通过该代理对象与servicemanager通信完成请求。获取servicemanager的代理对象涉及的类层次结构如图5-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方法用于返回该变量。