Android Binder 之奇幻國度

        话说Android国度中每个行程都各自为政.这些行程大致上分为两族, Server 跟 Application. Server族的阶级比较高, 而Application族的阶级低一级了. 也因为如此Sever族比较接近核心政府OS, Application 若有需要政府的支持, 常就需要透过Server 族来帮忙. 然而, Application跟Server本来就不同族群的人了, 沟通自然成问题. 再说在Server族中的Service又不只有一个, Application又要如何指定哪一个Service来帮忙传达需求呢? 这两个问题就要从Binder机制谈起了.

        由于每个service各司其职, 有管界面的SurfaceFlingerservice, 管声音的 AudioFlinger, 管媒体播放的MediaPlayerService等等, 这些Service各管各的功能, 在指派指令方面上总是个问题. 这时,Android国王就派出一个人作为ServiceManager, 其功用就是用来管理这些各自为政的service.之后Application若有需要特定的需求只要透过ServiceManager来指派就可以了.ServiceManager, Service, 和 Application 都是不同个体的行程, 沟通依然是个问题. 英明的Android国王当然知道行程沟通是一定要解决的, 所以就又颁布了一套Binder机制请所有在Android国度中的行程务必遵守. 建立Binder机制需要分为Server端,Client 端, BinderAdapter, 和 Binder核心. 基本沟通流程如下:

角色分配:

Client端:  Application

Server端:  特定的service

1.  Client端利用BinderAdapter 通知 ServiceManger, 请他指派特定的service支持.

2.  ServiceManager就会在他自己的管理清单看看有没有Client端需要的Service.

3.  若有找到就借由BinderAdapter 回传一个Binderproxy给Client端使用. 若没找到就回个error讯息.

4.     Client端就可以藉由这块 Binderproxy来使唤service帮他做事了.

        BinderAdapter到底是甚么?ServiceManager的管理清单是怎么产生的? Binder proxy指的到底是甚么? 这种种的一切, 到底是是事出有因, 还是天意捉弄? 在冥冥之中, 自有安排. 如何安排, 就让我们从程序代码看下去.

       首先先从ServiceManager开始分析, 再一开机时候,android 系统在做初始化时会启动一些native service, ServiceManger就是其中之一.

// init.rc

service servicemanager /system/bin/servicemanager

    class core

    user system

    group system

    critical

    onrestart restart zygote

    onrestart restart media

    onrestart restart surfaceflinger

    onrestart restart drm

ServiceManager一启动到底处理哪些事情, 让我们继续看下去

// service_manager.c

int main(int argc, char **argv)

{

    struct binder_state *bs;

    void *svcmgr = BINDER_SERVICE_MANAGER;

 

    bs = binder_open(128*1024);

 

    if (binder_become_context_manager(bs)) {

        ALOGE("cannot become context manager (%s)\n", strerror(errno));

        return -1;

    }

 

    svcmgr_handle = svcmgr;

    binder_loop(bs, svcmgr_handler);

    return 0;

}

由上面的程序代码, 可以知道ServiceManager一启动作三件事.

1. 打开binder 设备

// binder.c

struct binder_state *binder_open(unsigned mapsize)

{

    struct binder_state *bs;

 

    bs = malloc(sizeof(*bs));

    if (!bs) {

        errno = ENOMEM;

        return 0;

    }

    // 打开Binder设备档/dev/binder, 并回传一个档案描述符.

    bs->fd = open("/dev/binder", O_RDWR);

    if (bs->fd < 0) {

        fprintf(stderr,"binder: cannot open device (%s)\n",

                strerror(errno));

        goto fail_open;

    }

 

    bs->mapsize = mapsize;

    //利用刚刚得到的档案描述符加上传进来的mapsize大小, 产生一个

    // memory 映射. 优点在于直接存取这块内存相当于存取这个映像档案.

    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

    if (bs->mapped == MAP_FAILED) {

        fprintf(stderr,"binder: cannot map device (%s)\n",

                strerror(errno));

        goto fail_map;

    }

 

        /* TODO: check version */

 

    return bs;

 

fail_map:

    close(bs->fd);

fail_open:

