码迷,mamicode.com
首页 > 其他好文 > 详细

Binder机制解析

时间:2015-07-13 18:43:24      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:

一、Binder通信流程简单概述
技术分享
技术分享
(一)Binder用以Android内部的进程间通信,Binder相对于传统的Linux内核IPC(管道,信号,消息队列,共享内存,插口等)具有仅需拷贝一次内存的好处,进而提高了效率,也节省了内存;
    从设计模式来看,Binder通信可以抽象为上图C/S模式,数据通信流程已经足够清晰。从中可以看出:
1、Client组件获得Service组件的代理接口(Proxy),来对Service进行操作;(代理可以类比于办理证件,比如证件中心在北京,而不可能所有人办理证件都要过去北京办理;证件中心则在全国都设立了代理点,在代理点进行相应的操作即可,可以享受到在证件中心一样的服务。)
2、进程间的通信数据采用Parcel进行传输,Client进程调用Proxy的方法,Proxy将Client请求数据打包成Parcel发送给Binder驱动程序,Binder再转发给Server;
Binder驱动程序在内核中,Server接收到Binder发送来的parcel进行解析,然后处理相应的请求。请求处理完成后,则会将处理结果如图返回;
3、可以看到Client进程在等待请求处理结果时,会阻塞;即整个通信过程是个同步过程;(系统中也存在异步事务)

(二)Binder在用户空间中有三个重要的组件:Client,Server,ServerManager;
技术分享
    由图可以看出,Client,Server,ServiceManager(SM)都运行在用户空间,Binder驱动程序在运行在内核空间;虚线表示:Client与Service组件由应用程序来提供,SM与Binder由系统提供;Service Manager是一个守护进程,用来管理Server,并向Client提供查询Server接口的能力。

(三)一些名词:
* Client进程:访问服务的进程;          Service进程:提供服务的进程
* Service组件:同一个Server进程可以运行多个组件来为Client提供服务
* Client组件: 同一个Client进程可以向多个Server组件请求服务,每个请求对应一个Clinet组件;
* Binder线程池: 每一个Server,Binder进程都维护一个Binder线程池来处理Binder请求
* ServiceManager:Binder通信机制的上下文管理者(context_manager

<一> Service端:

二、以MediaService为例分析
(一)涉及组件:

*  ServiceManager,这是Android OS的整个服务的管理程序

*  MediaService,这个程序里边注册了提供媒体播放的服务程序MediaPlayerService,我们最后只分析这个

 MediaPlayerClient,这个是与MediaPlayerService交互的客户端程序


(二)MediaService:(源码基于Android 5.1):
地址:\frameworks\av\media\mediaserver\main_mediaserver.cpp
(注意Android 2.3在frameworks/base/media/mediaserver/main_mediaserver.cpp)

using namespace android;
 
int main(int argc __unused, char** argv)
{
    // 获取一个ProcessState实例
    sp<ProcessState> proc(ProcessState::self());
    // 一个ServiceManager实例
    sp<IServiceManager> sm = defaultServiceManager();
    /** 启动一些所需的Service服务**/
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();// 初始化MediaPlayerService服务
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    SoundTriggerHwService::instantiate();
    registerExtensions();
    // ProcessState开辟线程池
    ProcessState::self()->startThreadPool();
    // IPCThreadState加入到线程池
    IPCThreadState::self()->joinThreadPool();
}

sp是Android中的智能指针,用以管理对象生命周期;上面涉及到的函数一一来看:


(三)ProcessState:
************************************第一步*************************************************
1、ProcessState::self():用以获取一个ProcessState实例

/** \frameworks\native\libs\binder\ProcessState.cpp
 *  2.3在framework\base\libs\binder\ProcessState.cpp*/
// 很明显的单例模式
sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState;
    return gProcess;
}
很明显的单例模式,保证ProcessState是进程唯一的。


2、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) {
#if !defined(HAVE_WIN32_IPC)
    // mmap 把指定内存块(这里即mDriverFD)映射到应用程序的内存空间中
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            //...差错控制
        }
#else
        mDriverFD = -1;
#endif
    }
 
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}
在创建一个ProcessState实例时,open_driver()打开了Binder驱动,然后执行了mmap;


3、打开驱动函数open_driver():

static int open_driver()
{
    int fd = open("/dev/binder", O_RDWR);  // RW方式打开/dev/binder设备,具体打开信息暂时不关注
    if (fd >= 0) {
        fcntl(fd, F_SETFD, FD_CLOEXEC);
        int vers = 0;
        // 与Binder驱动通信正是使用ioctl函数来实现
        status_t result = ioctl(fd, BINDER_VERSION, &vers); // 获取Binder版本
        ...
        size_t maxThreads = 15;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); // 设置Binder线程池最大线程数(这里为15)
        ...
    } else {
        ...
    }
    return fd;
}

   通过open()打开/dev/binder设备,获取设备描述符fd,并进行了简单设置。

4、mmap内存映射,将binder设备映射到应用程序内存空间,使得仅需进行一次拷贝就能够执行类似write/read操作。

主函数main()中的第一步ProcessState执行完,下面一步是获取一个ServiceManager实例。

(四)获取SM实例
************************************第二步*************************************************
1、defaultServiceManager():

/** \frameworks\native\libs\binder\IServiceManager.cpp*/
sp<IServiceManager> defaultServiceManager()
{
    // 也是单例模式
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
 
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
        // 创建一个ServiceManager,可以看出又回到ProcessState中调用getContextObject函数
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
 
    return gDefaultServiceManager;
}
    可以看出也是单例模式,SM进程只需要存在一个,所有Client与Server均与之通信;


2、回到ProcessState::getContextObject():
/** \frameworks\native\libs\binder\ProcessState.cpp */
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    // 字面上翻译为通过Handle值来获得Proxy代理
    return getStrongProxyForHandle(0);
}
    由于SM的handle(可以理解为资源索引)值为0,故getStrongProxyForHandle传入的参数为0;

3、getStrongProxyForHandle():

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
 
    // 通过handle的值查询获得存储数组中对应的资源handle_entry,如果不存在该hanle,则创建一个;
    // 后面附有 lookupHandleLocked的源码:
    handle_entry* e = lookupHandleLocked(handle);
    /** 看一下获取到的handle_entry的结构,可以看到获取到想要的Binder(IBinder)
     * struct handle_entry {
        IBinder* binder;--->Binder
        RefBase::weakref_type* refs;-->和引用计数相关.
     };
     * */
 
    if (e != NULL) {
        IBinder* b = e->binder; // 由于是新创建的,b明显为NULL
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
              // transact是个重要函数,这里暂且不提
                Parcel data;
                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;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        }
        ...
    }
 
    return result;// 返回的即是new BpBinder(handle)
}
 

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = NULL;
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return NULL;
    }
    return &mHandleToObject.editItemAt(handle);
}
   最后得到的返回结果为一个BpBinder实例,回顾1,2,3步简单调度关系,即整个调度过程可以简化成:

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


    BpBinder主要功能是负责client向BD(Binder Driver)发送调用请求的数据。它是client端binder通信的核心对象,通过调用transact函数向BD发送调用请求的数据;下面看一下BpBinder;

(五) BpBinder:
1、上面用构造函数创建一个BpBinder实例,看下BpBinder构造函数:

