Binder_Native:MediaServer主函数代码跟踪分析

来源:互联网 发布:情人节 巧克力 知乎 编辑:程序博客网 时间:2024/05/01 21:56

说明:基于MeidaServer的main流程的分析

这里直接从MeidaServer的主函数main入口开始分析,代码如下:

<span style="font-family:SimSun;font-size:18px;">        sp<ProcessState> proc(ProcessState::self()); /* 获取一个ProcessState对象proc */        sp<IServiceManager> sm = defaultServiceManager(); /* 得到一个IServiceManager对象 */        ALOGI("ServiceManager: %p", sm.get());        AudioFlinger::instantiate(); /* 音频服务初始化 */        MediaPlayerService::instantiate(); /* 媒体服务初始化 */        CameraService::instantiate();   /* camera服务初始化 */        AudioPolicyService::instantiate(); /* 音频AudioPolicy的初始化 */        SoundTriggerHwService::instantiate();        registerExtensions();        ProcessState::self()->startThreadPool(); /* 创建一个线程池 */        IPCThreadState::self()->joinThreadPool(); /* 将自己加入到该线程池中 */</span>
这里分别对以下几句关键代码进行分析和跟踪,也就是清晰的了解整个流程
<span style="font-family:SimSun;font-size:18px;">sp<ProcessState> proc(ProcessState::self()); /* 获取一个ProcessState对象proc */        sp<IServiceManager> sm = defaultServiceManager(); /* 得到一个IServiceManager对象 */        ...        MediaPlayerService::instantiate(); /* 媒体服务初始化 */        ...        ProcessState::self()->startThreadPool(); /* 创建一个线程池 */        IPCThreadState::self()->joinThreadPool(); /* 将自己加入到该线程池中 */</span>
@1 sp<ProcessState> proc(ProcessState::self());
    ProcessState使用了单例模式,其中self的方法实现如下所示:

<span style="font-family:SimSun;font-size:18px;">sp<ProcessState> ProcessState::self(){    Mutex::Autolock _l(gProcessMutex);    if (gProcess != NULL) {        return gProcess;    }    gProcess = new ProcessState;    return gProcess;}</span>
    这里使用单例模式也就是说明:一个进程只能有一个ProcessState对象
   在创建ProcessState对象之后,构造器肯定是第一个执行的,因此这里我们对构造方法进行分析:
<span style="font-family:SimSun;font-size:18px;">ProcessState::ProcessState()    : mDriverFD(open_driver())    /* 这里打开了binder驱动 */    , mVMStart(MAP_FAILED)       /* 这里用MAP_FAILED初始化mmap映射地址, *?    , 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.");}</span>
   这里关键点之一就是打开binder驱动,继续分析:
<span style="font-family:SimSun;font-size:18px;">static int open_driver(){    int fd = open("/dev/binder", O_RDWR);    if (fd >= 0) {        fcntl(fd, F_SETFD, FD_CLOEXEC);        int vers;        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;        }        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { /* 版本相关信息 */            ALOGE("Binder driver protocol does not match user space protocol!");            close(fd);            fd = -1;        }        size_t maxThreads = 15; /* 这里告诉驱动,最大支持的线程数是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;}</span>
   致此,对这部分进行结束,对以上流程进行总结,ProcessState::self()所做的事情如下:
       使用单例模式获取对象,保证一个进程只能打开设备一次
       打开binder设备;同时对版本有一定的验证机制
       进行mmap操作,分配一块内存来接收数据
@2 sp<IServiceManager> sm = defaultServiceManager();{CodeTracker_2}
    这里就需要对defaultServiceManager()进行分析了,实现是在IServiceManager中完成
    主要用来返回一个IServiceManager类型的对象与ServiceManager进行交互与通信
   defaultServiceManager()的实现如下所示:
<span style="font-family:SimSun;font-size:18px;">sp<IServiceManager> defaultServiceManager(){    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;        {        AutoMutex _l(gDefaultServiceManagerLock);        while (gDefaultServiceManager == NULL) {            /* 这里是获取gDefaultServiceManager的关键 */            gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));            if (gDefaultServiceManager == NULL)                sleep(1);        }    }        return gDefaultServiceManager;}</span>
   defaultServiceManager()在获取gDefaultServiceManager时也使用了单例模式
