Bindr机制-向ServiceManager添加服务

本文将详细介绍Android系统中如何往ServiceManager中添加服务,当然还是以MediaPlayerService服务为例子。

在前文已经说明了,Android系统中的所有Service对外提供服务时,都需要先注册到ServiceManager,由其进行统一的服务管理。这将导致在注册前,首先就需要和ServiceManager进行IPC通信,而ServiceManager也是一个服务,只不过这个服务比较特殊而已(服务代理的引用句柄为0)。

在注册前,需要和ServiceManager通信,所以首先需要获得ServiceManager的Binder代理才能与其进行通信。
路径:Main_mediaserver.cpp (av\media\mediaserver)

sp<IServiceManager> sm(defaultServiceManager());

这条语句用户获取ServiceManager服务的Binder代理,defaultServiceManager()接口最终返回一个指向IServiceManager的智能指针(自己灵活回收内存)。函数展开如下:

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
        // 获取指向IServiceManager的智能指针
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}

此函数中最为关键的一句就是如下:

gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));

此函数主要调用了两个接口interface_cast<IServiceManager>()ProcessState::self()->getContextObject(NULL)
ProcessState::self()接口函数在Binder机制-ProcessState过程一文中有详细的介绍,这里不再展开讲述。其功能就是获取本进程中的唯一ProcessState对象,是一个单例模式的。
最终就是调用getContextObject(NULL)接口,参数传入NULL,其实最终返回一个BpBinder(0)对象,此函数体如下:

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

接着调用getStrongProxyForHandle(0)接口函数,句柄0代表ServiceManager的Binder代理引用。

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
    handle_entry* e = lookupHandleLocked(handle);
    if (e != NULL) {
        // 如果当前没有一个binder代理,则需要创建一个,或者我们不能够获取一个弱引用binder的情况下
        // 如果要了解更多详细信息,可以去看看关于getWeakProxyForHandle()接口的评论
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            b = new BpBinder(handle); //使用Binder代理句柄0去创建一个BpBinder,如果是BpHwBinder情况一样
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // 当自身没有一个,而另外一个server发送了一个handle的情况下,允许我们去添加一个远程代理的强引用
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }
    return result;
}

而lookupHandleLocked(handle)接口函数第一次一般返回一个值为空的handle_entry结构体,如下:

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) { // handle = 0, 如果在mHandleToObject中有数据,一般不会进入
        handle_entry e;
        e.binder = NULL; //就算进入也是创建一个值为空的的handle_entry 
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return NULL;
    }
    return &mHandleToObject.editItemAt(handle); //从此Vector<handle_entry> mHandleToObject中获取 handle_entry 
}

所以最终还是会调用 b = new BpBinder(handle);这一句去生成一个handle = 0的Binder的代理,也是ServiceManager的Binder代理,接着调用interface_cast<IServiceManager>()把BpBinder(0)做为一个参数传入其中,最后转换成一个sp<IServiceManager>并赋值给gDefaultServiceManager全局变量,这样可以直接和ServiceManager进行通信了。

// 是一个STL模板,INTERFACE为IServiceManager
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

参数obj = BpBinder(0),转换为:

inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
    return IServiceManager::asInterface(obj); //调用了IServiceManager的asInterface接口
}

IServiceManager::asInterface(obj)接口函数是在
IMPLEMENT_META_INTERFACE(ServiceManager, “android.os.IServiceManager”);实现的。

::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;                                                    
}

前面说过obj=BpBinder(0),调用其queryLocalInterface( “android.os.IServiceManager”),最终调用到IBinder,如下:

sp<IInterface>  IBinder::queryLocalInterface(const String16& /*descriptor*/)
{
    return NULL;
}

返回NULL,则生成一个BpServiceManager(obj = BpBinder(0)),与ServiceManager通信的Binder代理创建成功后,回归本文的主题,向它添加service,即在函数:

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService());
}

调用了ServiceManager的addService(String16("media.player"), new MediaPlayerService()),这也是一个RPC过程。服务的名字为“media.player”,服务的实例为MediaPlayerService(),而MediaPlayerService的继承关系是继承BBinder的,在Binder机制概述一文中有详细框图介绍。
addService()接口的函数体如下:

virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated)
{
     Parcel data, reply;
     // 写入ServiceManager的接口描述符"android.os.IServiceManager"
     data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); 
     data.writeString16(name);   //需要注册的服务的服务名
     // 需要注意这个地方,在parcel数据结构中写入一个BBindr,也是Binder的响应实体,会进行扁平化处理的 
     data.writeStrongBinder(service); 
     data.writeInt32(allowIsolated ? 1 : 0);
     status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
     return err == NO_ERROR ? reply.readExceptionCode() : err;
}

remote()实际调用到BpRefBase的remote()接口,返回mRemote.

class BpRefBase : public virtual RefBase
{
protected:
    inline  IBinder* remote() { return mRemote; }
    inline  IBinder* remote() const { return mRemote; }
}

mRemote实际是BpBinder(0),由构造函数传入的。

BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{}

 explicit BpServiceManager(const sp<IBinder>& impl)
    : BpInterface<IServiceManager>(impl)
{}

则调用的是BpBinder(0)->transact(ADD_SERVICE_TRANSACTION, data, &reply)接口,展开的是:

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }
    return DEAD_OBJECT;
}

最终还是调用到IPCThreadState::self()->transact()接口函数,这个接口及IPCThreadState::self()在我的另外一篇博文Binder机制-IPCThreadState过程中有详细的介绍过程,这里不做展开分析。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值