Binder native层源码分析(一):media_service的启动

本篇文章分析mediaserver的启动过程中获取servicemanager以及注册服务的过程。希望这篇文章能够帮助大家弄清楚系统服务对BpBinder的封装过程,同时为之后分析Binder通信过程做好通信数据上的准备,即让大家知道Binder通信中发送的数据内容是什么。

我们从media server的主函数开始。

main_mediaserver

//\frameworks\av\media\mediaserver\main_mediaserver.cpp
int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm(defaultServiceManager());//获取service manager
    ALOGI("ServiceManager: %p", sm.get());
    InitializeIcuOrDie();
    MediaPlayerService::instantiate();//注册服务
    ResourceManagerService::instantiate();
    registerExtensions();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

总结一下就是获取service manager并向其发送注册请求后,进入线程池循环。这里我们只要看service manager是怎么获取的,以及注册服务的流程即可。

defaultServiceManager获取sm业务封装类

defaultServiceManager的作用是返回service manager的业务封装类。

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

首次调用defaultSericeManager()时,该函数首先会调用ProcessState::self()->getContextObject(NULL),然后将返回结果传给模板函数interface_cast()。

getContextObject()的作用是返回ServiceManager的通信代理类BpBinder,而interface_cast()的作用是将BpBinder封装在业务类BpServiceManager中。可以这样理解这两个类,BpBinder负责完成通信工作,也就是将传进来的数据发送给ServiceManager。而BpServiceManager实现业务函数,也就是根据业务需要构造不同的数据包,然后调用BpBinder相关函数发送。用于通信的还有另外一个类BBinder,关于它的功能我们之后再介绍。

getContextObject得到sm的BpBinder

我们看getContextObject做了什么。

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

以0为参数调用了getStrongProxy。

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);
//从ProcessState的vector成员mHandleToObject找到handle值对应的handle_entry
    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        IBinder* b = e->binder;
        //如果handle_entry的Ibinder成员还未赋值
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {//传进来的参数为0,会进入这个分支
                Parcel data;
                //向service manager发送测试数据
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }

            b = new BpBinder(handle); //由handle值构造BpBinder
            e->binder = b;//放进handle_entry中。
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;//返回BpBinder(handle)
}

总结一下就是构造了根据handle值构造BpBinder,放进ProcessState的vector成员mHandleToObject中,并且返回该BpBinder。

里面特别注意的有两个点,第一个点是传进来的参数handle。handle值标识了一个服务端,Binder驱动就是根据该值来找到通信目标的。另一个点就是handle值构造的BpBinder,它是Binder通信代理类(我一直不理解什么是代理类),完成通信工作。

另外,这里传进来的handle值为0,代表service manager。一般而言,对所有进程来说,service manager的handle值都为0。知道服务端的handle值之后才能构造BpBinder来发送Binder通信数据。这里已经构造了service manager的BpBinder,之后便可以向service manager请求服务,例如请求得到其它服务的handle值。

interface_cast封装BpBinder

在defaultServiceManager中,通过getContextObject获取BpBinder后,将其传给了interface_cast进行封装,最终返回一个IServiceManager类。

// \frameworks\native\include\binder\IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

所以,defaultServiceManager()中就相当于调用了IServiceManager::asInterface(),然而,在IServiceManager中的头文件和cpp文件中却找不到asInterface(),看了书才知道,其实这个函数的申明是藏在了头文件中的DECLARE_META_INTERFACE(ServiceManager)宏定义里面。而定义藏在cpp文件的IMPLEMENT_META_INTERFACE(ServiceManager, “android.os.IServiceManager”)宏定义里面。长见识了。

DECLARE_META_INTERFACE的定义如下:

// \frameworks\native\include\binder\IInterface.h
#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(); 

将ServiceManager代入,就相当于:

static const android::String16 descriptor;                          
static android::sp<IServiceManager> asInterface(                       
    const android::sp<android::IBinder>& obj);                  
virtual const android::String16& getInterfaceDescriptor() const;    
IServiceManager();                                                     
virtual ~IServiceManager(); 

