Android Binder原理(二)ServiceManager中的Binder机制

关联系列
Android AOSP基础系列
Android系统启动系列
应用进程启动系列
Android深刻四大组件系列
Android深刻理解Context系列
Android深刻理解JNI系列
Android解析WindowManager
Android解析WMS系列
Android解析AMS系列
Android包管理机制系列
Android输入系统系列前端

本文首发于微信公众号「后厂村码农」android

前言

在上一篇文章中,咱们了解了学习Binder前必需要了解的知识点,其中有一点就是Binder机制的三个部分:Java Binder、Native Binder、Kernel Binder,其中Java Binder和Native Binder都是应用开发须要掌握的。Java Binder是须要借助Native Binder来工做的,所以须要先了解Native Binder,Native Binder架构的原型就是基于Binder通讯的C/S架构,所以咱们先从它开始入手。源码是基于Android 9.0。程序员

1.基于Binder通讯的C/S架构

在Android系统中,Binder进程间的通讯的使用是很广泛的,在Android进阶三部曲第一部的最后一章,我讲解了MediaPlayer框架,这个框架基于C/S架构,并采用Binder来进行进程间通讯,以下图所示。 微信

uZgTgJ.png

从图中能够看出,除了常规C/S架构的Client端和Server端,还包括了ServiceManager,它用于管理系统中的服务。 首先Server进程会注册一些Service到ServiceManager中,Client要使用某个Service,则须要先到ServiceManager查询Service的相关信息,而后根据Service的相关信息与Service所在的Server进程创建通讯通路,这样Client就可使用Service了。架构

2.MediaServer的main函数

Client、Server、ServiceManager三者的交互都是基于Binder通讯的,那么任意二者的交互均可以说明Binder的通讯的原理,能够说Native Binder的原理的核心就是ServiceManager的原理,为了更好的了解ServiceManager,这里拿MediaPlayer框架来举例,它也是学习多媒体时必需要掌握的知识点。框架

MediaPlayer框架的简单框架图以下所示。 函数

uMegMj.png
能够看到,MediaPlayer和MediaPlayerService是经过Binder来进行通讯的,MediaPlayer是Client端,MediaPlayerService是Server端,MediaPlayerService是系统多媒体服务的一种,系统多媒体服务是由一个叫作MediaServer的服务进程提供的,它是一个可执行程序,在Android系统启动时,MediaServer也被启动,它的入口函数以下所示。 frameworks/av/media/mediaserver/main_mediaserver.cpp

int main(int argc __unused, char **argv __unused) {
    signal(SIGPIPE, SIG_IGN);
    //获取ProcessState实例
    sp<ProcessState> proc(ProcessState::self());//1
    sp<IServiceManager> sm(defaultServiceManager());//2
    ALOGI("ServiceManager: %p", sm.get());
    InitializeIcuOrDie();
    //注册MediaPlayerService
    MediaPlayerService::instantiate();//3
    ResourceManagerService::instantiate();
    registerExtensions();
    //启动Binder线程池
    ProcessState::self()->startThreadPool();
    //当前线程加入到线程池
    IPCThreadState::self()->joinThreadPool();
}
复制代码

注释1处用于获取ProcessState实例,在这一过程当中会打开/dev/binder设备,并使用mmap为Binder驱动分配一个虚拟地址空间用来接收数据。 注释2处用来获得一个IServiceManager,经过这个IServiceManager,其余进程就能够和当前的ServiceManager进行交互,这里就用到了Binder通讯。 注释3处用来注册MediaPlayerService。 除了注释3处的知识点在下一篇文章进行介绍,注释1和注释2处的内容,本篇文章会分别来进行介绍,先看ProcessState实例。学习

3.每一个进程惟一的ProcessState

ProcessState从名称就能够看出来,用于表明进程的状态,先来查看上一小节的ProcessState的self函数。 frameworks/native/libs/binder/ProcessState.cppthis

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");//1
    return gProcess;
}
复制代码

这里采用了单例模式,确保每一个进程只有一个ProcessState实例。注释1处用于建立一个ProcessState实例,参数为/dev/binder。接着来查看ProcessState的构造函数,代码以下所示。 frameworks/native/libs/binder/ProcessState.cppspa

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))//1
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);//2
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
复制代码

