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对象,传入handle为0
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的流程就分析完了...
- Android Binder - service proxy
- android binder proxy
- android binder 中的proxy 模式
- Android Binder(二)——Service Proxy Object
- Binder Proxy技术方案
- Android Binder -什么是binder
- Android Binder
- Android Binder
- android Binder
- Android-binder
- android Binder
- Android--Binder
- android binder
- Android Binder
- android binder
- android: binder
- 【Android】Binder
- Android BInder
- 剩蛋开博致辞
- 文章标题
- Oracle 12c 没有scott 解决方法
- IC AND IC_CF
- PHP面试总结-1
- android binder proxy
- Qt之文件操作QFile于QFileInfo
- 实现memcpy函数
- 浅谈自适应滤波器---(自适应陷波器)
- Linux系统编程——特殊进程之孤儿进程
- python--字符串格式化(format)(一)
- pyalgotrade教程5--多标的策略
- Softmax classifier
- Redis-cli命令最新总结