    free(bs);

    return 0;

}

 

2. 设定为Contextmanager

// binder.c

int binder_become_context_manager(struct binder_state *bs)

{

    // 利用 ioctl 设定为 context manager.

    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);

}

 

3. 启动 Binderloop来监听需求.

// binder.c

void binder_loop(struct binder_state *bs, binder_handler func)

{

    int res;

    struct binder_write_read bwr;

    unsigned readbuf[32];

 

    bwr.write_size = 0;

    bwr.write_consumed = 0;

    bwr.write_buffer = 0;

   

    readbuf[0] = BC_ENTER_LOOPER;

    // 开始启动looper 用来监控接收Client端的需求.

    binder_write(bs, readbuf, sizeof(unsigned));

 

    for (;;) {

        bwr.read_size = sizeof(readbuf);

        bwr.read_consumed = 0;

        bwr.read_buffer = (unsigned) readbuf;

        // 利用ioctl函数搭配BINDER_WRITE_READ对Binder的档设备读取

        //  data.

        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

 

        if (res < 0) {

            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));

            break;

        }

        //  将读到的data作相对应的处理. 假若有需求要处理, data会夹带

        // BR_TRANSACTION command. 依照程序代码的分析结果, 之后会去呼

        // 叫传进来的 function pointer: func.

        res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);

        if (res == 0) {

            ALOGE("binder_loop: unexpected reply?!\n");

            break;

        }

        if (res < 0) {

            ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));

            break;

        }

    }

}

到目前为止, ServiceManager就在一个无穷循环中等待着呼唤. 究ServiceManager这样等着, 其他的行程需要他的时候, 又是如何藉BinderAdapter通知他呢? 在故事前面有提到,ServiceManager的功用式来管理Android 国度里所有的Service,而在ServiceManager里有一份servicelist记录着这些Service. 这种种的一切到底是如何演变的呢?在分析这一切的变化, 先来介绍一下Binder 核心角色

1.  IBinder: 接口类, 里面的功能需要其衍生类别去实作

2.  BBinder: IBinder的子类别, 用来作为实作Service端的.

    ps:ServiceManager是属于一个特殊的service, 所以实作并不会继承这个类

      别来实作, 里应来说他是个主要的程序, 因此接收并处理要求的机制是

      另外设计, 详见以上的binder_loop分析.

3.  BpBinder: IBinder的子类别, 用来提供给Client端使用.

接下来在介绍一下 BinderAdapter的角色

1.Parcel: 用来存放从Binder 设备中来的data.

2.ProcessState: 维护所有的service的Binderproxy.

3.IPCThreadState: 负责传送, 接收跟处理要求.

这几个角色之间的关系并不单纯, 这一切就由mediaserver说起.

//init.rc

service media /system/bin/mediaserver

    class main

    user media

    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc

    ioprio rt 4

 

// main_mediaserver.cpp

int main(int argc, char** argv)

{

    sp<ProcessState> proc(ProcessState::self());

    sp<IServiceManager> sm = defaultServiceManager();

    ALOGI("ServiceManager: %p", sm.get());

    AudioFlinger::instantiate();

    MediaPlayerService::instantiate();

    CameraService::instantiate();

    AudioPolicyService::instantiate();

    ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();

}

由上面的程序代码可以知道, mediaserver 一启动作的事请如下:

1. 打开binder 设备

// main_mediaserver.cpp

sp<ProcessState> proc(ProcessState::self());

 

// ProcessState.cpp

sp<ProcessState> ProcessState::self()

{

    Mutex::Autolock _l(gProcessMutex);

    //只要gProcess不是NULL, 就直接回传, 否则就new 一个 ProcessState 物

    //件, 由此可知此设计是辅合单利模式, 一个类别永远只有一个对象.

    if (gProcess != NULL) {

        return gProcess;

    }

    gProcess = new ProcessState;

    return gProcess;

}

 

ProcessState::ProcessState()

    : mDriverFD(open_driver())    //打开Binder设备档/dev/binder, 并回传

                               //一个档案描述符.

    , mVMStart(MAP_FAILED)

    , mManagesContexts(false)

    , mBinderContextCheckFunc(NULL)

    , mBinderContextUserData(NULL)

    , mThreadPoolStarted(false)

    , mThreadPoolSeq(1)