/** \frameworks\native\libs\binder\BpBinder.cpp */
BpBinder::BpBinder(int32_t handle)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)
{
    // 均和引用计数相关,相关知识为智能指针
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);  // 表示对象的生命周期同时受强引用计数和弱引用计数的影响
    IPCThreadState::self()->incWeakHandle(handle); // 这里终于引出了重要的IPCThreadState实例
}

2、又引出一个重要类——IPCThreadState,明显看出它也是一个单例模式:

先总结一下获取到的诸多类之间的关系,如下图所示:

技术分享

实际与BD进行命令通信的是IPCThreadState,它是线程唯一的;可以看到所有的通信都是基于BD的。

3、IPCThreadState::self():

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
IPCThreadState* IPCThreadState::self()
{
    /** TLS是Thread Local Storage,(Android中对Java中的TLS进行了优化),
     *  作用是保证对象线程唯一,且别的线程访问的只是该线程的对象数据的复本,互不干扰
     *  Handler,Looper里面也涉及到了该机制,来保证每一个线程Looper唯一**/
    if (gHaveTLS) {  // 第一次进来为false
restart:  // 源码里面好多goto函数啊
        const pthread_key_t k = gTLS;
        // 通过键值gTLS获取该Thread对应的IPCThreadState
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        //下面即为单例模式
        if (st) return st;
        returnnew IPCThreadState; // 后面继续进行分析IPCThreadState构造函数
    }
 
    if (gShutdown) return NULL;
 
    // 锁保护
    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {   // 第一次进来
    // TLS机制为对象在该Thread中创建相对应的key gTLS(可以类比一个空的键值对)
        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart; // goto:创建完key后,然后跳回上面
}
    可以看到使用TLS机制来保证IPCThreadState对象是线程唯一的(从类名也可以明显看出);上面整个函数也无非是一个单例模式实现。


4、下面看IPCThreadState的构造函数:

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),  // 看到这里与ProcessState实例联系到一起(ProcessState是进程唯一的)
      mMyThreadId(androidGetTid()),    // 设置Thread ID
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    pthread_setspecific(gTLS, this);   // TLS机制,存储键值对
    clearCaller();
    /** mIn, mOut是两个Parcel,用于存储接收/发送给BD的命令数据的
     *  这里最大容量设置为了256
     * 
     *  mIn,mOut数据结构中几个重要内部变量:
     *  mData指向内存地址,表示Parcel所包含数据在内存中的起始地址
     *  mDataSize指当前parcel已经有的数据量
     *  mDataPos指当前已经处理过得数据量
     *  其具体内存中的关系如下面附图所示:
     *  */
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

技术分享

    然后再回到这番流程的原点即BpBinder的构造函数 new BpBinder(handle)执行完成;
    回到最初总结的:
    gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
中来;

下面看一下创建的BpBinder是如何强制转化成为IServiceManager的;

(六)IServiceManager:
1、interface_cast定义在IInterface类中:

/** \frameworks\native\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);
}


2、然后再IServiceManager中并未找到相应的asInterface方法,先看一下其定义:

/** \frameworks\native\include\binder\IServiceManager.h*/
namespace android {
 
class IServiceManager : public IInterface
{
public:
    /** 学习过MFC知道,由DECLARE就会有相应的IMPLEMENT,
     *  这两个宏一个声明在.h中,一个声明在.cpp中*/
    DECLARE_META_INTERFACE(ServiceManager);
    /**
     * Register a service.
     */
    virtual status_t            addService( const String16& name,
                                            const sp<IBinder>& service,
                                            bool allowIsolated = false) = 0;
    ....
};

/** \frameworks\native\libs\binder\IServiceManager.cpp*/
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");


3、看一下两个宏的定义:
1)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();                                            \


   注意I##INTERFACE这种用法,应用在宏中,#define Conn(str) str##MyName 即连接前后两个数据

  IServiceManager的应用环境下,调用为:DECLARE_META_INTERFACE(ServiceManager);

则上面宏可以修改为函数:

static const android::String16 descriptor;        // -->增加一个描述字符串
static android::sp< IServiceManager > asInterface(
        const android::sp<android::IBinder>&obj)  // --》增加一个asInterface函数
virtual const android::String16& getInterfaceDescriptor() const; // --》增加一个get函数,估计其返回值就是descriptor这个字符串
// 增加构造函数和析构函数
IServiceManager ();                                                     virtual~IServiceManager();

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

    由调用:IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

如上转化为函数实现为:

const android::String16 IServiceManager::descriptor("android.os.IServiceManager");
 
const android::String16& IServiceManager::getInterfaceDescriptor() const
{
    return IServiceManager::descriptor; //返回上面那个android.os.IServiceManager
}
 
/** 这里清晰得获取到了所需要的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) {
            // 这里创建了一个新的类实例 BpServiceManager
            intr = new BpServiceManager(obj);
        }
    }
    return intr;
}
 
IServiceManager::IServiceManager() {}
IServiceManager::~IServiceManager() {}
由上面得到了所需要的IServiceManager.asInterface函数,分析可知最终创建的IServiceManager对象其实为:   

    static_cast<IServiceManager *>(new BpServiceManager(new BpBinder(0)))

这里又引出一个类BpServiceManager:

(六)BpServiceManager:
1、BpServiceManager中B知Binder,p指proxy即代理;BpServiceManager就是指SM的Binder代理(Proxy)。其定义在IServiceManager.cpp中:

/** \frameworks\native\libs\binder\IServiceManager.cpp*/
// ----------------------------------------------------------------------
/** 由后面给出的BpInterface的定义可以,BpInterface是继承INTERFACE(即这里的IServiceManager),
 *  可以知道BpServiceManager是继承BpInterface与IServiceManager的*/
class BpServiceManager : public BpInterface<IServiceManager>
{
public:
    // 这里构造函数为空,可知均交给父类去处理了,转而去看一下BpInterface的构造函数
    BpServiceManager(const sp<IBinder>& impl)
        : BpInterface<IServiceManager>(impl)
    {
    }
 
    /*** 这里重写了IServiceManager中的一些Service函数,具体细节暂且不提,记住有这些函数
     *   之案件的数据通信等具体情况时再做分析**/
    virtual sp<IBinder> getService(const String16& name) const
    {
        unsigned n;
        for (n = 0; n < 5; n++){
            sp<IBinder> svc = checkService(name);
            if (svc != NULL) return svc;
            sleep(1);
        }
        return NULL;
    }
 
    virtual sp<IBinder> checkService(const String16& name) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
        return reply.readStrongBinder();
    }
 
    virtual status_t addService(const String16& name, const sp<IBinder>& service,
            bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        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;
    }
 
    virtual Vector<String16> listServices()
    {
        Vector<String16> res;
        int n = 0;
 
        for (;;) {
            Parcel data, reply;
            data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
            data.writeInt32(n++);
            status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
            if (err != NO_ERROR)
                break;
            res.add(reply.readString16());
        }
        return res;
    }
};


2、下面来看BpInterface:
1)先看一下其声明:

/** \frameworks\native\include\binder\IInterface.h*/
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
                       BpInterface(constsp<IBinder>& remote);
 
