servicemanager作为一个守护进程在开机时被启动,此后就可以说servicemanager的服务端已经就绪,其它服务(如MediaService等具体服务)就可以向servicemanager注册自己了,为了实现和servicemanager的交付,在libbinder库中也为servicemanager提供了客户端(即代理部分),相关核心类就是下图中的IServiceManager和BpServiceManager。
这篇笔记就来分析servicemanager代理端的典型流程实现。
// client通过IServiceManager和servicemanager通信,通过该接口获取BpServiceManager(IServiceManager的子类)对象
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL)
return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
// IServiceManager是根据BpBinder对象构造出来的,这里的interface_cast转换也很关键
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
全局的gDefaultServiceManager表示每个进程只会持有一个BpServiceManager对象指针,实际上也只需要有一个该对象。有两步核心操作:
// 获取BpBinder对象
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
// 参数0非常重要,指定了要获取的服务的句柄,0表示servicemanager
return getStrongProxyForHandle(0);
}
// 当前进程持有的所有其它service的句柄
Vector<handle_entry>mHandleToObject;
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
// 获取或者新建handle对应的handle_entry
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
// Special case for context manager...
// The context manager is the only object for which we create
// a BpBinder proxy without already holding a reference.
// Perform a dummy transaction to ensure the context manager
// is registered before we create the first local reference
// to it (which will occur when creating the BpBinder).
// If a local reference is created for the BpBinder when the
// context manager is not present, the driver will fail to
// provide a reference to the context manager, but the
// driver API does not return status.
//
// Note that this is not race-free if the context manager
// dies while this code runs.
//
// TODO: add a driver API to wait for context manager, or
// stop special casing handle 0 for context manager and add
// a driver API to get a handle to the context manager with
// proper reference counting.
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
// 创建BpBinder对象
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
整个过程的核心在BpBinder::create(),创建一个BpBinder对象,传入的handle为0,0特指servicemanager。
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
对应到这里就是IServiceManager::asInterface(),该函数并没有直接实现,libbinder提供了两个宏,其中包含了该函数的实现,这两个宏分别为DECLARE_META_INTERFACE()和IMPLEMENT_META_INTERFACE()。这两个宏的展开过程不再细述,直接看最终的结果:
::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) {
// 返回的就是BpServiceManager对象,obj就是包装了0句柄的BpBinder对象
intr = new BpServiceManager(obj);
}
}
return intr;
}
一般,服务注册过程如下面的示例代码所示(来自BinderService::publish()):
// 向系统注册服务
static status_t publish(bool allowIsolated = false, int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT)
{
// 获取BpServiceManager对象
sp<IServiceManager> sm(defaultServiceManager());
// 调用addService()方法,前两个入参分别为服务名字和服务对象指针
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpFlags);
}
addService()是由BpServiceManager实现的。
virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority)
{
Parcel data, reply;
// 向servicemanager发送该调用请求
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
// 要注册的服务信息
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
data.writeInt32(dumpsysPriority);
// 调用BpBinder中的transact()
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
remote()函数是BpServiceManager从BpRefBase中继承来的,返回的就是封装了server端句柄的BpBinder对象指针。
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
// 调用的是IPCThreadState中的transact()
status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
最后通过IPCThreadState中的transact()将要传递给servicemager的数据写入binder驱动。
客户端要想调用服务端提供的接口,首先要获取服务端的代理,这是通过BpServiceManager::getService()实现的。
// 入参就是服务的名字
virtual sp<IBinder> getService(const String16& name) const
{
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
// 判断是否是厂商自己实现的binder驱动
const bool isVendorService = strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
const long timeout = uptimeMillis() + 5000;
if (!gSystemBootCompleted) {
char bootCompleted[PROPERTY_VALUE_MAX];
property_get("sys.boot_completed", bootCompleted, "0");
gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false;
}
// retry interval in millisecond.
const long sleepTime = gSystemBootCompleted ? 1000 : 100;
// 最多等待5s,获取封装了服务端句柄的BpBinder对象
int n = 0;
while (uptimeMillis() < timeout) {
n++;
if (isVendorService) {
ALOGI("Waiting for vendor service %s...", String8(name).string());
CallStack stack(LOG_TAG);
} else if (n%10 == 0) {
ALOGI("Waiting for service %s...", String8(name).string());
}
usleep(1000*sleepTime);
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
}
ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
return NULL;
}
如上,实际调用的是checkService():
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}