{

    if (mDriverFD >= 0) {

        // XXX Ideally, there should be a specific define for whether we

        // have mmap (or whether we could possibly have the kernel module

        // availabla).

#if !defined(HAVE_WIN32_IPC)

        // mmap the binder, providing a chunk of virtual address space to receive transactions.

        //利用刚刚得到的档案描述符加上BINDER_VM_SIZE大小, 产生一个

        // memory 映射.

        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.");

}

2. 获得ServiceManager的BinderProxy.

// main_mediaserver.cpp

sp<IServiceManager> sm = defaultServiceManager();

 

// IServiceManager.cpp

sp<IServiceManager> defaultServiceManager()

{

    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

   

    {

        AutoMutex _l(gDefaultServiceManagerLock);

        if (gDefaultServiceManager == NULL) {

            gDefaultServiceManager = interface_cast<IServiceManager>(

                ProcessState::self()->getContextObject(NULL));

        }

    }

   

    return gDefaultServiceManager;

}

在c++的世界里, 对象型态转化方式只有 static_cast, dynamic_cast, const_cast和reinterpreter_cast 这四种, 并没有interface_cast的方式? 这究竟是怎么一回事? 程序代码之前, 绝无秘密. 果然在一处发现了interface_cast的足迹.

//IInterface.h

template<typename INTERFACE>

inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)

{

    return INTERFACE::asInterface(obj);

}

 

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

 

 

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

 

由上面的演化便可以发现interface_cast<IServiceManager>(

                ProcessState::self()->getContextObject(NULL));

的演变, 演变如下:

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

IServiceManager:: asInterface(ProcessState::self()->getContextObject(NULL));

new BpServiceManager(ProcessState::self()->getContextObject(NULL));

到头来原来interface_cast<IServiceManager>的真面目就是new 一个BpServiceManager的对象. 也因为如此, 之后只要在Android国度中只要一发现interface_cast<IXXX>, 就知道它的真面目一定是new 一个BpXXX对象.

    然而故事到这还没完, BpServiceManager建构子里带的参数又是甚么呢? 由其建构子宣告只能知道是IBinder的型态, 但详细对象到底是甚么呢? 一切源头就要由ProcessState::self()->getContextObject(NULL)开始分析

// 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);

 

    if (e != NULL) {

        IBinder* b = e->binder;

        if (b == NULL || !e->refs->attemptIncWeak(this)) {

            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;

}

    就这样抽丝剥卷的一路分析下来, 发现ProcessState::self()->getContextObject(NULL) 得到的东西竟是BpBinder 对象.也就是Binder proxy.

3. 开始跟ServiceManager注册各个Service.

// main_mediaserver.cpp

AudioFlinger::instantiate();         //注册 AudioFlinger service

MediaPlayerService::instantiate();   //注册 MediaPlayerService service

CameraService::instantiate();       //注册 CameraService service

AudioPolicyService::instantiate();    //注册 AudioPolicyService service

 

   就拿注册CameraService的案例来解释跟ServiceManager注册的流程. 在c++的程序语法中, 一旦由类别带出来的函数一定是定义在类别中的static函数. 所以去收查了一下CameraService类别, 发现竟然没有instantiate函数宣告或是定义. 整件事情到此已经进入朴硕离迷的罗生门, 正当失望之际, 突然发现了一个嫌疑犯 BinderService 类别. 在c++的程序语法中, 类别的函数事可以继承使用的, 也就是说子类别若没有重写父类别的函数,哪怕是static函数. 也是极有可能所呼叫的函数是定义在父类别. CameraService刚好继承自BinderService.

 

//BinderService.h

template<typename SERVICE>

class BinderService

{

public:

    static status_t publish(bool allowIsolated = false) {

        sp<IServiceManager> sm(defaultServiceManager());

        return sm->addService(String16(SERVICE::getServiceName()), new

              SERVICE(), allowIsolated);

    }

 

    static void publishAndJoinThreadPool(bool allowIsolated = false) {

        sp<IServiceManager> sm(defaultServiceManager());

        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(),

            allowIsolated);

        ProcessState::self()->startThreadPool();

        IPCThreadState::self()->joinThreadPool();

    }

 

    static void instantiate() { publish(); }

 

    static status_t shutdown() {

        return NO_ERROR;

    }

};

