在基于Binder通信的C/S架构体系中,除了C/S架构所包括的Client端和Server端外,Android还有一个全局的ServiceManager端,它的作用是管理系统中的各种服务。Client、Server、ServiceManager这三者之间的关系如下如所示:
根据上图的显示,我们可以得到如下结论:
1. Server进程要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端,而ServiceManager是服务端。
2. 如果某个Client进程要使用某个Service,必须先到ServiceManager中获取该Service的相关信息,所以Client是ServiceManager的客户端。
3. Client根据得到的Service信息与Service所在的Server进程建立通信链路,然后就可以直接和Service交互了,所以Client也是Server的客户端。
4. 三者之间的交互都是基于Binder通信的。
前面的文章我们已经分析了下ServiceManager的实现,那么我们今天主要借助MediaServer来分析下Server是怎么向ServiceManager注册服务并实现两者之间的通信的。
和ServiceManager一样,MediaServer也是由init进程在初始化时根据init.rc配置文件来启动的。
service media /system/bin/mediaserver class main user media group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm ioprio rt 4
Mediaserver的代码主要在frameworks\av\media\mediaserver\main_mediaserver.cpp中实现:
int main(int argc, char** argv) { …… sp<ProcessState> proc(ProcessState::self()); // 获得ServiceManager的实例 sp<IServiceManager> sm = defaultServiceManager(); // Mediaserver进程承载了好几个服务 AudioFlinger::instantiate(); MediaPlayerService::instantiate(); CameraService::instantiate(); AudioPolicyService::instantiate(); registerExtensions(); // 开始循环接收消息 ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool();}
上面的代码看似还挺简单的,但是其中蕴含了很多的知识点,我们一个个来逐一击破。
首先我们来看下sp<ProcessState> proc(ProcessState::self());这行代码。
sp<ProcessState> ProcessState::self() { Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess; }
如上所示,Self函数采用了单例模式,每个进程只有一个ProcessState对象。
Self函数最后new了一个ProcessState对象出来,那么我们再来看看其构造函数:
ProcessState::ProcessState() : mDriverFD(open_driver()) // open_driver打开binder驱动 , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) { // XXX Ideally, there should be a specific define for whether we // have mmap (or whether we could possibly have the kernel module // availabla). #if !defined(HAVE_WIN32_IPC) // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); close(mDriverFD); mDriverFD = -1; } #else mDriverFD = -1; #endif } LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); }
ProcessState的构造函数其实很简单,主要是调用open_driver函数来打开binder驱动,并调用mmap来映射一块内存出来接收数据。
static int open_driver() { // 打开/dev/binder设备 int fd = open("/dev/binder", O_RDWR); if (fd >= 0) { fcntl(fd, F_SETFD, FD_CLOEXEC); int vers; // 获取binder驱动的版本 status_t result = ioctl(fd, BINDER_VERSION, &vers); if (result == -1) { ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); close(fd); fd = -1; } // #define BINDER_CURRENT_PROTOCOL_VERSION 7 // 如果binder驱动版本不等于7,那么就返回失败 if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { ALOGE("Binder driver protocol does not match user space protocol!"); close(fd); fd = -1; } // 设置binder的最大支持线程数为15 size_t maxThreads = 15; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1) { ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); } } else { ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); } return fd; }
至此,ProcessState::self()函数分析完了,它主要干的事情如下:
1. 打开/dev/binder设备,这就相当于与内核的binder驱动建立了交互的通道。
2. 对于返回的fd使用mmap,这样binder驱动就会分配一块内存用来传递数据。
3. 由于ProcessState具有唯一性,因此一个进程只能打开设备一次。
defaultServiceManager函数返回一个IserviceManager的对象。通过这个对象,我们就能和远程的ServiceManager进程建立交互连接了。
sp<IServiceManager> defaultServiceManager() { if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); while (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); if (gDefaultServiceManager == NULL) sleep(1); } } return gDefaultServiceManager; }
感情这个对象也是个单例啊。首先来看看ProcessState::self()->getContextObject的实现:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) { // 这个调用返回的是Ibinder对象,注意此处参数为0 return getStrongProxyForHandle(0); }
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); /* ProcessState类内部维护了一个vector,名为mHandleToObject, 主要用来记录该进程中的proxy服务。 lookupHandleLocked就是根据handle索引值来找到这个proxy服务。 如果没有该服务,那么就新插入一个。 注意,此处handle值为0,还记得ServiceManager有一个magic object的 值也为0,其实此处是和ServiceManager对应的。 */ handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { // 第一次进来,刚插入的项e->binder为NULL IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) { /* 像MediaPlayerService这样的服务,本身会有ServiceManager 来管理其死活。 但是如果handle为0,即要和ServiceManager建立连接,那么 我们只能先ping一下ServiceManager,看看sm是否有回应。 */ Parcel data; status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, NULL, 0); if (status == DEAD_OBJECT) return NULL; } // new了一个BpBinder 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; }
在上述代码中,我们看到new了一个BpBinder对象,那么它到底是干什么的呢?在介绍BpBinder之前,我们有必要先来介绍它的孪生兄弟BBinder。
BpBinder和BBinder都是Android中和Binder通信相关的代表,他们都是从IBinder类中派生而来,如下图所示:
由上图可知:
1. BpBinder是客户端用来与Server交互的代理类,p即proxy的意思。
2. BBinder则是与proxy相对的一端,它是proxy交互的目的端。如果说proxy代表客户端,那么BBinder则代表服务端。这里的BpBinder和BBinder是一一对应的关系。
再来看看BpBinder的构造函数:
BpBinder::BpBinder(int32_t handle) : mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(NULL) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle); }
从上面的代码中可以看到BpBinder的构造很简单,既然BpBinder和BBinder是binder通信中的重要组件,这里却没有看到操作ProcessState打开的那个/dev/binder设备,换言之,这两个Binder类并没有和binder设备直接交互。
我们再来回顾下前面的调用:
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
现在这个调用可以被简化成如下语句:
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
注意:我们给BpBinder构造函数传的参数handle的值为0。这个0在整个Binder系统中有重要含义,因为0代表的就是ServiceManager所对应的BBinder。
那么又是如何将BpBinder*类型强制转化成IServiceManager*类型的呢?答案就在interface_cast的实现中。
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
看来这个interface_cast仅仅是个模板函数,所以interface_cast<IServiceManager>等价于:
inline sp< IServiceManager > interface_cast(const sp<IBinder>& obj) { return IServiceManager::asInterface(obj); }
前面我们说到,BpBinder和BBinder是与通信业务相关的,但是又没看到BpBinder与底层设备直接的通信。秘密都在IServiceManager中,让我们来看看IServiceManager的定义。
class IServiceManager : public IInterface { public: DECLARE_META_INTERFACE(ServiceManager); /** * Retrieve an existing service, blocking for a few seconds * if it doesn't yet exist. */ virtual sp<IBinder> getService( const String16& name) const = 0; /** * Retrieve an existing service, non-blocking. */ virtual sp<IBinder> checkService( const String16& name) const = 0; /** * Register a service. */ virtual status_t addService( const String16& name, const sp<IBinder>& service, bool allowIsolated = false) = 0; /** * Return list of all existing services. */ virtual Vector<String16> listServices() = 0; enum { GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, CHECK_SERVICE_TRANSACTION, ADD_SERVICE_TRANSACTION, LIST_SERVICES_TRANSACTION, }; };
如上所述,IServiceManager类定义了ServiceManager所提供的服务。例如,获取服务、添加服务等等。
继续来看DECLARE_META_INTERFACE宏的实现
#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(); \
DECLARE_META_INTERFACE(ServiceManager);展开之后如下:
// 定义了descriptor字符串 static const android::String16 descriptor; // 定义函数asInterface static android::sp<IServiceManager > asInterface(const android::sp<android::IBinder>& obj); //定义getInterfaceDescriptor函数,应该是返回上述descriptor字符串 virtual const android::String16& getInterfaceDescriptor() const; // 定义构造函数和析构函数 IServiceManager (); virtual ~IServiceManager ();
由上可知,DECLARE宏主要用来定义类的一些函数,变量等。那么与其对应的IMPLEMENT宏主要用来实现上述的定义。
IServiceManager中,IMPLEMENT宏的使用如下:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
再来看看IMPLEMENT_META_INTERFACE宏的实现:
#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() { } \
展开如下:
// 赋值字符串descriptor为android.os.IServiceManager const android::String16 IServiceManager::descriptor(“android.os.IServiceManager”); // getInterfaceDescriptor的实现 const android::String16& IServiceManager::getInterfaceDescriptor() const { return IServiceManager::descriptor; } // 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; } // 构造和析构函数的实现 IServiceManager:: IServiceManager () { } IServiceManager::~ IServiceManager(){ }
分析到这里,我们明白了interface_cast是如何把一个BpBinder对象转换成一个IServiceManager指针的。主要实现在asInterface函数中,关键代码为如下一句:
intr = new BpServiceManager (obj);
在这里,利用BpBinder对象作为参数又新建了一个BpServiceManager对象。
来看看IServiceManager类的家族图谱:
由上图可知:
1. IServiceManager、BpServiceManager、BnServiceManager都与业务逻辑相关。
2. BnServiceManager同时从IServiceManager和BBinder派生,表明它可以直接参与Binder通信。
3. BpServiceManager虽然从BpInterface类中派生,但是这条分支似乎与BpBinder没有关系。
4. BnServiceManager是一个虚类,它的业务函数最终需要子类来实现,例如图中的MyServiceManager。
BpServiceManager派生自BpInterface和IServiceManager,并没有像它兄弟BnServiceManager一样直接派生自Binder相关的类。那么它是怎么与BpBinder联系的呢?
BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { }
template<typename INTERFACE> inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) { }
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL), mState(0) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); if (mRemote) { mRemote->incStrong(this); // Removed on first IncStrong(). mRefs = mRemote->createWeak(this); // Held for our entire lifetime. } }
原来是BpServiceManager类中有一个名为mRemote的变量,它指向BpBinder对象。
至此,前面的defaultServiceManager函数执行后,我们得到如下两个关键对象:
1. 有一个BpBinder对象,它的handle值为0。
2. 有一个BpServiceManager对象,它的mRemote值为上述BpBinder对象。
BpServiceManager对象继承自IServiceManager,因此它有IServiceManager的所有业务函数。现在又有BpBinder作为通讯的代表,那么接下来的工作就简单了。我们继续分析MediaPlayerService的工作原理。