android binder proxy

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

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

 sp sm = defaultServiceManager(); //servicemanger 的proxy
   sp 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 defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

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

sp ProcessState::getContextObject(const sp& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp 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对象,传入handle 0

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

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

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

   virtual sp 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 Parcel::readStrongBinder() const
{
    sp val;
    readStrongBinder(&val);
    return val;
}
status_t Parcel::readStrongBinder(sp* val) const
{
    return unflatten_binder(ProcessState::self(), *this, val);
}

status_t unflatten_binder(const sp& proc,
    const Parcel& in, sp* out)
{
    const flat_binder_object* flat = in.readObject(false);

    if (flat) {
        switch (flat->type) {
            case BINDER_TYPE_BINDER:  
                *out = reinterpret_cast(flat->cookie);
                return finish_unflatten_binder(NULL, *flat, in);
            case BINDER_TYPE_HANDLE:
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast(out->get()), *flat, in);
        }
    }
    return BAD_TYPE;
}

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

switch(flat->type) {

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

                *out =reinterpret_cast(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(out->get()), *flat, in);

        }

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

interface_cast 的定义

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

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

 android::sp I##INTERFACE::asInterface(                \
            const android::sp& obj)                   \
    {                                                                   \
        android::sp intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast(                          \
                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的流程就分析完了...















你可能感兴趣的:(binder)