protected:
    virtual IBinder*   onAsBinder();
};
   可以看出其是继承INTERFACE类以及BpRefBase类(又多了一个新类,看名称应该与引用计数相关);


2)看其构造函数:

/** \frameworks\native\include\binder\IInterface.h*/
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
// 这里是委托构造函数,委托父类 BpRefBase去实例化(注这里的IBinder又换成了名字remote)
{
}
 
template<typenameINTERFACE>
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
    // 从前面就一直出现的remote()函数一直没看到定义,可以想到一定是定义在父类BpRefBase中
    return remote();
}


3)有前面分析知需要继续往前面走,去看其父类BpRefBase:

/** \frameworks\native\include\binder\Binder.h*/
// 看到其果然继承了RefBase,表示其与智能指针相关
class BpRefBase : public virtual RefBase
{
protected:
                            // 用到的构造函数
                            BpRefBase(const sp<IBinder>& o);
    virtual                 ~BpRefBase();
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(constvoid* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, constvoid* id);
 
                            // 一直在寻找的remote()函数
    inline  IBinder*        remote()                { return mRemote; }
    inline  IBinder*        remote() const          { return mRemote; }
 
private:
                            BpRefBase(constBpRefBase& o);
    BpRefBase&              operator=(constBpRefBase& o);
 
    IBinder* const          mRemote;       // 可以看到返回的依然是IBinder
    RefBase::weakref_type*  mRefs;
    volatile int32_t        mState;
};



再看一下前面我们所用到的构造函数:

/** \frameworks\native\libs\binder\Binder.cpp*/

BpRefBase::BpRefBase(const sp<IBinder>& o)

    : mRemote(o.get()), mRefs(NULL), mState(0) // 在这个构造函数中对返回值mRemote进行了初始化

/** osp<IBinder>类型,是智能指针,get是智能指针获取其中实际类型的方法,即这里是用以获取IBinder*/

{

    /** 与智能指针相关操作*/

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

 

    if (mRemote) {

        mRemote->incStrong(this);           // Removed on first IncStrong().

        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.

    }

}


    则这里所做的一切就是用o即

new BpBinder(0),去初始化IBinder mRemote变量;


总结一下前面所有的调用流程:

  gDefaultServiceManager = static_cast<IServiceManager *>(new BpServiceManager(new BpBinder(0)))

    即回到最终的起点main函数里面的第二步获取一个SM实例:
  sp<IServiceManager> sm = defaultServiceManager();
实际上获取到的是BpServiceManager,其中有个重要的mRemote变量(通过remote()获取)是BpBinder.

    前面涉及到的一些类之间的继承关系可以总结为下图:
技术分享
    该图是Client组件的实现原理;
    一般IXXXX类表示Service与Client组件都要实现的服务接口,
    BnXXX(n--native)与BpXXX(p--proxy)分别表示Service与Client组件要继承的Binder本地对象类,和Binder代理对象类。


************************************第三步*************************************************
三、MediaPlayerService:
    上面MediaService主main函数中第二步中获取SM终于研究完毕,回到原来的main函数:

/** \frameworks\av\media\mediaserver\main_mediaserver.cpp*/
int main(int argc __unused, char** argv)
{
    // 获取一个ProcessState实例
    sp<ProcessState> proc(ProcessState::self());
    // 一个ServiceManager实例
    sp<IServiceManager> sm = defaultServiceManager();
    /** 启动一些所需的Service服务**/
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();// 初始化MediaPlayerService服务
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    SoundTriggerHwService::instantiate();
    registerExtensions();
    // ProcessState开辟线程池
    ProcessState::self()->startThreadPool();
    // IPCThreadState加入到线程池
    IPCThreadState::self()->joinThreadPool();
}
    到这里完成了打开/dev/binder,进行了内存映射mmap,获取到BpServiceManager实例,下面MediaPlayerService对实例化:


(一)看一下MediaPlayerService的实例化函数instantiate():

/** \frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp*/
void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}
  可以看到,这里涉及到两个重要的事项——1、创建MediaPlayerService实例

   2、defaultServiceManager()是前面所提到的BpServiceManager,前面解析时BpServiceManager接触到过它的几个Service操作。
1)先看MediaPlayerService的构造函数:

/** \frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp*/
MediaPlayerService::MediaPlayerService()
{
    ALOGV("MediaPlayerService created");
    mNextConnId = 1;
 
    /** 下面是电源管理相关的操作,暂且不看**/
    mBatteryAudio.refCount = 0;
    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
        mBatteryAudio.deviceOn[i] = 0;
        mBatteryAudio.lastTime[i] = 0;
        mBatteryAudio.totalTime[i] = 0;
    }
    // speaker is on by default
    mBatteryAudio.deviceOn[SPEAKER] = 1;
 
    // reset battery stats
    // if the mediaserver has crashed, battery stats could be left
    // in bad state, reset the state upon service start.
    const sp<IServiceManager> sm(defaultServiceManager());
    if (sm != NULL) {
        const String16 name("batterystats");
        sp<IBatteryStats> batteryStats =
                interface_cast<IBatteryStats>(sm->getService(name));
        if (batteryStats != NULL) {
            batteryStats->noteResetVideo();
            batteryStats->noteResetAudio();
        }
    }
 
    MediaPlayerFactory::registerBuiltinFactories();
}
2)再看其继承关系:

/** \frameworks\av\media\libmediaplayerservice\MediaPlayerService.h*/
class MediaPlayerService : public BnMediaPlayerService
    看到MediaPlayerService是继承BnMediaPlayerService,前面已经介绍过BnXXX表示(Binder Native)Binder本地对象类,显然其余BpXXX应该是相对应存在的;即创建了一个proxy代理,本地端也应该有一个相对应的native与其打交道。


    前面分析中得到的BpServiceManager,以及现在的BnMediaPlayerService;从名称来看两者明显是不相对应,还应继续往下分析;
instantiate()函数表示创建一个BnMediaPlayerService,并将其addService,即注册到系统中的服务列表中;ServiceManager则是Service的管理者,即系统的所有Service度需要由ServiceManage去管理;所以创建BnMediaPlayerService实例后,需要将其添加到SM中,需要与SM进行通信,而进行通信即是获取到SM的代理Proxy——即这里的BpServiceManager。

3)转而继续看addService的代码,在前面解析BpServiceManager时便接触到该函数:

/** \frameworks\native\libs\binder\IServiceManager.cpp*/
virtual status_t addService(const String16& name, const sp<IBinder>& service,
           bool allowIsolated)
{
   /** 这里只是SM的代理,要处理具体的事务明显应该还是有对应的Bn端存在
    *  data(Parcel)则是发送给BnServiceManager的数据包*/
   Parcel data, reply;
   // 将IServiceManager的描述符即"android.os.IServiceManager"写入data
   data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
   // name即Service的名称
   data.writeString16(name);
   // 将service实体添加进来(这个情景下即是BnMediaPlayerService)
   data.writeStrongBinder(service);
  
   data.writeInt32(allowIsolated ? 1 : 0);
   // 前面分析的remote即是创建的BpBinder,这里会调用其transact来发送数据,并将返回数据保存到reply中
   status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
   return err == NO_ERROR ? reply.readExceptionCode() : err;
}
    这里引出了数据传输函数transact();下面继续来分析得:



