前面讲了里面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
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
}
}
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的流程就分析完了...