故事到此越是明朗化, 原来CameraService::instantiate() 演变如下

CameraService::instantiate()

defaultServiceManager()->addService(String16(CameraService::getServiceName()),

                         new CameraService (), false);

BpServiceManager(BpBinder(0)) -> addService(String16(CameraService::getServiceName()),  new CameraService (),

                 false);

 

//IServiceManager.cpp

virtual status_t addService(const String16& name, const sp<IBinder>& service,

            bool allowIsolated)

    {

        // 产生data跟 reply的容器.用来存放从Binder设备得来的data货是

        // 要传送给Binder设备的data.

        Parcel data, reply;

        // 写入interface Token: android.os.IServiceManager

        // 详见 IMPLEMENT_META_INTERFACE(ServiceManager,

        //"android.os.IServiceManager"); in IServiceManager.cpp

        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

        // 写入service 名子: media.camera

        // 详见 CameraService.h

        data.writeString16(name);

        // 写入 service 物件: new CameraService ()

        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;

    }

最后一道remote()->transact 程序代码中的 remote()指的是甚么? 这可有学问了.

事情都到了这个地步了, 还是谜团重重. 真是叫人匪思所疑. 既然是跟呼叫 transact 有关的一定是跟Binder的接口有关系. 先来看一下BpServiceManager类别怎么来的.

// IServiceManager.cpp

class BpServiceManager : public BpInterface<IServiceManager>

//IInterface.h

template<typename INTERFACE>

class BpInterface : public INTERFACE, public BpRefBase

{

public:

                                BpInterface(const sp<IBinder>& remote);

 

protected:

    virtual IBinder*            onAsBinder();

};

 

由此样板可以知道, BpInterface继承IServiceManagerBpRefBase两个类别.

而BpServiceManager继承BpInterface类别, 所以可以推得 BpServiceManager 就是IServiceManager的孙类别. 继续看下去IServiceManager类别又是怎么产生的?

//IServiceManager.h

class IServiceManager : public IInterface

//IInterface.h

class IInterface : public virtual RefBase

{

public:

            IInterface();

            sp<IBinder>         asBinder();

            sp<const IBinder>   asBinder() const;

           

protected:

    virtual                     ~IInterface();

    virtual IBinder*            onAsBinder() = 0;

};

总结一下这些类别的继承关系.

BpServiceManager 继承 BpInterface,

BpInterface 继承 IServiceManager

IServiceManager 继承IInterface

层层的分析下来, BpServiceManager 还真的跟 IInterface 类别有关系阿, 在C++的程序语法中, 只要衍生类别一旦要建构出对象, 一定先从基础类别开始呼叫建构子. 在前面的故事中,mediaserver 一启动时就经由defaultServiceManager函数去new了一个BpServiceManager 对象, 一早上面的继承关系其呼叫建构子的顺序如下:

// IInterface.cpp

IInterface::IInterface()

    : RefBase() {    //呼叫RefBase建构子

}

 

// IInterface.h

// 这里的建构子实作是利用Macro来定义的, 详见

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

IServiceManager:: IServiceManager() { }

 

由于BpInterface中没有宣告预设建构子, 所以直接往下呼叫.

 

// IServiceManager.cpp

BpServiceManager(const sp<IBinder>& impl)

        : BpInterface<IServiceManager>(impl)  //呼叫父类别的自定义建构子

    {

    }

 

// IInterface.h

// 其中 INTERFACE 为 IServiceManager

template<typename INTERFACE>

inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)

    : BpRefBase(remote)   //呼叫父类别的自定义建构子

{

}

 

//Binder.cpp

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

    : mRemote(o.get()), mRefs(NULL), mState(0)

{

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

 

    if (mRemote) {

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

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

    }

}

