Android Binder机制浅析之注册MediaPlayerService(1)

来源:互联网 发布:央视1台网络直播电视 编辑:程序博客网 时间:2024/04/29 16:06

在基于Binder通信的C/S架构体系中,除了C/S架构所包括的Client端和Server端外,Android还有一个全局的ServiceManager端,它的作用是管理系统中的各种服务。Client、Server、ServiceManager这三者之间的关系如下如所示:

根据上图的显示,我们可以得到如下结论:

1.      Server进程要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端,而ServiceManager是服务端。

2.      如果某个Client进程要使用某个Service,必须先到ServiceManager中获取该Service的相关信息,所以Client是ServiceManager的客户端。

3.      Client根据得到的Service信息与Service所在的Server进程建立通信链路,然后就可以直接和Service交互了,所以Client也是Server的客户端。

4.      三者之间的交互都是基于Binder通信的。

 

前面的文章我们已经分析了下ServiceManager的实现,那么我们今天主要借助MediaServer来分析下Server是怎么向ServiceManager注册服务并实现两者之间的通信的。

 

MediaServer的启动

和ServiceManager一样,MediaServer也是由init进程在初始化时根据init.rc配置文件来启动的。

service media /system/bin/mediaserver    class main    user media    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrmioprio rt 4

MediaServer的使命

Mediaserver的代码主要在frameworks\av\media\mediaserver\main_mediaserver.cpp中实现:

int main(int argc, char** argv){        ……sp<ProcessState> proc(ProcessState::self());// 获得ServiceManager的实例    sp<IServiceManager> sm = defaultServiceManager();// Mediaserver进程承载了好几个服务AudioFlinger::instantiate();    MediaPlayerService::instantiate();    CameraService::instantiate();    AudioPolicyService::instantiate();registerExtensions();// 开始循环接收消息    ProcessState::self()->startThreadPool();    IPCThreadState::self()->joinThreadPool();}

上面的代码看似还挺简单的,但是其中蕴含了很多的知识点,我们一个个来逐一击破。

 

独一无二的ProcessState

单例ProcessState

首先我们来看下sp<ProcessState> proc(ProcessState::self());这行代码。

sp<ProcessState> ProcessState::self(){    Mutex::Autolock _l(gProcessMutex);    if (gProcess != NULL) {        return gProcess;    }    gProcess = new ProcessState;    return gProcess;}

如上所示,Self函数采用了单例模式,每个进程只有一个ProcessState对象。


ProcessState的构造

Self函数最后new了一个ProcessState对象出来,那么我们再来看看其构造函数:

ProcessState::ProcessState()    : mDriverFD(open_driver())// open_driver打开binder驱动    , mVMStart(MAP_FAILED)    , mManagesContexts(false)    , mBinderContextCheckFunc(NULL)    , mBinderContextUserData(NULL)    , mThreadPoolStarted(false)    , mThreadPoolSeq(1){    if (mDriverFD >= 0) {        // XXX Ideally, there should be a specific define for whether we        // have mmap (or whether we could possibly have the kernel module        // availabla).#if !defined(HAVE_WIN32_IPC)        // mmap the binder, providing a chunk of virtual address space to receive transactions.        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);        if (mVMStart == MAP_FAILED) {            // *sigh*            ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");            close(mDriverFD);            mDriverFD = -1;        }#else        mDriverFD = -1;#endif    }    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");}

ProcessState的构造函数其实很简单,主要是调用open_driver函数来打开binder驱动,并调用mmap来映射一块内存出来接收数据。

 

open_driver打开binder驱动

static int open_driver(){// 打开/dev/binder设备    int fd = open("/dev/binder", O_RDWR);    if (fd >= 0) {        fcntl(fd, F_SETFD, FD_CLOEXEC);        int vers;// 获取binder驱动的版本        status_t result = ioctl(fd, BINDER_VERSION, &vers);        if (result == -1) {            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));            close(fd);            fd = -1;        }// #define BINDER_CURRENT_PROTOCOL_VERSION 7// 如果binder驱动版本不等于7,那么就返回失败        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {            ALOGE("Binder driver protocol does not match user space protocol!");            close(fd);            fd = -1;        }// 设置binder的最大支持线程数为15        size_t maxThreads = 15;        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);        if (result == -1) {            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));        }    } else {        ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));    }    return fd;}

ProcessState::self总结

至此,ProcessState::self()函数分析完了,它主要干的事情如下:

1.      打开/dev/binder设备,这就相当于与内核的binder驱动建立了交互的通道。

2.      对于返回的fd使用mmap,这样binder驱动就会分配一块内存用来传递数据。

3.      由于ProcessState具有唯一性,因此一个进程只能打开设备一次。

 

与ServiceManager建立连接

defaultServiceManager函数返回一个IserviceManager的对象。通过这个对象,我们就能和远程的ServiceManager进程建立交互连接了。

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

感情这个对象也是个单例啊。首先来看看ProcessState::self()->getContextObject的实现:

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){// 这个调用返回的是Ibinder对象,注意此处参数为0    return getStrongProxyForHandle(0);}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){    sp<IBinder> result;    AutoMutex _l(mLock);/*ProcessState类内部维护了一个vector,名为mHandleToObject,主要用来记录该进程中的proxy服务。lookupHandleLocked就是根据handle索引值来找到这个proxy服务。如果没有该服务,那么就新插入一个。注意,此处handle值为0,还记得ServiceManager有一个magic object的值也为0,其实此处是和ServiceManager对应的。*/    handle_entry* e = lookupHandleLocked(handle);    if (e != NULL) {        // 第一次进来,刚插入的项e->binder为NULL        IBinder* b = e->binder;        if (b == NULL || !e->refs->attemptIncWeak(this)) {            if (handle == 0) {/*像MediaPlayerService这样的服务,本身会有ServiceManager来管理其死活。但是如果handle为0,即要和ServiceManager建立连接,那么我们只能先ping一下ServiceManager,看看sm是否有回应。*/                Parcel data;                status_t status = IPCThreadState::self()->transact(                        0, IBinder::PING_TRANSACTION, data, NULL, 0);                if (status == DEAD_OBJECT)                   return NULL;            }// new了一个BpBinder            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;}

BpBinder的构造

在上述代码中,我们看到new了一个BpBinder对象,那么它到底是干什么的呢?在介绍BpBinder之前,我们有必要先来介绍它的孪生兄弟BBinder。

BpBinder和BBinder都是Android中和Binder通信相关的代表,他们都是从IBinder类中派生而来,如下图所示:


由上图可知:

1.      BpBinder是客户端用来与Server交互的代理类,p即proxy的意思。

2.      BBinder则是与proxy相对的一端,它是proxy交互的目的端。如果说proxy代表客户端,那么BBinder则代表服务端。这里的BpBinder和BBinder是一一对应的关系。

 

再来看看BpBinder的构造函数:

BpBinder::BpBinder(int32_t handle)    : mHandle(handle)    , mAlive(1)    , mObitsSent(0)    , mObituaries(NULL){    extendObjectLifetime(OBJECT_LIFETIME_WEAK);    IPCThreadState::self()->incWeakHandle(handle);}

从上面的代码中可以看到BpBinder的构造很简单,既然BpBinder和BBinder是binder通信中的重要组件,这里却没有看到操作ProcessState打开的那个/dev/binder设备,换言之,这两个Binder类并没有和binder设备直接交互。

 

我们再来回顾下前面的调用:

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

现在这个调用可以被简化成如下语句:

gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

注意:我们给BpBinder构造函数传的参数handle的值为0。这个0在整个Binder系统中有重要含义,因为0代表的就是ServiceManager所对应的BBinder


interface_cast的实现

那么又是如何将BpBinder*类型强制转化成IServiceManager*类型的呢?答案就在interface_cast的实现中。

template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){    return INTERFACE::asInterface(obj);}

看来这个interface_cast仅仅是个模板函数,所以interface_cast<IServiceManager>等价于:

inline sp< IServiceManager > interface_cast(const sp<IBinder>& obj){    return IServiceManager::asInterface(obj);}

IServiceManager的构造

前面我们说到,BpBinder和BBinder是与通信业务相关的,但是又没看到BpBinder与底层设备直接的通信。秘密都在IServiceManager中,让我们来看看IServiceManager的定义。

class IServiceManager : public IInterface{public:    DECLARE_META_INTERFACE(ServiceManager);    /**     * Retrieve an existing service, blocking for a few seconds     * if it doesn't yet exist.     */    virtual sp<IBinder>         getService( const String16& name) const = 0;    /**     * Retrieve an existing service, non-blocking.     */    virtual sp<IBinder>         checkService( const String16& name) const = 0;    /**     * Register a service.     */    virtual status_t            addService( const String16& name,                                            const sp<IBinder>& service,                                            bool allowIsolated = false) = 0;    /**     * Return list of all existing services.     */    virtual Vector<String16>    listServices() = 0;    enum {        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,        CHECK_SERVICE_TRANSACTION,        ADD_SERVICE_TRANSACTION,        LIST_SERVICES_TRANSACTION,    };};

如上所述,IServiceManager类定义了ServiceManager所提供的服务。例如,获取服务、添加服务等等。

 

继续来看DECLARE_META_INTERFACE宏的实现

#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();                                            \

DECLARE_META_INTERFACE(ServiceManager);展开之后如下:

// 定义了descriptor字符串static const android::String16 descriptor;// 定义函数asInterfacestatic android::sp<IServiceManager > asInterface(const android::sp<android::IBinder>& obj);                  //定义getInterfaceDescriptor函数,应该是返回上述descriptor字符串virtual const android::String16& getInterfaceDescriptor() const;// 定义构造函数和析构函数IServiceManager ();    virtual ~IServiceManager ();  

由上可知,DECLARE宏主要用来定义类的一些函数,变量等。那么与其对应的IMPLEMENT宏主要用来实现上述的定义。

IServiceManager中,IMPLEMENT宏的使用如下:

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

再来看看IMPLEMENT_META_INTERFACE宏的实现:

#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() { }                                   \

展开如下:

// 赋值字符串descriptor为android.os.IServiceManagerconst android::String16 IServiceManager::descriptor(“android.os.IServiceManager”);// getInterfaceDescriptor的实现const android::String16&                                                       IServiceManager::getInterfaceDescriptor() const {                     return IServiceManager::descriptor;                               }    // asInterface函数的实现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(){ }       

分析到这里,我们明白了interface_cast是如何把一个BpBinder对象转换成一个IServiceManager指针的。主要实现在asInterface函数中,关键代码为如下一句:

intr = new BpServiceManager (obj);

在这里,利用BpBinder对象作为参数又新建了一个BpServiceManager对象。


来看看IServiceManager类的家族图谱:

由上图可知:

1.      IServiceManager、BpServiceManager、BnServiceManager都与业务逻辑相关。

2.      BnServiceManager同时从IServiceManager和BBinder派生,表明它可以直接参与Binder通信。

3.      BpServiceManager虽然从BpInterface类中派生,但是这条分支似乎与BpBinder没有关系。

4.      BnServiceManager是一个虚类,它的业务函数最终需要子类来实现,例如图中的MyServiceManager。

 

BpServiceManager派生自BpInterface和IServiceManager,并没有像它兄弟BnServiceManager一样直接派生自Binder相关的类。那么它是怎么与BpBinder联系的呢?

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

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

BpRefBase::BpRefBase(const sp<IBinder>& o)    : mRemote(o.get()), mRefs(NULL), mState(0){    extendObjectLifetime(OBJECT_LIFETIME_WEAK);    if (mRemote) {        mRemote->incStrong(this);           // Removed on first IncStrong().        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.    }}

原来是BpServiceManager类中有一个名为mRemote的变量,它指向BpBinder对象。

 

至此,前面的defaultServiceManager函数执行后,我们得到如下两个关键对象:

1.      有一个BpBinder对象,它的handle值为0。

2.      有一个BpServiceManager对象,它的mRemote值为上述BpBinder对象。


BpServiceManager对象继承自IServiceManager,因此它有IServiceManager的所有业务函数。现在又有BpBinder作为通讯的代表,那么接下来的工作就简单了。我们继续分析MediaPlayerService的工作原理。









0 0
原创粉丝点击