ProcessState的构造函数中调用了不少函数,须要注意的是注释1处,它用来打开/dev/binder设备。 注释2处的mmap函数,它会在内核虚拟地址空间中申请一块与用户虚拟内存相同大小的内存,而后再申请物理内存,将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间,实现了内核虚拟地址空间和用户虚拟内存空间的数据同步操做,也就是内存映射。 mmap函数用于对Binder设备进行内存映射,除了它还有open、ioctl函数,来看看它们作了什么。 注释1处的open_driver函数的代码以下所示。 frameworks/native/libs/binder/ProcessState.cpp

static int open_driver(const char *driver) {
    int fd = open(driver, O_RDWR | O_CLOEXEC);//1
    if (fd >= 0) {
        ...
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);//2
        if (result == -1) {
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
        }
    } else {
        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
    }
    return fd;
}
复制代码

注释1处用于打开/dev/binder设备并返回文件操做符fd,这样就能够操做内核的Binder驱动了。注释2处的ioctl函数的做用就是和Binder设备进行参数的传递,这里的ioctl函数用于设定binder支持的最大线程数为15(maxThreads的值为15)。最终open_driver函数返回文件操做符fd。

ProcessState就分析倒这里,总的来讲它作了如下几个重要的事: 1.打开/dev/binder设备并设定Binder最大的支持线程数。 2.经过mmap为binder分配一块虚拟地址空间,达到内存映射的目的。

4.ServiceManager中的Binder机制

回到第一小节的MediaServer的入口函数,在注释2处调用了defaultServiceManager函数。 frameworks/native/libs/binder/IServiceManager.cpp

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));//1
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}
复制代码

从IServiceManager所在的文件路径就能够知道,ServiceManager中不只仅使用了Binder通讯,它自身也是属于Binder体系的。defaultServiceManager中一样使用了单例,注释1处的interface_cast函数生成了gDefaultServiceManager,其内部调用了ProcessState的getContextObject函数,代码以下所示。 frameworks/native/libs/binder/ProcessState.cpp

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

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
    handle_entry* e = lookupHandleLocked(handle);//1
    if (e != NULL) {
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            b = BpBinder::create(handle);//2
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

复制代码

getContextObject函数中直接调用了getStrongProxyForHandle函数,注意它的参数的值为0,那么handle的值就为0,handle是一个资源标识。注释1处查询这个资源标识对应的资源(handle_entry)是否存在,若是不存在就会在注释2处新建BpBinder,并在注释3处赋值给 handle_entry的binder。最终返回的result的值为BpBinder。

4.1 BpBinder和BBinder

说到BpBinder,不得不提到BBinder,它们是Binder通讯的“双子星”,都继承了IBinder。BpBinder是Client端与Server交互的代理类,而BBinder则表明了Server端。BpBinder和BBinder是一一对应的,BpBinder会经过handle来找到对应的BBinder。 咱们知道在ServiceManager中建立了BpBinder,经过handle(值为0)能够找到对应的BBinder。

usIeXQ.png

分析完了ProcessState的getContextObject函数,回到interface_cast函数:

gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
复制代码

interface_cast具体实现以下所示。 frameworks/native/libs/binder/include/binder/IInterface.h

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

当前的场景中,INTERFACE的值为IServiceManager,那么替换后代码以下所示。

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

咱们接着来分析IServiceManager。

4.2 解密IServiceManager

BpBinder和BBinder负责Binder的通讯,而IServiceManager用于处理ServiceManager的业务,IServiceManager是C++代码,所以它的定义在IServiceManager.h中。 frameworks/native/libs/binder/include/binder/IServiceManager.h

class IServiceManager : public IInterface
{
public:
    DECLARE_META_INTERFACE(ServiceManager)//1
    ...
    //一些操做Service的函数
    virtual sp<IBinder>         getService( const String16& name) const = 0;
    virtual sp<IBinder>         checkService( const String16& name) const = 0;
    virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated = false, int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
    virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;
    enum {
        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        CHECK_SERVICE_TRANSACTION,
        ADD_SERVICE_TRANSACTION,
        LIST_SERVICES_TRANSACTION,
    };
};
复制代码

能够看到IServiceManager继承了IInterface,其内部定义了一些常量和一些操做Service的函数,在注释1处调用了DECLARE_META_INTERFACE宏,它的定义在IInterface.h中。 frameworks/native/libs/binder/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();     
复制代码

其中INTERFACE的值为ServiceManager,那么通过替换后的代码以下所示。

static const ::android::String16 descriptor;       
    //定义asInterface函数
    static ::android::sp<IServiceManager> asInterface(                    
            const ::android::sp<::android::IBinder>& obj);            
    virtual const ::android::String16& getInterfaceDescriptor() const;  
    //定义IServiceManager构造函数
    IServiceManager();          
    //定义IServiceManager析构函数
    virtual ~IServiceManager();     
复制代码

从DECLARE_META_INTERFACE宏的名称和上面的代码中,能够发现它主要声明了一些函数和一个变量。那么这些函数和变量的实如今哪呢?答案仍是在IInterface.h中,叫作IMPLEMENT_META_INTERFACE宏,代码以下所示/ frameworks/native/libs/binder/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() { }                                   \
复制代码

DECLARE_META_INTERFACE宏和IMPLEMENT_META_INTERFACE宏是配合使用的,不少系统服务都使用了它们,IServiceManager使用IMPLEMENT_META_INTERFACE宏只有一行代码,以下所示。 frameworks/native/libs/binder/IServiceManager.cpp

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
复制代码

IMPLEMENT_META_INTERFACE宏的INTERFACE值为ServiceManager,NAME值为"android.os.IServiceManager",进行替换后的代码以下所示。

const ::android::String16 IServiceManager::descriptor("android.os.IServiceManager");          
    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);//1 
            }                                                           
        }                                                               
        return intr;                                                    
    }                                                                   
    IServiceManager::IServiceManager() { }                                    
    IServiceManager::~IServiceManager() { }                                   