到这里便会发现 BpServiceManager 建构子会再去呼叫 BpRefBase 建构子, 之后会发现所带的BpBinder 对象就指向mRemote这个参数. 故事真的是千变万化阿, 在去查阅一下BpRefBase类别竟然发现了 remote()的足迹.

// Binder.h

class BpRefBase : public virtual RefBase

{

protected:

                            BpRefBase(const sp<IBinder>& o);

    virtual                 ~BpRefBase();

    virtual void            onFirstRef();

    virtual void            onLastStrongRef(const void* id);

    virtual bool            onIncStrongAttempted(uint32_t flags, const void*

                         id);

 

    inline  IBinder*        remote()                { return mRemote; }

    inline  IBinder*        remote() const          { return mRemote; }

private:

                            BpRefBase(const BpRefBase& o);

    BpRefBase&              operator=(const BpRefBase& o);

 

    IBinder* const          mRemote;

    RefBase::weakref_type*  mRefs;

    volatile int32_t        mState;

};

最后一道remote()->transact 程序代码中的 remote()指的就是BpBinder对象.

// 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) {

        // 会利用一个statci self函数去new 一个 IPCThreadState 对象就是

        // 要说 IPCThreadState 也是一个单利模式设计.

        status_t status = IPCThreadState::self()->transact(

            mHandle, code, data, reply, flags);

        if (status == DEAD_OBJECT) mAlive = 0;

        return status;

    }

 

    return DEAD_OBJECT;

}

 

// IPCThreadState.cpp

status_t IPCThreadState::transact(int32_t handle,

                                  uint32_t code, const Parcel& data,

                                  Parcel* reply, uint32_t flags)

{

    // do something

    // 将所要传送的data写入mOut 容器里, 此data里含有cmd跟

    // binder_transaction_data

    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data,

                          NULL);

    if (reply) {

            //详见以下分析

            err = waitForResponse(reply);

    } else {

            Parcel fakeReply;

            err = waitForResponse(&fakeReply);

    }

 

    //so something

}

 

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)