(二)transact函数:
    前面分析知最终调用了mRemote的transact函数,mRemote是BpBinder,下面继续来看BpBinder->transact():

/** \frameworks\native\libs\binder\BpBinder.cpp*/
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
    // 可以看到BpBinder是调用前面提到的IPCThreadState的transact函数来实现通信的
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }
 
    return DEAD_OBJECT;
}
    BpBinder的transact是通过IPCThreadState(线程私有)的transact来实现的;IPCThreadState::self()前面已经提到是获取到IPCThreadState的一个实例,再转而看IPCThreadState:


1、transact函数:

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    // data 即是前面BpServiceManager发送来的parcel data,首先对其进行错误监测
    status_t err = data.errorCheck();
    flags |= TF_ACCEPT_FDS;
    ...
    if (err == NO_ERROR) {
    /** transact首先要整理数据,通过writeTransactionData来完成,将其
     * 打包成Binder驱动协议规定的格式
     * 注意这里并未发送数据,只是整理数据*/
        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
    }
    ...
   
    if ((flags & TF_ONE_WAY) == 0) {    // 表示是同步事务的情况
        ...
        if (reply) {
        // 这是是等到响应,故发送命令应该在这里实现
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply; // reply为空的话,就初始化一个假的Parcel供使用
            err = waitForResponse(&fakeReply);
        }
        ...
    } else {                           // 异步事务
        err = waitForResponse(NULL, NULL);
    }
   
    return err;
}

    这里又引出两个函数:

1> writeTransactionData:这个函数只是整理数据,将data数据封装成适合发送的TransactionData
2> waitForResponse:才是发送消息的函数
继续往下看:

2、writeTransactionData:

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    // 这是前面Binder基础数据结构中提到的事务数据结构binder_transaction_data
    binder_transaction_data tr;
 
    // 可以看到下面都是对该结构进行初始化及填充
    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
    tr.target.handle = handle;
    tr.code = code;
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;
   
    const status_t err = data.errorCheck();
    if (err == NO_ERROR) {
        tr.data_size = data.ipcDataSize();
        tr.data.ptr.buffer = data.ipcData();
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
        tr.data.ptr.offsets = data.ipcObjects();
    } elseif (statusBuffer) {
        tr.flags |= TF_STATUS_CODE;
        *statusBuffer = err;
        tr.data_size = sizeof(status_t);
        tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
        tr.offsets_size = 0;
        tr.data.ptr.offsets = 0;
    } else {
        return (mLastError = err);
    }   
    // 填充好数据后将数据写入到mOut缓冲区中,mOut是个Parcel前面已经提到过
    mOut.writeInt32(cmd);
    mOut.write(&tr, sizeof(tr));
   
    return NO_ERROR;
}
    正如前面分析的那样,writeTransactionData函数只是将data数据封装成binder_transaction_data 格式,并且写入到输出缓冲区mOut中。而waitForResponse应该是发送数据到/dev/binder,并与其进行交互的地方。


3、waitForResponse():

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    int32_t cmd;
    int32_t err;
 
    while (1) {
    // talkWithDriver,名称就可以看出是与Driver进行交互
        if ((err=talkWithDriver()) < NO_ERROR) break;
        err = mIn.errorCheck();
        if (err < NO_ERROR) break;
        // 从binder驱动中读取数据存放在mIn中,这里则进行等待读取
        if (mIn.dataAvail() == 0) continue;
 
        // mIn输入缓冲区,读取一个返回cmd命令
        cmd = mIn.readInt32();
        ...
 
        // 下面是针对返回命令进行相应操作
        switch (cmd) {
        case BR_TRANSACTION_COMPLETE:
            if (!reply && !acquireResult) goto finish;
            break;
            ...
        }
    }
    ...
    return err;
}
    waitForResponse所做的工作是通过talkWithDriver函数与Binder驱动进行交互,将mOut缓冲区中的数据发送给BD;然后等待BD返回信息,并读取BD中数据到mIn缓冲区中,通过返回命令进行相应处理。

    来看看talkWithDriver是如何与BD进行通信的:

4、talkWithDriver():

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    /** 注意这里的mProcess,由IPCThreadState构造函数中初始化,
     *  mProcess(ProcessState::self())
     *  mProcess即是ProcessState*/
    if (mProcess->mDriverFD <= 0) {  // 先判断Binder设备是否已经打开
        return -EBADF;
    }
   
    //
    binder_write_read bwr;    // 描述进程间通信过程中所传输的数据,读写操作都是使用该结构
   
    /*** 处理读取mIn缓冲区中的数据,然后赋值给bwr*/
    // 由前面给出的mIn数据处理示意图,可以得出这里实在判断是否还需要进行读取
    constbool needRead = mIn.dataPosition() >= mIn.dataSize();
   
    /** 只有doReceive为true(表示调用者希望被读取),且needRead为false(由前式知道false表示需要读取mIn),
     *  此时outAvail为0,表示不能去写mOut*/
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
   
    // 填写需要wirte的内容和大小
    bwr.write_size = outAvail;
    bwr.write_buffer = (uintptr_t)mOut.data();
 
    // 填写需要read的大小及地址   
    if (doReceive && needRead) {
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (uintptr_t)mIn.data();
    } else {
        bwr.read_size = 0;
        bwr.read_buffer = 0;
    }
   
    // 明显表示不需要read,也不需要write,则直接返回
    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
 
    // 初始化
    bwr.write_consumed = 0; // 记录从缓冲区取了多少字节的数据
    bwr.read_consumed = 0; // 从read_buffer中读取的数据量
    status_t err;
    do {
#if defined(HAVE_ANDROID_OS)
    /** 前面介绍到与binder驱动进行通信使用ioctl函数,BINDER_WRITE_READ用以读写数据,操作的Binder则是mDriverFD*/
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
#else
        err = INVALID_OPERATION;
#endif
        if (mProcess->mDriverFD <= 0) {
            err = -EBADF;
        }
    } while (err == -EINTR);
 
 
    /** 通信完成后,对mIn与mOut做善后处理*/
    if (err >= NO_ERROR) {
        if (bwr.write_consumed > 0) {
            if (bwr.write_consumed < mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
        }
        if (bwr.read_consumed > 0) {
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        return NO_ERROR;
    }
   
    return err;
}
    talkWithDriver所做的工作是将mIn于mOut缓冲区的信息写入到bwr(binder_write_read)中,通过ioctl函数与binder驱动程序进行通信。


    至此transact通信函数分析完毕,回到addService的原点,其间数据流通关系可见下图:
技术分享
技术分享
    第三步 MediaPlayerService::instantiate();获取MediaPlayer的实例分析完毕,这里创建了一个MediaPlayerService实例,并通过BpServiceManager的addService操作,通过BpBinder->IPCInterface的transact,将数据传递给/dev/binder,实现addService操作,将MediaPlayerService信息添加到ServiceManager中。
    主main函数中后面还有两个初始化Binder线程池的操作,暂且略过;

    注意到一个事情,前面通过BpServiceManager将注册数据传递给了binder驱动程序后,后面的事情理论上是应该有一个对应的BnServiceManager来对其继续读取执行,并将执行的请求结果返回回去。但阅读源码,似乎并没由这样一个BnServiceManager存在。实际上有这么一个ServiceManager进程来完成这些请求操作的。
    具体分析见....
    ServiceManager是由init进程启动的,是在系统启动时便启动的,用以处理Service发送来的请求;

为什么需要这样的一个SM存在呢:

    Android系统中Service信息都是先addServiceManager中,由ServiceManager来集中管理,这样就可以查询当前系统有哪些服务。而且,Android系统中某个服务例如MediaPlayerService的客户端Client想要和MediaPlayerService通讯的话,必须先向ServiceManager查询MediaPlayerService的信息,然后通过ServiceManager返回的东西再来和MediaPlayerService交互。

毕竟,要是MediaPlayerService身体不好,老是挂掉的话,客户的代码就麻烦了,就不知道后续新生的MediaPlayerService的信息了,所以只能这样:

*       MediaPlayerServiceSM注册

*       MediaPlayerClient查询当前注册在SM中的MediaPlayerService的信息

*       根据这个信息,MediaPlayerClientMediaPlayerService交互

另外,ServiceManagerhandle标示是0,所以只要往handle0的服务发送消息了,最终都会被传递到ServiceManager中去。


************************************第四步*************************************************
四、BnMediaPlayerService:
    既然MediaPlayerService已经注册到SM的服务列表中,它又是如何处理客户端发来的请求呢。实际上,MediaPlayerService正是BnMediaPlayerService;
由前面对SM的分析知SM的工作原理是有一个binder_loop来循环等待处理发送来的请求。可想而知,BnMediaPlayerService也应当实现类似的机制。

(一)打开/dev/binder与mmap操作:
1、注意BnMediaPlayerService定义在IMediaPlayerService.h中:

/* \frameworks\av\include\media\IMediaPlayerService.h*/
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};
 
}; // namespace android
    其中只实现了一个onTransact函数。同时可以看到BnMediaPlayerService是继承BnInterface的。