复制代码

关键的点就在于注释1处,新建了一个BpServiceManager,传入的参数obj的值为BpBinder。看到这里,咱们也就明白了,asInterface函数就是用BpBinder为参数建立了BpServiceManager,从而推断出interface_cast函数建立了BpServiceManager,再往上推断,IServiceManager的defaultServiceManager函数返回的就是BpServiceManager。 BpServiceManager有什么做用呢,先从BpServiceManager的构造函数看起。 frameworks/native/libs/binder/IServiceManager.cpp

class BpServiceManager : public BpInterface<IServiceManager>
{
public:
    explicit BpServiceManager(const sp<IBinder>& impl)
        : BpInterface<IServiceManager>(impl)
    {
    }
...
}
复制代码

impl的值其实就是BpBinder,BpServiceManager的构造函数调用了基类BpInterface的构造函数。 frameworks/native/libs/binder/include/binder/IInterface.h

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
...
};
复制代码

BpInterface继承了BpRefBase,BpRefBase的实现以下所示。 frameworks/native/libs/binder/Binder.cpp

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

    if (mRemote) {
        mRemote->incStrong(this);           
        mRefs = mRemote->createWeak(this);  
    }
}
复制代码

mRemote是一个IBinder* 指针,它最终的指向为BpBinder,也就是说BpServiceManager的mRemote指向了BpBinder。那么BpServiceManager的做用也就知道了,就是它实现了IServiceManager,而且经过BpBinder来实现通讯。

4.3 IServiceManager家族

可能上面讲的会让你有些头晕,这是由于对各个类的关系不大明确,经过下图也许你就会豁然开朗。

ufWhRI.png

1.BpBinder和BBinder都和通讯有关,它们都继承自IBinder。 2.BpServiceManager派生自IServiceManager,它们都和业务有关。 3.BpRefBase包含了mRemote,经过不断的派生,BpServiceManager也一样包含mRemote,它指向了BpBinder,经过BpBinder来实现通讯。

5.小节

本篇文章咱们学到了Binder通讯的C/S架构,也知道了Native Binder的原理的核心其实就是ServiceManager的原理,为了讲解ServiceManager的原理,咱们须要一个框架来举例,那就是MediaPlayer框架。在讲解MediaServer的入口函数时,咱们遇到了三个问题,其中前两个问题相关的知识点ProcessState和IServiceManager都讲解到了,下一篇文章会讲解第三个问题,MediaPlayerService是如何注册的。


这里不只分享大前端、Android、Java等技术,还有程序员成长类文章。

相关文章
相关标签/搜索