servicemanager的客户端代理: BpServiceManager

servicemanager作为一个守护进程在开机时被启动,此后就可以说servicemanager的服务端已经就绪,其它服务(如MediaService等具体服务)就可以向servicemanager注册自己了,为了实现和servicemanager的交付,在libbinder库中也为servicemanager提供了客户端(即代理部分),相关核心类就是下图中的IServiceManager和BpServiceManager。
在这里插入图片描述
这篇笔记就来分析servicemanager代理端的典型流程实现。

  1. 获取servicemanager代理对象;
  2. 注册服务;
  3. 获取服务;

获取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对象指针,实际上也只需要有一个该对象。有两步核心操作:

  1. ProcessState::self()->getContextObject(NULL);
  2. interface_cast<IServiceManager>();

getContextObject()

// 获取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。

interface_cast<IServiceManager>()

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();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值