android binder proxy

来源:互联网 发布:snmp端口号及作用 编辑:程序博客网 时间:2024/06/01 07:26

前面讲了里面binder的接口,怎么将service注册到系统,以及service的接口是怎么调用的,接下来要分析client端怎么拿到binder proxy和调用到service端去。

1、和cameraservice进程进行binder通信,首先要拿到它的proxy对象,代码如下

 sp<IServiceManager> sm = defaultServiceManager(); //servicemanger 的proxy   sp<IBinder> binder;     do {        binder = sm->getService(String16(kCameraServiceName)); //通过service name从servicemanager拿到service 的proxy        if (binder != 0) {           break;         }         ALOGW("CameraService not published, waiting...");         usleep(kCameraServicePollDelay);    } while(true);    gCameraService = interface_cast<::android::hardware::ICameraService>(binder);

1)defaultServiceManager()

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

2)ProcessState 和 IPCThreadState前面已经介绍过了

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)) {            if (handle == 0) {                // Special case for context manager...                // The context manager is the only object for which we create                // a BpBinder proxy without already holding a reference.                // Perform a dummy transaction to ensure the context manager                // is registered before we create the first local reference                // to it (which will occur when creating the BpBinder).                // If a local reference is created for the BpBinder when the                // context manager is not present, the driver will fail to                // provide a reference to the context manager, but the                // driver API does not return status.                //                // Note that this is not race-free if the context manager                // dies while this code runs.                //                // TODO: add a driver API to wait for context manager, or                // stop special casing handle 0 for context manager and add                // a driver API to get a handle to the context manager with                // proper reference counting.                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);              e->binder = b;            if (b) e->refs = b->getWeakRefs();            result = b;        } else {            // This little bit of nastyness is to allow us to add a primary            // reference to the remote proxy when this team doesn't have one            // but another team is sending the handle to us.            result.force_set(b);            e->refs->decWeak(this);        }    }    return result;}

b = new BpBinder(handle); //主要的在这里,创建了一个BpBinder对象,传入handle0

3)sm->getService(String16(kCameraServiceName));

根据binder的继承关系,我们知道这里会调用到BpServiceManager 的getService()

virtual sp<IBinder> getService(const String16& name) const    {        unsigned n;        for (n = 0; n < 5; n++){  //尝试5此还是获取失败,就返回null            sp<IBinder> svc = checkService(name);            if (svc != NULL) return svc;            ALOGI("Waiting for service %s...\n", String8(name).string());            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();}

4)可以拿到的话,最终通过readStrongBinder();返回一个Ibinder对象,实际是BpBinder对象,前面画的继承关系图有标出来。

sp<IBinder> Parcel::readStrongBinder() const{    sp<IBinder> val;    readStrongBinder(&val);    return val;}status_t Parcel::readStrongBinder(sp<IBinder>* val) const{    return unflatten_binder(ProcessState::self(), *this, val);}

status_t unflatten_binder(const sp<ProcessState>& proc,    const Parcel& in, sp<IBinder>* out){    const flat_binder_object* flat = in.readObject(false);    if (flat) {        switch (flat->type) {            case BINDER_TYPE_BINDER:                  *out = reinterpret_cast<IBinder*>(flat->cookie);                return finish_unflatten_binder(NULL, *flat, in);            case BINDER_TYPE_HANDLE:                *out = proc->getStrongProxyForHandle(flat->handle);                return finish_unflatten_binder(                    static_cast<BpBinder*>(out->get()), *flat, in);        }    }    return BAD_TYPE;}

//下面这段代码很重要,很重要,很重要

switch(flat->type) {

            case BINDER_TYPE_BINDER:  //如果是在同一个进程,会进这个case

                *out =reinterpret_cast<IBinder*>(flat->cookie);

                returnfinish_unflatten_binder(NULL, *flat, in);

            case BINDER_TYPE_HANDLE:  //不是同一个进程,会走这个case

                //这个上面已经贴过了

                //在ProcessState::getStrongProxyForHandle(int32_thandle) 会创建出一个Bpbinder实例,传入的handle至关重要。

                *out =proc->getStrongProxyForHandle(flat->handle);

                return finish_unflatten_binder(

                   static_cast<BpBinder*>(out->get()), *flat, in);

        }

5)gCameraService =interface_cast<::android::hardware::ICameraService>(binder);

interface_cast 的定义

在frameworks\native\include\binder\Iinterface.h

inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){    return INTERFACE::asInterface(obj); }

 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;                                                    \    }                                                                   \

搞了那么多玩意,理解成下面就可以了,看懂了继承关系图就不难理解

gCameraService =interface_cast<::android::hardware::ICameraService>(binder);

等价于

gCameraService = new BpCameraService(binder);


2、拿到proxy 端后,调用它的接口,有会经历那些流程呢?

还是以TestService为例,调用ItestService::test(0)接口,实际调用了BpTestService::test(0)


virtual status_t test(int api) {          Parcel data, reply;          data.writeInterfaceToken(ITestService::getInterfaceDescriptor());          data.writeInt32(api);          remote()->transact(TEST, data, &reply);          result = reply.readInt32();          return result;   }

接着调用remote()->transact(TEST, data, &reply);

remote()返回的就是创建BpTestService

时传入的BpBinder对象。

所以会调用到BpBinder的transact() 


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); //传入的这个mHandler很重要,就是上面//unflatten_binder 得到的handle        if (status == DEAD_OBJECT) mAlive = 0;        return status;    }    return DEAD_OBJECT;}  

接着进入IPCThreadState::transact()

status_t IPCThreadState::transact(int32_t handle,                                  uint32_t code, const Parcel& data,                                  Parcel* reply, uint32_t flags){    ...    if ((flags & TF_ONE_WAY) == 0) {  //如果是同步的,会等到server端处理结束才返回        if (reply) {            err = waitForResponse(reply);        } else {            Parcel fakeReply;            err = waitForResponse(&fakeReply);        }        ...    } else {  //走这里表示是异步的        err = waitForResponse(NULL, NULL);    }        return err;}

然后调用到IPCThreadState:: waitForResponse ()

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){    uint32_t cmd;    int32_t err;    while (1) {        if ((err=talkWithDriver()) < NO_ERROR) break;        ....        default:            err = executeCommand(cmd);            if (err != NO_ERROR) goto finish;            break;        }    }    return err;}

最后会进入到talkWithDriver(),通过ioctl将数据传给driver,这样server就会从binder driver读到数据,然后进行处理。

status_t IPCThreadState::talkWithDriver(bool doReceive){    ...    do {        IF_LOG_COMMANDS() {            alog << "About to read/write, write size = " << mOut.dataSize() << endl;        }#if defined(__ANDROID__)        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;        }        IF_LOG_COMMANDS() {            alog << "Finished read/write, write size = " << mOut.dataSize() << endl;        }    } while (err == -EINTR);   ...    return err;}

--------------------------------------------------------------------------------------------------------------------------------------------

proxy端最重要的一个东西之一就是binder driver 返回的handle,是一个init32_t 类型,也就是一个整形。binder proxy端的创建和通过ioctl 调用binder driver的流程就分析完了...