@@2.1 ProcessState::self()->getContextObject(NULL)这里的关键方法getContextObject进行分析,如下所示:
<span style="font-family:SimSun;font-size:18px;">sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){    return getStrongProxyForHandle(0);}</span>
   继续分析getStrongProxyForHandle,代码如下所示:
<span style="font-family:SimSun;font-size:18px;">sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){    sp<IBinder> result;    AutoMutex _l(mLock);    handle_entry* e = lookupHandleLocked(handle);     if (e != NULL) {        IBinder* b = e->binder;        /* 只有对于新的资源项,binder才为空 */        if (b == NULL || !e->refs->attemptIncWeak(this)) {            if (handle == 0) {                /* 这里对handle为0的进程多了特殊处理,先ping一下,ping通了才可以使用*/                Parcel data;                status_t status = IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION, data, NULL, 0);                if (status == DEAD_OBJECT)                   return NULL;            }            /* 这里创建一个BpBinder对象并填充到handle_entry结构体中 */            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;}</span>
   这里的lookuphandleLocked主要是根据handle值查找对应的索引值,如果没有会创建一个新项并返回(注意:只有出错才会返回NULL),一般情况下一定会返回一个不为空的handle_entry对象,它的实现如下
<span style="font-family:SimSun;font-size:18px;">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);}  </span>
    getStrongProxyForHandle返回的是一个BpBinder对象,interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));这句代码就等价于interface_cast<IServiceManager>(new BpBinder(0));      接下来,对BpBinder和BBinder进行进一步的说明:
       BpBinder和BBinder都是从IBinder中派生出来的
        BpBinder是客户端用来与Server端交互的代理类,同时BBinder代表服务端
        BpBinder与BBinder是多对一关系,即BpBinder只能与对应的BBinder进行交互(这里只要看BpBinder用handle来初始化即可明白)
        BpBinder用handle来初始化自己,而所有的BBinder是通过handle来区分的,即BpBinder通过handle来绑定BBinder
   这里对BpBinder的构造方法实现进行说明:
<span style="font-family:SimSun;font-size:18px;">BpBinder::BpBinder(int32_t handle)    : mHandle(handle)    , mAlive(1)    , mObitsSent(0)    , mObituaries(NULL){    extendObjectLifetime(OBJECT_LIFETIME_WEAK);    IPCThreadState::self()->incWeakHandle(handle);}</span>
   这里有一点很可疑,那就是BpBinder没有和binder驱动进行交互,而如果要通讯,与binder驱动交互是一定的
   (实际上,与binder交互的关键点是IPCThreadState方法中的talkWithDriver;下面会继续分析)
@@2.2 接下来仔细分析interface_cast,interface_cast的实现如下所示
<span style="font-family:SimSun;font-size:18px;">template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){    return INTERFACE::asInterface(obj);}</span>
    这里返回的就是关键,后面也主要是分析asInterface方法的内部实现,基于此,继续分析
    这里是一个模板函数,因此将IServiceManager等价过去即为:
<span style="font-family:SimSun;font-size:18px;">inline sp< IServiceManager > interface_cast(const sp<IBinder>& obj){    return IServiceManager::asInterface(obj);}</span>
    这里要做一下说明:BpBinder和BBinder是与通信相关的逻辑,而与业务相关的逻辑主要在IServiceManager中
    IServiceManager的代码如下所示:
<span style="font-family:SimSun;font-size:18px;">class IServiceManager : public IInterface{public:    DECLARE_META_INTERFACE(ServiceManager);    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) = 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,    };};</span>
    这里保证了通信和业务的挂钩,关键点在于两个宏:DECLARE_META_INTERFACE和IMPLENT_META_INTERFACE,下面对其分别进行说明:DECLARE_META_INTERFACE的实现如下所示:
<span style="font-family:SimSun;font-size:18px;">#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();</span>
   将这里的用ServiceManager替换INTERFACE,替换后如下所示
<span style="font-family:SimSun;font-size:18px;">#define DECLARE_META_INTERFACE(ServiceManager)                          \    static const android::String16 descriptor;                          \    static android::sp<IServiceManager > asInterface(                   \            const android::sp<android::IBinder>& obj);                  \    virtual const android::String16& getInterfaceDescriptor() const;    \    IServiceManager();                                                  \    virtual ~IServiceManager();  </span>
   同时,DECLARE_META_INTERFACE目的是将其声明,IMPLENT_META_INTERFACE目的是将其实现,IMPLENT_META_INTERFACE的代码实现如下所示:
<span style="font-family:SimSun;font-size:18px;">#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() { }                                   \</span>
   这里的用ServiceManager替换INTERFACE后,用"android.os.IServiceManager"替换NAME,即为:
<span style="font-family:SimSun;font-size:18px;">#define 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::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() { }     </span>
    至此,IServiceManager::asInterface实现就展现出来了,它的功能是:通过传递进来的Bpbinder对象创建一个BpServiceManager对象。
   同时,目前interface_cast<IServiceManager>(new BpBinder(0)); 等价为BpServiceManager(new BpBinder(0));     
   在这里,对IServiceManager家族图谱进行说明:
        IServiceManager、BpServiceManager、BnServiceManager均与业务逻辑有关
        BnServiceManager继承BBinder与IServiceManager,可以直接与binder设备进行通信
        BnServiceManager是一个虚类,需要子类来实现对应的功能    
        BpServiceManager继承BpInterface,而BpInterface又继承BpRefBase,BpRefBase中mRemote为IBinder类型,与BpBinder有关系
@@2.3 接下来分析BpServiceManager
     查看BpServiceManager的实现代码
<span style="font-family:SimSun;font-size:18px;">class BpServiceManager : public BpInterface<IServiceManager>{public:    BpServiceManager(const sp<IBinder>& impl)        : BpInterface<IServiceManager>(impl)/* 这里调用基类的构造函数 */    {    }    ...};</span>
    这里,关注BpInterface的实现,代码如下所示:
<span style="font-family:SimSun;font-size:18px;">template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase /* 基类构造函数 */{public:                                BpInterface(const sp<IBinder>& remote); protected:    virtual IBinder*            onAsBinder();};</span>
   这里,关注BpRefBase的实现代码,如下所示:
<span style="font-family:SimSun;font-size:18px;">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.    }}</span>
   至此,BpServiceManager中的mRemote对象指向了BpBinder
    BpServiceManager实现了IServiceManager的业务逻辑,同时有BpBinder作为代表,通信和业务逻辑平台就都搭建好了。
@@2.4 这里附上两张图,分别描述IBinder、BpBinder、BBinder的关系与IServiceManager家族图谱:


图1 IBinder、BpBinder、BBinder的关系 
                   
  
        图2 IServiceManager家族图谱                    
@3 MediaPlayerService::instantiate();{CodeTracker_3}
@@3.1 业务层的工作,主要针对BpServiceManager
    该方法的主要功能是注册MeidaplayerService,代码具体实现如下所示:
<span style="font-family:SimSun;font-size:18px;">void MediaPlayerService::instantiate() {    defaultServiceManager()->addService(            String16("media.player"), new MediaPlayerService());}</span>
   defaultServiceManager的返回值是BpServiceManager对象,继续分析addService
<span style="font-family:SimSun;font-size:18px;">   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);        /* 这里返回的就是一个mRemote对象,即BpBinder(0) */        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);        return err == NO_ERROR ? reply.readExceptionCode() : err;    }</span>
   说明:
        addService是一个业务层的函数;通信的任务主要交给BpBinder来做
        业务层和通信层的差别在于;业务层是将请求信息打包,通信层是传输信息,仅此而已。
   接下来,addService的关键点就在这里,Bpbinder的transtract方法,接下来分析通信层的工作
@@3.2 通信层的工作,主要针对BpBinder的传输
    之前分析过,BpBinder中没有直接与binder设备交互的地方,那么继续分析transact方法,代码如下所示:
