由代码来补充部分:
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
sp<ProcessState> proc(ProcessState::self()),这一行代码会建立ProcessState对象,一个进程只有唯一的一个ProcessState对象,而ProcessState类的作用是来打开/dev/binder设备。这也就说明了一个问题,一个进程只不可能同时存在多个对/dev/binder的操作。
sp<IServiceManager> sm = defaultServiceManager(),这一行代码要做的事情参见上图。1、创建一个BpBinder。2、由BpBinder对象创建BpServiceManger对象。(为什么要采取如此不自然的方式,可以看一下这两个对象继承的基类)。完成这一步骤的最重要的作用在于以后对于IServiceManager对象的方法的调用,都将会由其子类BpServiceManger的方法来实现(这样做的意义何在?这样的作用仅仅在于我们可以重用IServiceManager的代码,别忘了我们还有一个类似的继承自IServiceManager的类,它叫做BnServiceManger)。这样说起来似乎过于抽象,好在我们可以举一个例子,接下去的代码就会有例子出现。
CameraService::instantiate(),这一行的代码(前面还有两行?相信我,他们绝对是几乎一样的实现,当然我是指从Binder层来说,而不是指与硬件相关的交互)。我们仍然先画出结构图:
我们需要一点代码来辅助我们的分析,CameraService::instantiate的代码如下:
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("media.camera"), new CameraService());
}。
仍然是由defaultServiceManager函数开始,但是我们此时已经拥有了对象,而这样做的目的仅仅在于我们调用的会是BpServiceManger类中的addService方法,而不是IServiceManager基类的addService方法。我们试着去寻找BpServiceManger类中的addService函数。在此之前有个需要我们注意的地方new CameraService,这里实例化了一个CameraService对象,他的基类们是我们要注意的,因为之后我们将不得不关注于整套虚函数调用的机制。CameraService类的继承关系我在图中已经画出:IBinder->BBinder(ICmaerService两个基类)->BnInterface->BnCamerService->CamerService,看起来足够复杂,不幸的是这个继承模式是有意义的。
我们将思路再拉回来,接着看BpServiceManger类中addService的实现:
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readInt32() : err;
}
Data.writeInterfaceToken与data.writeString这两行我们无需关注,因为它们完成一些接口命名之类的事情。来看看data.writeStrongBinder会做些什么:
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
而flatten_binder代码如下:
status_t flatten_binder(const sp<ProcessState>& proc,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == NULL) {
LOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;
obj.handle = handle;
obj.cookie = NULL;
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = local->getWeakRefs();
obj.cookie = local;
}
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = NULL;
obj.cookie = NULL;
}
return finish_flatten_binder(binder, obj, out);
}
我们先来关注IBinder *local = binder->localBinder()这一行代码,binder变量是一个IBinder类的指针,那么是否是说我们要调用的是IBinder类的localBinder函数呢?我去查看代码,发现它是一个虚函数,说明我们将会调用的是指针指向的对象的localBinder函数。还没忘记我们刚才特别提到的地方吧?defaultServiceManager()->addService(String16("media.camera"), new CameraService());它是一个CamerService对象,理论上来说我们应该是按照沿基类向上的方式查找实现,CamerService-> BnCamerService->BnInterface->ICmaerService,BBinder两个基类-> IBinder这样的查找顺序。我们在BBinder类的实现中找到了这个localBinder这个函数,那么这里将会调用的就是BBinder对象的实现:
BBinder* BBinder::localBinder()
{
return this;
}很明显代码接着会走到橙色部分。
那么finish_flatten_binder又会做些什么呢?代码我就不贴了,它的作用是更新相应的数据偏移量指针。但是写到这里,我们似乎越看越糊涂,这些步骤有什么意义?Parcel类为什么又突然出现了?我们来做一下补充,首先是Parcel类的作用,它是用来完成数据的序列化的,也就是完成数据投递之前的准备工作的。投递的数据都会放在这个类的一个实例中。我去查找Parcel类的定义的时候发现它没有虚函数,也就是说关于投递数据序列化的操作都会在这个类及其实现中完成。我们终于可以暂时的摆脱那些虚函数们了。
我们的工作还远没有结束,我们还没有看到数据是如何投递的?那么我们接着来看addService函数中的最后一个函数调用remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply),它明显是用来投递数据的,如何投递?这里我们要弄清楚两个问题:1、remote函数返回的是什么?也就是transcat是哪个对象的方法。2、transcat如何与底层交互。
我们先来看看第一个问题。先前已经讨论过,addService方法的调用是来自BpServiceManager对象,我们忘了给出另一套类继承的机制:RefBase->IServiceManager,BpRefBase两个基类->BpInterface->BpServiceManager。 那么这里的remote方法(与addService一样均属于BpServiceManager),将会调用BpServiceManager的基类BpRefBase的remote方法。其实现时:inline IBinder* remote() { return mRemote; }。问题在于这里的mRemote会是BBinder呢还是BpBinder?这个讨论使得我们不得不又再次回到之前的代码中去(确实复杂,但还不至于会使人疑惑。)答案在很早以前的defaultServiceManager函数中,之前我们并没有分析过这个函数,是因为我们之前并不需要知道这个函数太多的细节,我们只用知道它是为了完成BpServiceManger对象的建立,但实际上,它还完成了另一个功能,将BpRefBased对象的mRemote成员初始化为BpBinder对象。来看代码:
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
ProcessState::self()->getContextObject 此函数返回一个BpBinder对象,当然这个对象的指针是其基类指针IBander。然后由interface_cast再次调用,而为mRemote成员的赋值也同样发生在BpServiceManger对象的建立之时,调用BpServiceManger类的构造函数: BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl),再次调用BpInterface类的构造函数
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
就在绿色的代码部分了,具体的分析请看另一篇文档,这里只是补充。
第一个问题,为我们指明了方向,也就是通讯的时候会采用BpBinder对象的transact函数。这样我们来继续看一下第二个问题,现在我们直奔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);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
今天只能写这么多,binder机制的路还很长很长!
http://wsqhs.spaces.live.com/blog/cns!94F639580F58209C!642.entry