2、BnInterface:定义在IIterface.h中:

/* \frameworks\native\include\binder\IInterface.h*/
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(constString16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;
 
protected:
    virtual IBinder*            onAsBinder();
};
   和前面一样的多重继承继承用法,BnInterface同时继承了INTERFACE(现在情况下是IMediaPlayerService),和BBinder;则BnMediaPlayerService同时继承了BnInterface,IMediaPlayerService,以及BBinder.

    
3、下面再来看BBinder:

/** \frameworks\native\include\binder\Binder.h*/
class BBinder : public IBinder
{
public:
                        BBinder();
 
    virtual const String16& getInterfaceDescriptor() const;
    virtual bool        isBinderAlive() const;
    virtual status_t    pingBinder();
    virtual status_t    dump(int fd, const Vector<String16>& args);
 
    virtual status_t    transact(   uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
 
    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
                                    void* cookie = NULL,
                                    uint32_t flags = 0);
 
    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
                                        void* cookie = NULL,
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = NULL);
 
    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
                                        object_cleanup_func func);
    virtual void*       findObject(const void* objectID) const;
    virtual void        detachObject(const void* objectID);
 
    virtual BBinder*    localBinder();
 
protected:
    virtual             ~BBinder();
 
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
 
private:
                        BBinder(const BBinder& o);
            BBinder&    operator=(const BBinder& o);
 
    class Extras;
 
    atomic_uintptr_t    mExtras;  // should be atomic<Extras *>
            void*       mReserved0;
};
    除了看到几个函数,没什么参考价值,进而看一下其构造函数:
/** \frameworks\native\libs\binder\Binder.cpp*/
class BBinder::Extras
{
public:
    Mutex mLock;
    BpBinder::ObjectManager mObjects;
};
 
// ---------------------------------------------------------------------------
 
BBinder::BBinder()
{
    atomic_init(&mExtras, 0);
}
    因为在前面创建MediaService中,初始化Process(Process::self())时,便进行了打开/dev/binder,以及mmap操作;故根据前面的推测以及SM的事件处理流程,下一步应该是类似binder_loop进行循环的等待与事件处理。


(二)循环处理消息:
    Looper明显是与线程相关的,便可以回顾到前面所提到的ProcessState与IPCThreadState,他们分别是进程唯一和线程唯一,看一下其与Looper会发生的怎么样的联系。回到主main函数:

/** \frameworks\av\media\mediaserver\main_mediaserver.cpp*/
using namespace android;
 
int main(int argc __unused, char** argv)
{
    // 获取一个ProcessState实例
    sp<ProcessState> proc(ProcessState::self());
    // 一个ServiceManager实例
    sp<IServiceManager> sm = defaultServiceManager();
    /** 启动一些所需的Service服务**/
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();// 初始化MediaPlayerService服务
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    SoundTriggerHwService::instantiate();
    registerExtensions();
    // ProcessState开辟线程池
    ProcessState::self()->startThreadPool();
    // IPCThreadState加入到线程池
    IPCThreadState::self()->joinThreadPool();
}
    看到第四步中有开辟Binder线程池的操作,追踪来看:


1、ProcessState::StartThreadPool:

/** \frameworks\native\libs\binder\ProcessState.cpp*/
void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        // 引出一个函数
        spawnPooledThread(true);
    }
}

2、spawnPooledThread():

/** \frameworks\native\libs\binder\ProcessState.cpp*/
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        // 创建线程池,然后run
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

3、再看一下引出的一个重要类PoolThread:

/** \frameworks\native\libs\binder\ProcessState.cpp*/
class PoolThread : public Thread
{
public:
    // 构造函数,这里isMain为true
    PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }
   
protected:
    // 这里看到了想要的loop
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
   
    const bool mIsMain;
};
    可以看到PoolThread是继承Thread的,要看其构造函数完成了什么功能,需要进而看其父类Thread的构造函数:

1)下面给出Thread的定义:

/** \system\core\include\utils\Thread.h*/
class Thread : virtual public RefBase
{
public:
    // Create a Thread object, but doesn't create or start the associated
    // thread. See the run() method.
                        Thread(bool canCallJava = true);
    virtual             ~Thread();
 
    // Start the thread in threadLoop() which needs to be implemented.
    virtual status_t    run(    const char* name = 0,
                                int32_t priority = PRIORITY_DEFAULT,
                                size_t stack = 0);
   
    // Ask this object's thread to exit. This function is asynchronous, when the
    // function returns the thread might still be running. Of course, this
    // function can be called from a different thread.
    virtual void        requestExit();
 
    // Good place to do one-time initializations
    virtual status_t    readyToRun();
   
    // Call requestExit() and wait until this object's thread exits.
    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
    // this function from this object's thread. Will return WOULD_BLOCK in
    // that case.
            status_t    requestExitAndWait();
 
    // Wait until this object's thread exits. Returns immediately if not yet running.
    // Do not call from this object's thread; will return WOULD_BLOCK in that case.
            status_t    join();
 
