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

在基于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 mediadrm
ioprio 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;

// 定义函数asInterface
static 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.IServiceManager
const 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Binder 机制Android 系统中的一种进程间通信(IPC)机制,用于在不同的进程之间传递数据和调用方法。它是 Android 系统中最重要的 IPC 机制之一,也是 Android 应用程序与系统服务进行通信的基础。 Binder 机制的工作原理是基于一个抽象的客户端-服务器模型。在 Binder 机制中,有三种角色:客户端、服务器和服务管理器。客户端和服务器在不同的进程中运行,而服务管理器运行在系统服务进程中。 当客户端需要与服务器通信时,它首先通过服务管理器获取服务器的引用。服务管理器通过一个名为 Binder 驱动的内核模块来实现进程间通信。客户端可以通过跨进程访问服务器对象来调用服务器上的方法,并将参数传递给服务器。服务器可以将结果返回给客户端。 Binder 机制的一个重要特性是它支持跨进程的对象引用。这意味着客户端可以获取服务器上的对象引用,并将其传递给其他进程中的客户端。通过这种方式,多个客户端可以共享服务器上的相同对象,并相互协作。 在 Android 应用程序中,开发者可以通过 AIDL(Android 接口定义语言)来定义客户端和服务器之间的接口。AIDL 可以生成一个 Java 接口和一个 C++ 接口,用于在客户端和服务器之间进行通信。 总之,Android Binder 机制Android 系统中用于进程间通信的核心技术之一。它提供了一种高效、灵活和安全的方式来在不同的进程之间传递数据和调用方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值