<span style="font-family:SimSun;font-size:18px;">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) {        status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);        if (status == DEAD_OBJECT) mAlive = 0;        return status;    }     return DEAD_OBJECT;}</span>
@@@3.2.1 接下来,分析IPCThreadState::self()的transact方法,先分析self与构造器,代码如下:
<span style="font-family:SimSun;font-size:18px;">IPCThreadState* IPCThreadState::self(){    if (gHaveTLS) {/* 第一次进来为false */restart:        const pthread_key_t k = gTLS;        /* 通过pthread_getspecific获取对应的IPCThreadState对象 */        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);        /* 如果不为空,直接返回;如果为空,则创建一个IPCThreadState对象出来 */        if (st) return st;        return new IPCThreadState;    }        if (gShutdown) return NULL;        pthread_mutex_lock(&gTLSMutex);    if (!gHaveTLS) {        if (pthread_key_create(&gTLS, threadDestructor) != 0) {            pthread_mutex_unlock(&gTLSMutex);            return NULL;        }        gHaveTLS = true;    }    pthread_mutex_unlock(&gTLSMutex);    goto restart;}</span>
    这里对TLS(Thread Local Storage,本地线程存储)进行下说明:
        每个线程空间都有一个,但是线程间不共享这些空间
        通过pthread_getspecific/pthread_setspecific来获取/设置这些空间中的内容       
        从pthread_getspecific中可以获取其中的IPCThread_State对象
   接下来分析其构造函数,代码如下:
<span style="font-family:SimSun;font-size:18px;">IPCThreadState::IPCThreadState()     : mProcess(ProcessState::self()),      mMyThreadId(androidGetTid()),      mStrictModePolicy(0),      mLastTransactionBinderFlags(0){    /* 在构造函数中,把自己设置到TLS中 */    pthread_setspecific(gTLS, this);    clearCaller();    /* 分别是发送和接收命令的缓冲区 */    mIn.setDataCapacity(256);    mOut.setDataCapacity(256);}</span>
   关于IPCThreadState的一些说明:
       每个线程都有一个IPCThreadState对象。而每个IPCThreadState也都有一个mIn和mOut对象
        mIn用来接收Binder设备发来的数据,mOut用来存储发送给binder设备的数据
   接下来分析transact方法,代码如下所示:
<span style="font-family:SimSun;font-size:18px;">status_t IPCThreadState::transact(int32_t handle,uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags){    status_t err = data.errorCheck();     flags |= TF_ACCEPT_FDS;        if (err == NO_ERROR) {        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);    }        if (err != NO_ERROR) {        if (reply) reply->setError(err);        return (mLastError = err);    }        if ((flags & TF_ONE_WAY) == 0) {           } else {        err = waitForResponse(NULL, NULL);    }        return err;}</span>
@@@3.2.2 这里的两个关键方法是writeTransactionData和waitForResponse,分别是发送数据和等待回复,那么接下来分别对其进行分析,writeTransactionData负责写传输数据,代码实现如下:
<span style="font-family:SimSun;font-size:18px;">status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer){    binder_transaction_data tr; /* 这个是binder设备通信的结构 */    tr.target.handle = handle;/* handle表示target,表示传输的目的地 */     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(size_t);        tr.data.ptr.offsets = data.ipcObjects();    } else if (statusBuffer) {        tr.flags |= TF_STATUS_CODE;        *statusBuffer = err;        tr.data_size = sizeof(status_t);        tr.data.ptr.buffer = statusBuffer;        tr.offsets_size = 0;        tr.data.ptr.offsets = NULL;    } else {        return (mLastError = err);    }    /* 将数据写到mOut中,并没有发送 */    mOut.writeInt32(cmd);    mOut.write(&tr, sizeof(tr));        return NO_ERROR;}</span>
   接下来,查看发送请求和接收回复的部分,waitForResponse方法的实现如下所示:
<span style="font-family:SimSun;font-size:18px;">status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){    int32_t cmd;    int32_t err;    while (1) {        if ((err=talkWithDriver()) < NO_ERROR) break;/* talkWithDriver与地层binder设备交互,发送请求 */        /* 以下均为收到回复后所做的处理 */        err = mIn.errorCheck();        if (err < NO_ERROR) break;        if (mIn.dataAvail() == 0) continue;                cmd = mIn.readInt32();         switch (cmd) {        case BR_TRANSACTION_COMPLETE:            if (!reply && !acquireResult) goto finish;            break;        ...        case BR_DEAD_REPLY:        ...        case BR_FAILED_REPLY:        ...        case BR_ACQUIRE_RESULT:        ...               case BR_REPLY:        ...        default:            err = executeCommand(cmd);            if (err != NO_ERROR) goto finish;            break;        }    }finish:    if (err != NO_ERROR) {        if (acquireResult) *acquireResult = err;        if (reply) reply->setError(err);        mLastError = err;    }        return err;}</span>
   如果发送请求后立刻就收到了回复,对于这个回复的处理,一方面waitForResponse会处理一部分,主要的部分会交给executeCommand来执行。executeCommand的代码实现如下所示:
<span style="font-family:SimSun;font-size:18px;">status_t IPCThreadState::executeCommand(int32_t cmd) {    BBinder* obj;    RefBase::weakref_type* refs;    status_t result = NO_ERROR;        switch (cmd) {    case BR_ERROR:    ...    case BR_TRANSACTION:        {            binder_transaction_data tr;            result = mIn.read(&tr, sizeof(tr));            ALOG_ASSERT(result == NO_ERROR,"Not enough command data for brTRANSACTION");            if (result != NO_ERROR) break;                        Parcel buffer;            buffer.ipcSetDataReference(                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),                tr.data_size,                reinterpret_cast<const size_t*>(tr.data.ptr.offsets),                tr.offsets_size/sizeof(size_t), freeBuffer, this);                        const pid_t origPid = mCallingPid;            const uid_t origUid = mCallingUid;                        mCallingPid = tr.sender_pid;            mCallingUid = tr.sender_euid;                        int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);            if (gDisableBackgroundScheduling) {                if (curPrio > ANDROID_PRIORITY_NORMAL) {                                       setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);                }            } else {                if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {                    set_sched_policy(mMyThreadId, SP_BACKGROUND);                }            }                        Parcel reply;            if (tr.target.ptr) {                sp<BBinder> b((BBinder*)tr.cookie);                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);                if (error < NO_ERROR) reply.setError(error);             } else {                /* the_context_object是IPCThreadState中的一个全局变量,                   可以通过setTheContextObject函数来设置 */                const status_t error = the_context_object->transact                    (tr.code, buffer, &reply, tr.flags);                if (error < NO_ERROR) reply.setError(error);            }                        if ((tr.flags & TF_ONE_WAY) == 0) {                sendReply(reply, 0);            }                        mCallingPid = origPid;            mCallingUid = origUid;                    }        break;        case BR_DEAD_BINDER:        {   /* 收到binder驱动发来的service死亡的消息,只有Bp端能收到 */            BpBinder *proxy = (BpBinder*)mIn.readInt32();            proxy->sendObituary();            mOut.writeInt32(BC_DEAD_BINDER_DONE);            mOut.writeInt32((int32_t)proxy);        } break;    ...    case BR_SPAWN_LOOPER:        /* 这里收到驱动的指示,创建了一个线程,用于和binder进行通信 */        mProcess->spawnPooledThread(false);        break;            default:        printf("*** BAD COMMAND %d received from Binder driver\n", cmd);        result = UNKNOWN_ERROR;        break;    }     if (result != NO_ERROR) {        mLastError = result;    }        return result;}</span>
@@@3.2.3 与驱动的交互,这里对talkWithDriver进行分析,因为这是与底层交互的根基,代码实现如下:
<span style="font-family:SimSun;font-size:18px;">status_t IPCThreadState::talkWithDriver(bool doReceive) /*这里注意,默认不指定参数时doReceive值为true*/{    if (mProcess->mDriverFD <= 0) {        return -EBADF;    }    binder_write_read bwr;/* 构造与binder设备通信的参数 */        // Is the read buffer empty?    const bool needRead = mIn.dataPosition() >= mIn.dataSize();    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;        /*请求命令的填充 */    bwr.write_size = outAvail;    bwr.write_buffer = (long unsigned int)mOut.data();     // This is what we'll read.    if (doReceive && needRead) {        /* 接收缓冲区信息填充,如果收到信息,就写在该缓冲区内 */        bwr.read_size = mIn.dataCapacity();        bwr.read_buffer = (long unsigned int)mIn.data();    } else {        bwr.read_size = 0;        bwr.read_buffer = 0;    }        // Return immediately if there is nothing to do.    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;     bwr.write_consumed = 0;    bwr.read_consumed = 0;    status_t err;    do {        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)            err = NO_ERROR;        else            err = -errno;        if (mProcess->mDriverFD <= 0) {            err = -EBADF;        }    } while (err == -EINTR);     if (err >= NO_ERROR) {        if (bwr.write_consumed > 0) {            if (bwr.write_consumed < (ssize_t)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;}</span>
@4 ProcessState::self()->startThreadPool();startThreadPool的实现如下所示:
<span style="font-family:SimSun;font-size:18px;">void ProcessState::startThreadPool(){    AutoMutex _l(mLock);    if (!mThreadPoolStarted) {        mThreadPoolStarted = true;/* 表明一个进程只能启动一个线程池 */        spawnPooledThread(true);    }}</span>
   继续分析spawnPooledThread,代码实现如下:
<span style="font-family:SimSun;font-size:18px;">void ProcessState::spawnPooledThread(bool isMain){    if (mThreadPoolStarted) {        String8 name = makeBinderThreadName();        sp<Thread> t = new PoolThread(isMain);/* 为了方便分析代码,这里的isMain为true */        t->run(name.string());    }} </span>
    Poolthread是在ProcessState类中定义的的一个类,继续分析Poolthread的内部实现,代码如下所示:
<span style="font-family:SimSun;font-size:18px;">class PoolThread : public Thread{public:    PoolThread(bool isMain)        : mIsMain(isMain)    {    }    protected:    virtual bool threadLoop()    {           /* 这里注意,新创建的线程都会调用该方法 */        IPCThreadState::self()->joinThreadPool(mIsMain);        return false;    }    const bool mIsMain;};</span>
@5 IPCThreadState::self()->joinThreadPool();{CodeTracker_5}
@@5.1 按照android的要求,新创建的线程都会调用这个函数,实现如下所示
<span style="font-family:SimSun;font-size:18px;">void IPCThreadState::joinThreadPool(bool isMain){    /* 如果isMain为真,需要循环处理,将请求信息写到mOut中,最后一起发送 */    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);    set_sched_policy(mMyThreadId, SP_FOREGROUND);            status_t result;    do {        processPendingDerefs();//处理已经死亡的BBinder对象        // now get the next command to be processed, waiting if necessary        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);       mOut.writeInt32(BC_EXIT_LOOPER);    talkWithDriver(false);}</span>
 @@5.2 这里有2个重要的方法,processPendingDerefs和getAndExecuteCommand,分别对这2个方法进行说明
     processPendingDerefs主要是处理已经死亡的BBinder,实现如下所示:
<span style="font-family:SimSun;font-size:18px;">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();        }    }}</span>
    getAndExecuteCommand主要是发送命令和读取请求,代码实现如下:
<span style="font-family:SimSun;font-size:18px;">status_t IPCThreadState::getAndExecuteCommand(){    status_t result;    int32_t cmd;     result = talkWithDriver();    if (result >= NO_ERROR) {        size_t IN = mIn.dataAvail();        if (IN < sizeof(int32_t)) return result;        cmd = mIn.readInt32();        result = executeCommand(cmd);//处理消息        set_sched_policy(mMyThreadId, SP_FOREGROUND);    }     return result;}</span>
   即无论是ProcessState::self()->startThreadPool()还是IPCThreadState::self()->joinThreadPool();本质上都是IPCThreadState::self()->joinThreadPool();最后都会talkWithDriver,从而与binder驱动交互。
@6 总结:
    binder本身支持多线程和同步操作
   到目前为止,总共有2个线程在为service服务,一个是startThreadPool()线程池中启动的,另一个是自身joinThreadPool()启动的
    Binder通信逻辑和业务逻辑之间的关系:Binder仅仅是通信机制,业务可以基于binder,也可以基于其他IPC通信机制
    Binder复杂的原因:Android通过封装,将业务和通信巧妙的融合在了一起,交互关系如图3所示:

        图3 Binder机制中通信架构与业务架构之间的关系 
   这里,BpServiceManager和BnServiceManager专注于业务逻辑层的交互;BpBinder和BBinder专注于通信层的交互。
@7 接下来对IServiceManager家族中BnServiceManager进行分析,查看BpServiceManager将请求addService发送给service_manager后,查看service_manager具体做了什么(实际上对于注册服务来讲,所谓BnServiceManager就是service_manager),请看下一篇文章->Binder_Native:service_manager的主函数main的分析


    

    

    


















0 0