{

     //so something

     while (1) {

        // 详见以下分析

        if ((err=talkWithDriver()) < NO_ERROR) break;

        err = mIn.errorCheck();

        if (err < NO_ERROR) break;

        if (mIn.dataAvail() == 0) continue;

       

        cmd = mIn.readInt32();

        switch (cmd) {

              //do something case

       default:

            //执行从Binder设备得到的command, 并且呼叫BBinder对象的

            //onTransact 函数.

            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;

 

}

 

status_t IPCThreadState::talkWithDriver(bool doReceive)

{

     // 检查一下Binder设备是否被开启

     if (mProcess->mDriverFD <= 0) {

        return -EBADF;

     }

    

     binder_write_read bwr;

 

     //do something

 

     bwr.write_size = outAvail;

     bwr.write_buffer = (long unsigned int)mOut.data();

 

     //do something

     // 藉由ioctl搭配 BINDER_WRITE_READ 将data写

     // 入Binder 设备.

     if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)

            err = NO_ERROR;

       //do something

}

 

4.ServiceManager 一收到request command, 马上作addservice的处理.

在故事前面, ServiceManager一启动就开始在做Binder loop, 目的就是用来监控目前在Binder 设备的变化.一旦Binder设备中有变化, 就会触发ServiceManager对象中的binder_parse函数, 而这函数中有个funtion pointer参数, 正是ServiceManager在作Binder loop一开始注册的 svcmgr_handler 函数.

//service_manager.c

int svcmgr_handler(struct binder_state *bs,

                   struct binder_txn *txn,

                   struct binder_io *msg,

                   struct binder_io *reply)

{

      struct svcinfo *si;

      //do something

     

      switch(txn->code) {

    //检查service list上的service

    case SVC_MGR_GET_SERVICE:

    case SVC_MGR_CHECK_SERVICE:

        s = bio_get_string16(msg, &len);

        ptr = do_find_service(bs, s, len, txn->sender_euid);

        if (!ptr)

            break;

        bio_put_ref(reply, ptr);

        return 0;

    //增加serviceservice list

    case SVC_MGR_ADD_SERVICE:

        s = bio_get_string16(msg, &len);

        ptr = bio_get_ref(msg);

        allow_isolated = bio_get_uint32(msg) ? 1 : 0;

        if (do_add_service(bs, s, len, ptr, txn->sender_euid, allow_isolated))

            return -1;

        break;

    // 检视service list

    case SVC_MGR_LIST_SERVICES: {

        unsigned n = bio_get_uint32(msg);

 

        si = svclist;

        while ((n-- > 0) && si)

            si = si->next;

        if (si) {

            bio_put_string16(reply, si->name);

            return 0;

        }

        return -1;

    }

    default:

        ALOGE("unknown code %d\n", txn->code);

        return -1;

    }

 

    bio_put_uint32(reply, 0);

    return 0;

}

在BpServiceManager呼叫transact函数来写入Binder设备时, 有带一个command为 ADD_SERVICE_TRANSACTION, 因此, ServiceManager从Binder 设备也会读到一个类似ADD_SERVICE_TRANSACTION的command:SVC_MGR_ADD_SERVICE. 而这个commandSVC_MGR_ADD_SERVICE 作的事正是 do_add_service.

int do_add_service(struct binder_state *bs,

                   uint16_t *s, unsigned len,

                   void *ptr, unsigned uid, int allow_isolated)

{

    struct svcinfo *si;

 

    if (!ptr || (len == 0) || (len > 127))

        return -1;

    //检查此service是否允许可以被注册, 详细请看 svc_can_register 实作.

    if (!svc_can_register(uid, s)) {

        ALOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",

             str8(s), ptr, uid);

        return -1;

    }

    //查询Service list 上的service item

    si = find_svc(s, len);

    if (si) {

        //在service list中已经有service的si了, 就不再另外新增了. 但需要

        //重新联机Binder机制.

        if (si->ptr) {

            svcinfo_death(bs, si);

        }

        si->ptr = ptr;

    } else {

        //在service list中新增一笔service 的si.

        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));

        if (!si) {

            ALOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n",

                 str8(s), ptr, uid);

            return -1;

        }

        si->ptr = ptr;

        si->len = len;

        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));

        si->name[len] = '\0';

        si->death.func = svcinfo_death;

        si->death.ptr = si;

        si->allow_isolated = allow_isolated;

        si->next = svclist;

        svclist = si;

    }

    // 开始与Client端搭起Binder机制.

    binder_acquire(bs, ptr);

    binder_link_to_death(bs, ptr, &si->death);

    return 0;

}

5.Client端开始启动Binder loop, 用来监控Server端的回应状态.

Service端既然有个Binder loop作监控, Client端也不甘示弱也是需要有个Binder loop来监控. 在前面做完各个Service 将ADD_SERVICE_TRANSACTION command写入Binder 设备之后, 就开始利用ProcessState跟IPCThreadState来启动Binder loop.

// main_mediaserver.cpp

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

 

// ProcessState.cpp

void ProcessState::startThreadPool()

{

    AutoMutex _l(mLock);

    if (!mThreadPoolStarted) {

        mThreadPoolStarted = true;

        spawnPooledThread(true);

    }

}

 

void ProcessState::spawnPooledThread(bool isMain)

{

    if (mThreadPoolStarted) {

        int32_t s = android_atomic_add(1, &mThreadPoolSeq);

        char buf[16];

        snprintf(buf, sizeof(buf), "Binder_%X", s);

        ALOGV("Spawning new pooled thread, name=%s\n", buf);

        sp<Thread> t = new PoolThread(isMain);

        t->run(buf);

    }

}

 

class PoolThread : public Thread

{

public:

    PoolThread(bool isMain)

        : mIsMain(isMain)

    {

    }

   

protected:

    // 这是个Callback function, 一旦Thread 对象中的run函数被呼叫,

   // threadLoop 函数就会被触发.

    virtual bool threadLoop()

    {

        IPCThreadState::self()->joinThreadPool(mIsMain);

        return false;

    }

   

    const bool mIsMain;

};