    // Indicates whether this thread is running or not.
            bool        isRunning() const;
 
#ifdef HAVE_ANDROID_OS
    // Return the thread's kernel ID, same as the thread itself calling gettid() or
    // androidGetTid(), or -1 if the thread is not running.
            pid_t       getTid() const;
#endif
 
protected:
    // exitPending() returns true if requestExit() has been called.
            bool        exitPending() const;
   
private:
    // Derived class must implement threadLoop(). The thread starts its life
    // here. There are two ways of using the Thread object:
    // 1) loop: if threadLoop() returns true, it will be called again if
    //          requestExit() wasn't called.
    // 2) once: if threadLoop() returns false, the thread will exit upon return.
    virtual bool        threadLoop() = 0;
 
private:
    Thread& operator=(constThread&);
    static  int             _threadLoop(void* user);
    const   bool            mCanCallJava;
    // always hold mLock when reading or writing
            thread_id_t     mThread;
    mutable Mutex           mLock;
            Condition       mThreadExitedCondition;
            status_t        mStatus;
    // note that all accesses of mExitPending and mRunning need to hold mLock
    volatile bool           mExitPending;
    volatile bool           mRunning;
            sp<Thread>      mHoldSelf;
#ifdef HAVE_ANDROID_OS
    // legacy for debugging, not used by getTid() as it is set by the child thread
    // and so is not initialized until the child reaches that point
            pid_t           mTid;
#endif
};
    可以看到前面PoolThread中使用的run(),threadLoop(),均是取自Thread;先看其构造函数做了什么事情:

/** \system\core\libutils\Threads.cpp*/
Thread::Thread(bool canCallJava)  
    :   mCanCallJava(canCallJava),
        mThread(thread_id_t(-1)),
        mLock("Thread::mLock"),
        mStatus(NO_ERROR),
        mExitPending(false), mRunning(false)
#ifdef HAVE_ANDROID_OS
        , mTid(-1)
#endif
{
}
    创建完PoolThread,发现只是进行了简单的初始化操作,并未真正创建进程。回到spawnPooledThread()函数,发现调用了PoolThread的run函数,感觉这就和java 层的Thread结构略像了,所有操作放在run中;


2)PoolThread调用run实际上是调用了Thread中的run():

/** \system\core\libutils\Threads.cpp*/
status_t Thread::run(const char* name, int32_t priority, size_t stack)
{
    Mutex::Autolock _l(mLock);
 
    /** 一系列的初始化操作,忽略**/
    if (mRunning) {
        return INVALID_OPERATION;
    }
    mStatus = NO_ERROR;
    mExitPending = false;
    mThread = thread_id_t(-1);
    mHoldSelf = this;
    mRunning = true;
 
    bool res;
    /*** 创建线程Thread***/
    if (mCanCallJava) {   //由前面语境知,这里为true
    // 很明这里是创建Thread的地方,具体Android是如何封装pthread_create()的,遇见Thread再具体分析
        res = createThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    } else {
        res = androidCreateRawThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    }
 
    /** 创建时失败的错误处理,忽略**/
    if (res == false) {
        mStatus = UNKNOWN_ERROR;   // something happened!
        mRunning = false;
        mThread = thread_id_t(-1);
        mHoldSelf.clear();  // "this" may have gone away after this.
 
        return UNKNOWN_ERROR;
    }
 
    return NO_ERROR;
}
     可以看到在这里使用函数createThreadEtc创建了线程,Android Thread也是使用pthread_create来创建线程的;

     createThreadEtc定义如下:

inline bool createThreadEtc(thread_func_t entryFunction, void* userData,
            const char* threadName = "android:unnamed_thread",
            int32_t threadPriority = PRIORITY_DEFAULT,
            size_t threadStackSize = 0,
            thread_id_t *threadId = 0)
{
    return androidCreateThreadEtc(entryFunction, userData, threadName, threadPriority,
        threadStackSize, threadId) ? true : false;
}

    具体分析不在给出,总之是根据提供的优先级等信息创建一个线程,而线程的函数则是_threadLoop(),这个函数很熟悉,明显刚才在Threads.cpp中见过,也终于得到了前面推测中所需要的Loop 循环处理函数;

     这里创建了新线程,与主线程同时运行,这时就要回到主线程到最初调用的起点,也就是到这里ProcessState::self()->startThreadPool();完成了开辟线程池。下面就要进行IPCThreadState::self()->joinThreadPool();

    下面需要分开来看,分别来看子线程与主线程做了什么事情,注意两者是并行的。


(三)Loop循环处理函数

先看新建的子线程:

1、先创建线程的线程函数是_threadLoop函数,如下所示:

/** \system\core\libutils\Threads.cpp*/
int Thread::_threadLoop(void* user)
{
    Thread* const self = static_cast<Thread*>(user);
 
    /** 强弱引用计数**/
    // mHoldSelf在run中指向了自己(this)
    sp<Thread> strong(self->mHoldSelf);
    wp<Thread> weak(strong);
    self->mHoldSelf.clear();
    /** 主要用于测试*/
#ifdef HAVE_ANDROID_OS
    self->mTid = gettid();
#endif
 
    bool first = true;
 
    do {
        bool result;
        /** 第一次执行*/
        if (first) {
            first = false;
            // Good place to do one-time initializations(virtual函数)
            self->mStatus = self->readyToRun();
            result = (self->mStatus == NO_ERROR);
 
            if (result && !self->exitPending()) {
                // Binder threads (and maybe others) rely on threadLoop
                // running at least once after a successful ::readyToRun()
                // (unless, of course, the thread has already been asked to exit
                // at that point).
                // This is because threads are essentially used like this:
                //   (new ThreadSubclass())->run();
                // The caller therefore does not retain a strong reference to
                // the thread and the thread would simply disappear after the
                // successful ::readyToRun() call instead of entering the
                // threadLoop at least once.
 
              /*** 注意这里调用了自己的threadLoop函数
               *   回到Thread发现threadLoop为virtual函数,则真正调用的PoolThread的
               *   threadLoop函数**/
                result = self->threadLoop();
            }
        } else { /** 非再次执行则无需再做检测*/
            result = self->threadLoop();
        }
 
        /** 下面的事情与主线无关,不再关心**/
        // establish a scope for mLock
        {
        Mutex::Autolock _l(self->mLock);
        if (result == false || self->mExitPending) {
            self->mExitPending = true;
            self->mRunning = false;
            // clear thread ID so that requestExitAndWait() does not exit if
            // called by a new thread using the same thread ID as this one.
            self->mThread = thread_id_t(-1);
            // note that interested observers blocked in requestExitAndWait are
            // awoken by broadcast, but blocked on mLock until break exits scope
            self->mThreadExitedCondition.broadcast();
            break;
        }
        }
 
        // Release our strong reference, to let a chance to the thread
        // to die a peaceful death.
        strong.clear();
        // And immediately, re-acquire a strong reference for the next loop
        strong = weak.promote();
    } while(strong != 0);
 
    return 0;
}
    可以看到线程函数中调用了自己的threadLoop函数,由于前面Thread的声明知道,threadLoop函数是virtual函数,而此语境下,Thread对应的是PoolThread,故最终调用的是PoolThread::threadLoop:


2、PoolThread::threadLoop:

/** \frameworks\native\libs\binder\ProcessState.cpp*/
virtual bool threadLoop()
{
    /** 竟然也调用了joinThreadPool,这个语境下mIsMain为true*/
    IPCThreadState::self()->joinThreadPool(mIsMain);
    return false;
}
    函数很简单,却竟然和主线程中要分析的第五步完全一模一样。IPCThreadState前面讲到是线程私有的,即每个线程都对应的一个IPCThreadState是不同的。因而主线程与子线程是两个不同的IPCThreadState调用了joinThreadPool。不过最终所有的事情都交由一个相同的函数来负责,所以下面重点分析一下joinThreadPool函数:

************************************第五步*************************************************

3、IPCThreadState::joinThradLoop:
(注:这里是基于Android 5.1的,和深入浅出Binder中的Android 2.3该函数已经有了较大改动)

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
void IPCThreadState::joinThreadPool(bool isMain)
{
    /* Binder驱动程序请求进程注册一个线程到它的线程池中,新建立线程会使用BC_REGISTER_LOOPER来通知Binder其准备就绪
       BC_REGISTER_LOOPER = _IO('c', 11),
                         一个线程自己注册到Binder驱动程序后,会使用BC_ENTER_LOOPER通知Binder其准备就绪
       BC_ENTER_LOOPER = _IO('c', 12),**/
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
 
    // 设置线程为前台线程
    set_sched_policy(mMyThreadId, SP_FOREGROUND);
 
    status_t result;
    /********这里可以看到是一个很明显的while循环处理函数************/
    do {
    // 准备工作,修改强弱引用计数
        processPendingDerefs();
        // 代码最终的主体在这里
        result = getAndExecuteCommand();
 
        // 下面是差错控制
        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
            abort();
        }
        if(result == TIMED_OUT && !isMain) {
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);
 
    /*** 通知退出,发送数据到binder driver**/
    mOut.writeInt32(BC_EXIT_LOOPER);
    talkWithDriver(false);
}
 
 
// 当完成了对incoming的命令队列的读取,要注意减少对进程的强弱引用计数
void IPCThreadState::processPendingDerefs()
{
 
    if (mIn.dataPosition() >= mIn.dataSize()) {// 表示完成了读取
        size_t numPending = mPendingWeakDerefs.size();
        if (numPending > 0) {
            for (size_t i = 0; i < numPending; i++) {
                RefBase::weakref_type* refs = mPendingWeakDerefs[i];
                refs->decWeak(mProcess.get());
            }
            mPendingWeakDerefs.clear();
        }
 
        numPending = mPendingStrongDerefs.size();
        if (numPending > 0) {
            for (size_t i = 0; i < numPending; i++) {
                BBinder* obj = mPendingStrongDerefs[i];
                obj->decStrong(mProcess.get());
            }
            mPendingStrongDerefs.clear();
        }
    }
}
    joinPoolThread实现了一个do-while的循环处理函数,很明显,处理命令请求的细节都被封装在了getAndExecuteCommand()函数中;


1)IPCThreadState::getAndExecuteCommand(从名称就可以看出它的作用)

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;
 
    /** talkWithDriver所做的工作是将mIn于mOut缓冲区的信息写入到
     *  bwr(binder_write_read)中,通过ioctl函数与binder驱动程序进行通信。*/
    result = talkWithDriver();
    if (result >= NO_ERROR) {
    /** 读取cmd*/
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();
 
        // 真正执行命令的函数又放在了executeCommand
        result = executeCommand(cmd);
 
        // After executing the command, ensure that the thread is returned to the
        // foreground cgroup before rejoining the pool.  The driver takes care of
        // restoring the priority, but doesn't do anything with cgroups so we
        // need to take care of that here in userspace.  Note that we do make
        // sure to go in the foreground after executing a transaction, but
        // there are other callbacks into user code that could have changed
        // our group so we want to make absolutely sure it is put back.
        set_sched_policy(mMyThreadId, SP_FOREGROUND);
    }
    return result;
}
    可以看到是常见的命令请求处理流程,读取mIn缓冲区的请求数据cmd,然后放到executeCommand方法中进行处理。


2)继续来看executeCommand:

/** \frameworks\native\libs\binder\IPCThreadState.cpp*/
status_t IPCThreadState::executeCommand(int32_t cmd)
{
    BBinder* obj;
    RefBase::weakref_type* refs;
    status_t result = NO_ERROR;
    /** 总之又是一大串根据命令不同进行相应事件处理,具体情况再去具体分析**/
    switch (cmd) {
    //...
    case BR_TRANSACTION:
        {
            binder_transaction_data tr;
            result = mIn.read(&tr, sizeof(tr));
            ...
           
            Parcel reply;
            status_t error;
            if (tr.target.ptr) {
              // 前面一系列事件处理暂时不管,这里出现了两个前面介绍过得BBinder类以及transact函数
                sp<BBinder> b((BBinder*)tr.cookie);
                error = b->transact(tr.code, buffer, &reply, tr.flags);
 
            } else {
                error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
            }
 
           ...
        }
    }
    return result;
}
    cookie指向Binder实体对象,这里将其强制转化成BBinder,BBinder在前面4.1.3中见到过,这里调用BBinder的transact函数。

    注意BnMediaPlayerService是继承BBinder的,这里tr.cookie是指向BnMediaPlayerService的,强制转换成父类sp<BBinder> b((BBinder*) tr.cookie),BBinder的transact函数是virtual函数,但BnMediaPlayerService并未实现相应的transact函数。因此最后调用的还是BBinder的transact函数。

3)BBinder::transact函数:

/** \frameworks\native\libs\binder\Binder.cpp*/
status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    data.setDataPosition(0);
 
    status_t err = NO_ERROR;
    switch (code) {
        case PING_TRANSACTION:
            reply->writeInt32(pingBinder());
            break;
        default:
       
        /*** 重点在于这里,调用了onTransact函数来传递消息**/
            err = onTransact(code, data, reply, flags);
            break;
    }
 
    if (reply != NULL) {
        reply->setDataPosition(0);
    }
 
    return err;
}
   看到这里调用了onTransact函数,BBinder::onTransact函数是virtual函数,前面给出的BnMediaPlayerService实现了onTransact函数,则由虚函数知识知这里其实调用的是BnMediaPlayerService::onTransact函数。


4)BnMediaPlayerService::onTransact函数:

/** \frameworks\av\media\libmedia\IMediaPlayerService.cpp*/
status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    /*** 这是对命令进行处理,注意下面处理的共性**/
    switch (code) {
        case CREATE: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IMediaPlayerClient> client =
                interface_cast<IMediaPlayerClient>(data.readStrongBinder());
            int audioSessionId = data.readInt32();
            sp<IMediaPlayer> player = create(client, audioSessionId);
            reply->writeStrongBinder(player->asBinder());
            return NO_ERROR;
        } break;
        case DECODE_URL: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IMediaHTTPService> httpService;
            if (data.readInt32()) {
                httpService =
                    interface_cast<IMediaHTTPService>(data.readStrongBinder());
            }
            ...
            return NO_ERROR;
        } break;
        ...
        case CREATE_MEDIA_RECORDER: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IMediaRecorder> recorder = createMediaRecorder();
            reply->writeStrongBinder(recorder->asBinder());
            return NO_ERROR;
        } break;
        case CREATE_METADATA_RETRIEVER: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
            reply->writeStrongBinder(retriever->asBinder());
            return NO_ERROR;
        } break;
        ...
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}
   注意上面处理code的执行模式基本都是一致,基本上都是根据code命令的不同,将其分发给相应的派生类进行处理:

1> CHECK_INTERFACE(IMediaPlayerService, data, reply);用以排错
2> sp<IMediaXXX> client= interface_cast<IMediaXXX>(data.readStrongBinder());根据code类型生成相应的接收reply的类对象client(如果需要的话)
3> sp<IMediaPlayer> player = create(client, audioSessionId); 根据code 类型create出相应的派生类来处理请求。注意这里的create是virtual,会根据调用类对象的不同而创建所需要的派生类
4> reply->writeStrongBinder(retriever->asBinder());

    前面提到过MediaPlayerService是继承BnMediaPlayerService的,如下

  class MediaPlayerService : public BnMediaPlayerService

而MediaPlayerService中定义了上面提到的virtual函数create():

  virtual sp<IMediaPlayer>    create(const sp<IMediaPlayerClient>& client, int audioSessionId);

则知在上面onTransact函数中实际调用的MediaPlayerService::create().
    而一直是MediaPlayerService,相对应的MediaPlayerClient在何处?注意到onTransact函数中,case CREATE:

  sp<IMediaPlayerClient> client =

                interface_cast<IMediaPlayerClient>(data.readStrongBinder());

引出了正在寻找的MediaPlayerClient.
    前面指出:
  class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
BnMediaPlayerService是继承IMediaPlayerService,那么就可以姑且推测MediaPlayerClient是同样继承IMediaPlayerClient的。

    至此创建MediaService的五步已经完全执行完毕,下面来看Client端。先看一下MediaPlayer系统图:
技术分享
技术分享

<二>Client端

    和前面同样的设计模式,如果Client要使用MediaPlayerService,发送请求给该Service,回顾图一中的描述,首先要获取到MediaPlayerService的代理proxy——BpMediaPlayerService。然后通过代理再与binder驱动以及MediaPlayerService(BnMediaPlayerService)。

1、先熟悉下继承关系:

/** \frameworks\av\include\media\mediaplayer.h*/
class MediaPlayer : public BnMediaPlayerClient,
                    public virtual IMediaDeathNotifier
   MidiaPlayer是是同时继承BnMediaPlayerClinet,IMediaDeathNotifier的。IMediaDeathNotifier类里面有一个静态成员函数

getMeidaPlayerService,它通过IServiceManager::getService接口来获得MediaPlayerService的远程接口。


2、IMediaDeathNotifier的定义:

/** \frameworks\av\include\media\IMediaDeathNotifier.h*/
class IMediaDeathNotifier: virtual public RefBase
{
    public:
        ...
        static const sp<IMediaPlayerService>& getMediaPlayerService();
   
    private:
        ...
   
        static  Mutex                                   sServiceLock;
        static  sp<IMediaPlayerService>                 sMediaPlayerService;
        static  sp<DeathNotifier>                       sDeathNotifier;
        static  SortedVector< wp<IMediaDeathNotifier> > sObitRecipients;
    };
 
}; // namespace android
在MediaPlayer.cpp中,函数setDataSource调用了getMediaPlayerService函数:

/** \frameworks\av\include\media\mediaplayer.cpp*/
status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
{
    status_t err = UNKNOWN_ERROR;
    /** 这里调用getMediaPlayerService**/
    const sp<IMediaPlayerService>& service(getMediaPlayerService());
    if (service != 0) {
        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
            (NO_ERROR != player->setDataSource(fd, offset, length))) {
            player.clear();
        }
        err = attachNewPlayer(player);
    }
    return err;
}
    查看MediaPlayer类知其并未实现getMediaPlayerService方法,则调用的即是上面提到的IMediaDeathNotifier::getMediaPlayerService()方法。


3、来看要播放一个本地视频,一般要做的事情:

    MediaPlayer  mMediaPlayer = new MediaPlayer( );
    mMediaPlayer.setDataSource(mContext, mUri);-
    mMediaPlayer.setDisplay(mSurfaceHolder);
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mMediaPlayer.prepareAsync();
    mMediaPlayer.start();
看到这里,创建了一个MediaPlayer对象之后,首先调用便是setDataSource。


4、IMediaDeathNotifier::getMediaPlayerService():

/** \frameworks\av\media\libmedia\IMediaDeathNotifier.cpp*/
const sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()
{
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService == 0) {
    /** 获取SM实例**/
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
        /** 通过SM获取相应注册的服务即MediaPlayerService*/
            binder = sm->getService(String16("media.player"));
            if (binder != 0) {
                break;
            }
            usleep(500000); // 0.5 s
        } while (true);
 
        if (sDeathNotifier == NULL) {
            sDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(sDeathNotifier);
        /*** 注意在这里强制转化成IMediaPlayerService**/
        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    return sMediaPlayerService;
}
    BpMediaPlayerService用这个binderBnMediaPlayerService进行通信


至此,MediaService使用Binder进行通信的机制分析完毕。总结一下总的流程,下面的流程所有Service都是相仿:

1、上面所有的分析都是基于main主函数来进行分析的:

int main(int argc __unused, char** argv)
{
    // 获取一个ProcessState实例
    sp<ProcessState> proc(ProcessState::self());
    // 一个ServiceManager实例
    sp<IServiceManager> sm = defaultServiceManager();
    // 初始化MediaPlayerService服务
    MediaPlayerService::instantiate();
    // ProcessState开辟线程池
    ProcessState::self()->startThreadPool();
    // IPCThreadState加入到线程池
    IPCThreadState::self()->joinThreadPool();
}
2、BnXXX与BPXXX都应是基于IXXX的,所以要定义IXXX:

/** \frameworks\av\media\libmedia\IMediaDeathNotifier.cpp*/
class IMediaPlayerService: public IInterface
{
public:
    /** 分析SM时提到的宏,该宏定义在IInterface中*/
    DECLARE_META_INTERFACE(MediaPlayerService);
    ...
}


3、再分别定义BnXXX,BpXXX:
1)BnXXX:
    首先进行声明:

/* \frameworks\av\include\media\IMediaPlayerService.h*/
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};
 
}; // namespace android

    然后定义进行通信处理的逻辑:
/** \frameworks\av\media\libmedia\IMediaPlayerService.cpp*/
/** 注意要同SM实例一样,DECLARE之后要IMPLMENT*/
IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");

status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    /*** 这是对命令进行处理,注意下面处理的共性**/
    switch (code) {
        case CREATE: {
           ...
        } break;
        ...
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

2)BpXXX:

/** /frameworks/av/media/libmedia/IMediaplayer.cpp*/
// 其实它应该和BnMediaPlayer对应,这里只用于示例
class BpMediaPlayer: public BpInterface<IMediaPlayer>
{
public:
    BpMediaPlayer(const sp<IBinder>& impl) : BpInterface<IMediaPlayer>(impl)
    {
    }
 
    status_t setDataSource(const char* url,
    const KeyedVector<String8, String8>* headers)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        data.writeCString(url);
        if (headers == NULL) {
            data.writeInt32(0);
        } else {
            // serialize the headers
            data.writeInt32(headers->size());
            for (size_t i = 0; i < headers->size(); ++i) {
                data.writeString8(headers->keyAt(i));
                data.writeString8(headers->valueAt(i));
            }
        }
        remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
        return reply.readInt32();
    }
}
remote()是BpBinder,通过BpBinder来与binder驱动程序进行通信。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Binder机制解析

标签:

原文地址:http://blog.csdn.net/woliuyunyicai/article/details/46864567

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!