IMPLEMENT_META_INTERFACE的定义如下:

// \frameworks\native\include\binder\IInterface.h
#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() { }                                   \

同理将ServiceManager和"android.os.IServiceManager"代入IMPLEMENT_META_INTERFACE,可以得到:

const android::String16 IServiceManager::descriptor("android.os.IServiceManager");             
const android::String16&                                            
        IServiceManager::getInterfaceDescriptor() const {              
    return IServiceManager::descriptor;                                
}                                                                   
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() { }                        

我们主要关注asInterface()函数,可以看到,这个函数返回的是一个BpServiceManager对象,传入的obj(根据我们之前的分析,obj即是BpBinder指针)用来构造这个BpServiceManager对象。

这两个宏不仅在IServiceManager里面可以找到,在其它服务类比如IMediaPlayer中也能看到,只不过传入DECLARE_META_INTERFACE的参数变成MediaPlayer,传入IMPLEMENT_META_INTERFACE的参数变成MediaPlayer,和"android.media.IMediaPlayer"。所以可以推测,系统中的每一个Service,都有一个Bp+服务名的类,例如BpServiceManager,BpMediaPlayer,而这些类需要用BpBinder指针来构造,而当进行通信时,就是通过这个BpBinder指针调用相关函数来进行的。我们继续看BpServiceManager的构造函数。

我们继续看BpServiceManager的构造函数。

// \frameworks\native\libs\binder\IServiceManager.cpp
BpServiceManager(const sp<IBinder>& impl)
    : BpInterface<IServiceManager>(impl)
{
}

构造函数将BpBinder指针传给了父类BpInterface的构造函数。

// \frameworks\native\include\binder\IInterface.h
//原始定义
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote){}
//代入IServiceManager,注意,代入的不是BpServiceMaNager
inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote){}

BpBinder指针又被传给了父类BpRefBase的构造函数,而在BpRefBase的构造函数中,该值被用来初始化mRemote成员。

service manager获取小结

如图所示:
​​​​​​​​​​​​在这里插入图片描述
最终返回了BpServiceManager(IServiceManager)。其中BpServiceManager的mRemote成员就是BpBinder指针。而BpBinder对应的BBinder又是怎么封装的呢?这里使用《深入理解Android》中的一张图来解释:
在这里插入图片描述
可以看到BBinder直接被业务类BnServiceManager继承。这里需要注意的是BpBinder和BBinder这两个用于通信的类的不同封装方式,一个是作为成员变量封装在业务类中,一个是作为父类被业务类所继承。我们会在后面的文章中具体介绍这两个通信类完成的工作。

另外,虽然我只分析了ServiceManager的封装,但其实几乎所有的系统服务都采用相同的封装方式,它们都有Bp+服务名和Bn+服务名的两个类,继承关系也和上面介绍的基本相同。

MediaPlayerService::instantiate注册服务

//\frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

调用了BpServiceManager的addService。传入的参数是服务名media.player和MediaPlayerService类,在前面的图中我们知道,MediaPlayerService其实是BBinder的继承类。

//\frameworks\native\libs\binder\IServiceManager.cpp
//addService(String16("media.player"), new MediaPlayerService());
virtual status_t addService(const String16& name, const sp<IBinder>& service,
        bool allowIsolated)
{
    Parcel data, reply;
    //将服务名和MediaPlayerService写入Parcel
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    data.writeStrongBinder(service);
    data.writeInt32(allowIsolated ? 1 : 0);
    //在interface_cast分析中我们知道BpServiceManager的remote成员是handle值
    //为0的BpBinder,这里相当于BpBinder->transact。该函数完成数据的发送
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    return err == NO_ERROR ? reply.readExceptionCode() : err;
}

总结一下,addService把服务吗和MediaPlayerService类写进数据包Parcel之后,通过BpBinder->transact发送给了service manager。

本篇文章到此结束。下篇文章将分析Binder中的数据包类Parcel。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值