在这篇文章中,我们将深入剖析一下Android系统的服务管理员ServiceManager。
ServiceManager是Android系统服务的管理者。所有需要通过Binder机制进行进程间通信的进程都要首先获得Service Manager的代理对象才能进行Binder通讯。比如系统中有用于音频混音的AudioFlingerService,用于照相的CameraService,用于媒体文件播放的MediaPlayerService。所有这些服务都会向ServiceManager注册,因此ServiceManager就维护了系统中所有服务的一个列表。任何应用程序要想使用这些服务,首先要向ServiceManager请求获得这些服务的引用,从而建立起和这些服务的联系。
在本系列的第一篇文章中,ExampleService通过如下语句向系统注册服务。
这里有两个问题:
1. defaultServiceManager()都完成了哪些工作,它返回的结果是什么?
2. 为什么调用上一步返回对象的addService方法,就可以向系统注册服务?这一注册过程都完成了哪些工作?
这篇文章先回答问题1。
ServiceManager也是系统中的一个服务,那么应用程序如何和它取得联系呢?答案就是通过defaultServiceManager()函数。defaultServiceManager()是系统在Android命名空间中定义的一个全局函数,用来获得ServiceManager的代理对象的引用。我们看一下该函数的源代码。
gDefaultServiceManager在libutil中定义,因此任何程序或库使用了libutil库都会有该变量,它在一个进程中是唯一的。gDefaultServiceManager的初始值为NULL,所以先调用ProcessState::self()方法获取一个ProcessState实例。这里用到了Singleton的设计模式,从而可知一个进程只有一个ProcessState实例。
view plain copy to clipboard print ?
-
- sp<ProcessState> ProcessState::self()
- {
- if (gProcess != NULL) return gProcess;
-
- AutoMutex _l(gProcessMutex);
- if (gProcess == NULL) gProcess = new ProcessState;
- return gProcess;
- }
该ProcessState会打开/dev/binder设备供IPCThreadState使用。查看其构造函数便知。
view plain copy to clipboard print ?
-
- ProcessState::ProcessState()
- : mDriverFD(open_driver())
- , mVMStart(MAP_FAILED)
- , mManagesContexts(false)
- , mBinderContextCheckFunc(NULL)
- , mBinderContextUserData(NULL)
- , mThreadPoolStarted(false)
- , mThreadPoolSeq(1)
- {
- if (mDriverFD >= 0) {
-
-
-
- #if !defined(HAVE_WIN32_IPC)
-
- mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
- if (mVMStart == MAP_FAILED) {
-
- LOGE("Using /dev/binder failed: unable to mmap transaction memory./n");
- close(mDriverFD);
- mDriverFD = -1;
- }
- #else
- mDriverFD = -1;
- #endif
- }
- if (mDriverFD < 0) {
-
- }
- }
再看一下open_driver()方法的源代码。
view plain copy to clipboard print ?
-
- static int open_driver()
- {
- if (gSingleProcess) {
- return -1;
- }
-
- int fd = open("/dev/binder", O_RDWR);
- if (fd >= 0) {
- fcntl(fd, F_SETFD, FD_CLOEXEC);
- int vers;
- #if defined(HAVE_ANDROID_OS)
- status_t result = ioctl(fd, BINDER_VERSION, &vers);
- #else
- status_t result = -1;
- errno = EPERM;
- #endif
- if (result == -1) {
- LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
- close(fd);
- fd = -1;
- }
- if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
- LOGE("Binder driver protocol does not match user space protocol!");
- close(fd);
- fd = -1;
- }
- #if defined(HAVE_ANDROID_OS)
- size_t maxThreads = 15;
- result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
- if (result == -1) {
- LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
- }
- #endif
-
- } else {
- LOGW("Opening '/dev/binder' failed: %s/n", strerror(errno));
- }
- return fd;
- }
open_driver()方法打开binder设备(/dev/binder),获取binder版本号,设定最大线程个数,并返回binder设备的文件描述符。内核空间中分配约1M的连续空间(BINDER_VM_SIZE)给进程,并用mmap函数映射到进程的用户空间。该空间用于transaction交互数据用。
回到defaultServiceManager()方法。我们可以看到defaultServiceManager()是调用ProcessState对象的getContextObject方法获得ServiceManager的代理对象。我们再看一下getContextObject函数的源代码:
view plain copy to clipboard print ?
-
- sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
- {
- if (supportsProcesses()) {
- return getStrongProxyForHandle(0);
- } else {
- return getContextObject(String16("default"), caller);
- }
- }
因为支持binder驱动(supportsProcesses()函数会判断binder驱动是否打开,以此来检验是否支持binder),这里是以0为参数调用getStrongProxyForHandle()方法获得ServiceManager的代理对象。我们再看一下getStrongProxyForHandle()方法的源代码:
view plain copy to clipboard print ?
-
- sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
- {
- sp<IBinder> 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;
- }
getStrongProxyForHandle()首先调用lookupHandleLocked()方法查找当前进程是否维护的Service代理对象的列表。我们再看一下lookupHandleLocked()方法的源代码。
view plain copy to clipboard print ?
-
- ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
- {
- const size_t N=mHandleToObject.size();
- if (N <= (size_t)handle) {
- handle_entry e;
- e.binder = NULL;
- e.refs = NULL;
- status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
- if (err < NO_ERROR) return NULL;
- }
- return &mHandleToObject.editItemAt(handle);
- }
mHHandleToObject是一个以handle_entry类型为元素的Vector,维护当前进程的代理对象列表。其索引就是每个代理对象句柄的值。比如ServiceManager对应的句柄肯定是0,那么它就是这个列表的第1项。如果待查询的的句柄的值大于等于当前列表的大小,说明待创建的Service代理对象条目尚未在当前进程中创建,那么就需要插入新项。当前的列表大小是N,索引从0至N-1,如果待查询的索引是handle,那么就要插入handle-(N-1)项。如果该代理对象条目已经创建过了,那么直接返回其引用就可以了。
注:这里的“创建”只是在列表中创建相应的条目(e.binder = NULL;e.refs = NULL;),真正的代理对象要在稍后才创建。
现在回到getStrongProxyForHandle()方法。如果该代理对象尚未创建(e->binder==NULL),那么就创建一个,并更新代理对象列表中的相应记录。
我们再来看一下BpBinder类的构造函数做了什么。
view plain copy to clipboard print ?
-
- 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);
- }
这里调用了IPCThreadState类的incWeakHandle()方法来增加引用计数。我们再看看incWeakHandle()方法的源代码。
view plain copy to clipboard print ?
-
- void IPCThreadState::incWeakHandle(int32_t handle)
- {
- LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)/n", handle);
- mOut.writeInt32(BC_INCREFS);
- mOut.writeInt32(handle);
- }
这里incWeakHandle()在输出缓冲区增加了一条BC_INCREFS命令。
如果该handle对应的代理对象已经创建过了,那么就增加它的引用计数。result是一个指向IBinder类型的强指针。Android系统中定义了sp(strong pointer)和wp(weak pointer)两种智能指针。注意这里的操作符"="已经被重载了。force_set是RefBase类专门为ProcessState类优化的一个方法,让我们看一下它的源代码。
view plain copy to clipboard print ?
-
- template<typename T>
- void sp<T>::force_set(T* other)
- {
- other->forceIncStrong(this);
- m_ptr = other;
- }
设定好引用计数之后,getStrongProxyForHandle()方法返回代理对象的句柄。接下来会通过interface_cast将其转换为IserviceManager类型。我们来看看这个转换是怎么实现的。
view plain copy to clipboard print ?
- gDefaultServiceManager = interface_cast<IServiceManager>(
- ProcessState::self()->getContextObject(NULL));
interface_cast<IServiceManager>,其实调用的是IServiceManager.asInterface方法:
view plain copy to clipboard print ?
-
- template<typename INTERFACE>
- inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
- {
- return INTERFACE::asInterface(obj);
- }
查看IServiceManager的源文件,好像并没有定义asInterface方法。不要急,我们先看一下IServiceManager的定义:
view plain copy to clipboard print ?
-
- class IServiceManager : public IInterface
- {
- public:
- DECLARE_META_INTERFACE(ServiceManager);
-
-
-
-
-
- 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) = 0;
-
-
-
-
- virtual Vector<String16> listServices() = 0;
-
- enum {
- GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
- CHECK_SERVICE_TRANSACTION,
- ADD_SERVICE_TRANSACTION,
- LIST_SERVICES_TRANSACTION,
- };
- };
这里的宏DECLARE_META_INTERFACE在IInterface.h头文件中定义如下:
view plain copy to clipboard print ?
-
- #define DECLARE_META_INTERFACE(INTERFACE) /
- static const String16 descriptor; /
- static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); /
- virtual const String16& getInterfaceDescriptor() const; /
- I##INTERFACE(); /
- virtual ~I##INTERFACE(); /
这里,我们终于找到了asInterface方法的声明。该方法是通过在IServiceManager.cpp文件中的IMPLEMENT_META_INTERFACE宏来实现的。
view plain copy to clipboard print ?
-
- IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
IMPLEMENT_META_INTERFACE宏定义如下:
view plain copy to clipboard print ?
-
- #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> I##INTERFACE::asInterface(const sp<IBinder>& obj) /
- { /
- 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() { } /
将上面这些宏展开后的最终结果就是,
view plain copy to clipboard print ?
- sp<IServiceManager> IServiceManager::asInterface(const sp<IBinder>& obj)
- {
- 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::asInterface()函数最终会用一个IBinder对象创建一个BpServiceManager对象,并将它返回。
好了,现在我们总结一下获取ServiceManager代理对象的全部过程:
defaultServiceManager(); // 获取ServiceManager代理对象
{
interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL)); // 将返回的BpBinder类型的代理对象转换成ServiceManager类型的代理对象
{
getStrongProxyForHandle(0); // 以0为参数即可获得ServiceManager的代理对象
{
lookupHandleLocked(0);
b = new BpBinder(0); // 新建一个代理对象
返回根据handle生成的代理对象
}
返回根据handle生成的代理对象
}
返回转换成ServiceManager类型的代理对象
}
最后,我们可以回答问题1了:
问题: defaultServiceManager()都完成了哪些工作,它返回的结果是什么?
答: 如果当前进程已经生成了ServiceManager的代理对象,那么该函数返回它的一个引用;如果当前进程还没有生成过ServiceManager的代理对象,那么创建它,并返回它的一个引用。
我们将在下篇文章中深入剖析为什么调用该引用指向的getService方法就可以获得ExampleService的代理对象的引用。