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里有一份service list记录着这些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继承IServiceManager和BpRefBase两个类别.
而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;
    //增加service到service 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.而这个command SVC_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 架构".
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值