一路追寻下来, 发现此流程会再起另外一个thread去启动 Thread pool. 此Thread pool里作的事就跟Main thread最后作的事是一样的.都是呼叫IPCThreadState::self()->joinThreadPool程序代码.

// IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)

{

    // 将BC_ENTER_LOOPER command写入 Binder设备. 表示目前进入Binder

    // loop 状态.

    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

 

    //设定优先权为SP_FOREGROUND确保在作Transaction的时候不被中断.

    set_sched_policy(mMyThreadId, SP_FOREGROUND);

 

    status_t result;

    do {

        int32_t cmd;

        //do something

        // 详见以下分析

        result = talkWithDriver();

        if (result >= NO_ERROR) {

            size_t IN = mIn.dataAvail();

            if (IN < sizeof(int32_t)) continue;

            cmd = mIn.readInt32();

            result = executeCommand(cmd);

        }

       

        // 由于在作executeCommand时, 会将优先权设为正常状态, 所以在

        //下一次进loop前,要再把优先权设高.

        set_sched_policy(mMyThreadId, SP_FOREGROUND);

        //do something

 

    } while (result != -ECONNREFUSED && result != -EBADF);

    // 将BC_EXIT_LOOPER command写入 Binder设备. 表示目前离开Binder

    // loop 状态.

    mOut.writeInt32(BC_EXIT_LOOPER);

    //关掉从Binder设备接收data的功能. 预设是打开.

    talkWithDriver(false);

}

 

status_t IPCThreadState::talkWithDriver(bool doReceive)

{

    if (mProcess->mDriverFD <= 0) {

        return -EBADF;

    }

   

    binder_write_read bwr;

   

    // Is the read buffer empty?

    const bool needRead = mIn.dataPosition() >= mIn.dataSize();

   

    //do something

 

    // This is what we'll read.

    if (doReceive && needRead) {

        // 将mIn Parcel 容器信息设定给 binder_write_read 中的read buffer,

        // 以作为从Binder 设备读取data.

        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 {

       //开是对Binder 设备作存取.

       if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)

            err = NO_ERROR;

        else

            err = -errno;

 

       //do something

 

    } while (err == -EINTR);

 

    //do something

    return err;

}

故事发展到这里, 只能说拍案叫绝, 原来joinThreadPool就是在作 Binder loop的动作. 请注意这里的joinThreadPool是由mediaserver另外起的thread来执行. 那接下来的 joinThreadPool 动作就是由mediaserver的main thread来执行, 究竟是为了甚么, mediaserver非得还要再另外起个Thread去执行binder loop. 造就了本身形成有两个Binder loop在监控. 这只能说是个不解之谜阿.亦或者说一个当作主要的Binder loop, 另外一个当作工作 Binder loop用. 至于两个差别,只能问Google了.

总结

纵观Android的Binder机制, Android国王运用了一个很简单的Clent/Server机制来作各个行程的沟通协调, 并指派ServiceManager来管理众多Service,并提供Client端管道来寻求Server端的支持. 总结上面的分析流程归纳如下:

1. 一开机, ServiceManager一启动便打开Binder设备

2. ServiceManager 启动 Binder loop 开始监控Binder设备中的command

3. mediaserver一启动便打开Binder设备

4.mediaserver 获得Binder Proxy: BpServiceManager

5. 利用BinderProxy来注册各个的Service

6.Binder proxy 将command ADD_SERVICE_TRANSACTION 写入Binder设备.

7.mediaserver 启动 Main thread的Binderloop和Work Thread的 Binderloop来监控Binder 设备着状态.

8. ServiceManager的Binder loop 一查觉Binder设备起了变化便读取command.

9. ServiceManager从Binder loop读到的command是 SVC_MGR_ADD_SERVICE

10.ServiceManager 开始新增一笔记录到他所管理的service list里.

11.Service Manager 便将reply的信息些入Binder 设备.

12. mediaserver 的binderloop一查觉到Binder设备有Reply数据便读取.

这整个沟通管道冥冥之中自有安排, 沟通的主要关键有IPCThreadState 中的talkWithDriver跟executeCommand,让我们看不透的是在这安排之前多了多到层层关卡, 这些迷样的关系就称为"Binder 架构"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值