Binder框架(2)
通过MediaServer详细解析Binder内部实现细节。
1. MediaServer的入口函数
int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); //获得一个ProcessState实例 // MediaServer作为ServiceManager的客户端,需要向ServiceManager注册服务。 // 调用defaultServiceManager,获取一个IServiceManager。 sp<IServiceManager> sm = defaultServiceManager(); AudioFlinger::instantiate(); // 初始化音频系统的AudioFlinger服务。 MediaPlayerService::instantiate() // 多媒体的MediaPlayerService。 CameraService::instantiate(); AudioPolicyService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
2. ProcessState
ProcessState是以单例模式设计的, 每个进程只有一个ProcessState。每个进程在使用binder机制通信时,均需要维护一个ProcessState实例来描述当前进程在binder通信时的binder状态。
2.1 ProcessState的作用:
- 打开/dev/binder设备, 对返回的fd使用mmap,这样Binder驱动就会分配一块内存来接收数据,即提供来与内核Binder驱动交互的通道。(在构造函数中调用open_driver())。
- 创建一个thread, 该线程负责与内核中的binder模块进行通信,称该线程为Pool Thread。(通过调用startThreadPool()函数创建并启动)
- 为指定的handle创建一个BpBinder对象,并管理该进程中所有的BpBinder对象。(提供函数getContextObject(handle)返回)
2.2 BpBinder
(1) BpBinder和BBinder都继承于IBinder。BpBinder是客户端用来与Server交互的代理类,p即proxy。BBinder是与proxy相对的一端,是proxy交互的目的端。BpBinder代表客户端,BBinder代表服务端。两者是一一对应的,即某个BpBinder只能与对应的BBinder交互。
客户端通过BpBinder的transact函数向Binder设备发送调用请求的数据,它的构造函数如下:
BpBinder(int32_t handle);
通过BpBinder的构造函数发现,BpBinder会将当前通信中server的handle记录下来,当有数据发送时,会通知Binder Driver数据的发送目标。Binder系统通过handle值来标识对应的BBinder。
(2) ProcessState通过如下方式来获取BpBinder对象:
ProcessState::self()->getContextObject(handle);
ProcessState会维护一个BpBinder的Vector mHandleToObject,每当ProcessState创建一个BpBinder的实例时,回去查询mHandleToObject,如果对应的 handle已经有binder指针,那么不再创建,否则创建binder并插入到mHandleToObject中。 (3) ProcessState创建的BpBinder实例,一般情况下会作为参数构建一个客户端的代理接口,这个代理接口的形式为BpINTERFACE,例如在与ServiceManager通信时,客户端会创建一个代理接口BpServiceManager, 由它来实现IServiceManager的业务函数。
从sp<IServiceManager> sm = defaultServiceManager() 开始看一下创建BpServiceManager的过程。
sp<IServiceManager> defaultServiceManager() { ... gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL)); ... return gDefaultServiceManager; }
由上面可以指定ProcessState::self()->getContextObject(handle)返回一个BpBinder,所以上面代码等价于:
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
interface_cast实现了BpBinder与IServiceManager的关联。 interface_cast其实是一个模板函数:
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
即:sp<IServiceManager> interface_cast(const sp<IBinder>& obj) {
return IServiceManager::asInterface(obj); // 将BnBinder作为参数传给了IServiceManager!
}
在IServiceManager的asInterface函数中,创建了BpServiceManager。下面看下BpServiceManager的构造:
BpServiceManager::BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { // 调用基类BpInterface的构造函数 } template<typename INTERFACE> inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) { // 调用基类构造函数 } BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL), mState(0) { //mRemote最终保存BpBinder }
由此可见,BpServiceManager的一个变量mRemote指向了BpBinder。
调用了defaultServiceManager()函数之后,得到了两个重要的对象:
- 一个是BpBinder对象,它的handle值为0.
- 一个是BpServiceManager对象,它的mRemote值是BpBinder.
3. IServiceManager家族中的类
3.1 类继承关系
(1) BpServiceManager同时继承于IServiceManager和BpInterface, 而BpInterface继承于BpRefBase。
(2) BnServiceManager同时继承于IServiceManager和BBinder。MyServiceManager继承于BnServiceManager。
3.2 注意点:
- IServiceManager,BpServiceManager, BnServiceManager都于业务逻辑相关。
- BnServiceManager同时继承于BBinder,说明它可以直接参与Binder通信。
- BpServiceManager派生过程看似乎与BpBinder没有关系,但实际上它的一个成员mRemote的值指向BpBinder。
- BnServiceManager是一个虚类,需要子类来具体实现业务函数。
4. 向ServiceManager注册MediaPlayerService
4.1 业务层的工作
MediaPlayerService::instantiate() { defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService()); }
根据前面知道,defaultServiceManager()返回的BpServiceManager,它是IServiceManager的后代。
virtual status_t BpServiceManager::addService(const String16& name, const sp<IBinder>& service) { Parcel data, replay; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); data.writeStrongBinder(service); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); // remote()返回mRemote, 即BpBinder对象。 return err == NO_ERROR ? reply.readInt32() : err; }
addService()是业务层的函数,它的作用就是将请求数据打包,然后交给通信层处理。
4.2 通信层的工作
4.2.1 BpBinder与Binder设备交互的秘密就在于transact()函数。
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) { status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags); // 实际的通信工作由IPCThreadState完成 if (status == DEAD_OBJECT) { mAlive = 0; } return status; } return DEAD_OBJECT; }
4.2.2 IPCThreadState
IPCThreadState与Binder通信有关,每个线程有一个。
(1) IPCThreadState的构造
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self())
, mMyThreadId(androidGetTid()) {
pthread_setspecific(gTLS, this); // 把自己设置到线程本地存储中去
clearCaller();
// mIn和mOut是两个Parcel, 看成是发送和接收命令的缓冲区
mIn.setDataCapicity(256); // mIn用来接收来自Binder设备的数据
mOut.setDataCapicity(256); // mOut用来存储发往Binder设备的数据
}
Pool thread会不停的查询BD中是否有数据可读,如果有将其读出并保存到mIn,同时不停的检查mOut是否有数据需要向Binder设备发送,如果有,则将其内容写入到Binder设备中。
(2) transact函数 BpBinder::transact()函数通过IPCThreadState::transact()函数来向mOut中写入数据。
status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t err = data.errorCheck(); flags |= TF_ACCEPT_FDS; ...... err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); ...... err = waitForResponse(reply); ...... return err; }
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) { binder_transaction_data tr; // binder_transaction_data是binder设备通信的数据结构 tr.target.handle = handle; // handle的值传给target, 用于识别目的端,其中0是ServiceMananger的标志。 tr.code = code; // code是消息码,用于switch/case。 tr.flags = binderFlags; const status_t err = data.errorCheck(); if (err == NO_ERROR) { tr.data_size = data.ipcDataSize(); tr.data.ptr.buffer = data.ipcData(); tr.offsets_size = data.ipcObjectsCount() * sizeof(size_t); tr.data.ptr.offsets = data.ipcObjects(); } else if (statusBuffer) { tr.flags |= TF_STATUS_CODE; *statusBuffer = err; tr.data_size = sizeof(status_t); tr.data.ptr.buffer = statusBuffer; tr.offsets.size = 0; tr.data.ptr.offsets = NULL; } else { retrun (mLastError = err); } mOut.writeInt32(cmd); // 把命令写到mOut中去,并没有直接发出去 mOut.write(&tr, sizeof(tr)); return NO_ERROR; }
函数writeTransactionData只是把addService的请求信息写到mOut中去,发送请求和接收回复由IPCThreadState::waitForResponse()来实现。
status_t IPCThreadState::waitForResponse(Parcel* reply, status_t* acquireResult) { int32_t cmd; int32_t err; while(1) { if ((err = talkWithDriver()) < NO_ERROR) { break; } err = mIn.errorCheck(); if (err < NO_ERROR) { break; } if (mIn.dataAvail() == 0) { continue; } cmd = mIn.readInt32(); switch (cmd) { case BR_TRANSACTION_COMPLETE: { if (!reply && !acquireResult) { goto finish; } } break; ...... default: { err = excuteCommand(cmd); //重点! if (err != NO_ERROR) { goto finish; } break; } } } finish: if (err != NO_ERROR) { if (acquireResult) { *acqueirResult = err; if (reply) reply->setError(err); mLastError = err; } } return err; }
发送了请求数据,假设收到了回复,接下来由executeCommand函数负责解析并执行mIn中的数据。
status_t IPCThreadState::executeCommand(int32_t cmd) { BBinder* obj; RefBase::weakref_type* refs; status_t result = NO_ERROR; switch (cmd) { case BR_ERROR: { result = mIn.readInt32(); } break; case BR_TRANSACTION: { binder_transaction_data tr; result = mIn.read(&tr, sizeof(tr)); if (result != NO_ERROR) break; Parcel buffer; Parcel reply; if (tr.target.ptr) { sp<BBinder> b((BBinder*)tr.cookie); // b实际上是实现BnServiceXXX的那个对象。 const status_t error = b->transact(tr.code, buffer, &reply, 0); if (error < NO_ERROR) reply.setError(error); } else { const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0); //the_context_object是IPCThreadState的一个全局变量。 if (error < NO_ERROR) reply.setError(error); } } break; case BR_DEAD_BINDER: { // 收到Binder驱动发来的service死掉的消息。 BpBinder* proxy = (BpBinder*)mIn.readInt32; proxy->sendObituary(); mOut.writeInt32(BC_DEAD_BINDER_DONE); mOut.writeInt32((int32_t)proxy) } break; ...... cast BR_SPAWN_LOOPER: { mProcess->spawnPooledThread(false); } break; default: result = UNKNOWN_ERROR; break; } ...... if (result != NO_ERROR) { mLastError = result; } return result; }
talkWithDriver()函数负责从Binder设备中读写数据。
status_t IPCThreadState::talkWithDriver(bool doReceive) { binder_write_read bwr; //binder_write_read是与binder设备交换数据的结构。 const bool needRead = mIn.dataPosition()->mIn.dataSize(); const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0; // 填充请求命令 bwr.write_size = outAvail; bwr.write_buffer = (long unsigned int) mOut.data(); if (doReceive && needRead) { bwr.read_size = mIn.dataCapacity(); // 填充接收数据缓冲区的信息。如果以后收到数据,就直接填在mIn中了。 bwr.read_buffer = (long unsigned int) mIn.data(); } else { bwr.read_size = 0; } if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR; bwr.write_consumed = 0; bwr.read_consumed = 0; status_t err; do { #if define(HAVE_ANDROID_OS) if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) { err = NO_ERROR; } else { err = -error; } #else err = INVALID_OPERATION;
#endif } while (err == -EINTR);
if (err >= NO_ERROR) { if (bwr.write_consumed > 0) { if (bwr.write_consumed < (ssize_t)mOut.dataSize()) { mOut.remove(0, bwr.write_consumed); } else { mOut.setDataSize(0); } } if (bwr.read_consumed > 0) { mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); } return NO_ERROR; } return err; }
5. startThreadPool()和joinThreadPool();
startThreadPool()创建一个新线程PoolThread,该线程的loop中也会调用IPCThreadState::self()->joinThreadPool()来读取Binder设备查看是否有请求。另外主线程也调用joinThreadPool()读取Binder设备。
可见当前有两个线程为Service服务。
void IPCThreadState::joinThreadPool(bool isMain) { mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); // isMain为true时,需要循环处理,先把请求信息写到mOut中去,待会一起发出去。 androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT); status_t result; do { int32_t cmd; if (mIn.dataPosition() >= mIn.dataSize()) { size_t numPending = mPendingWeakDerefs.size(); if (numPending > 0) { for (size_t i = 0; i < numPending; i++) { RefBase::weakref_type* refs = mPendingWeakDerefs[i]; refs->decWeak(mProcess.get()); } mPendingWeakDerefs.clear(); } // 处理已经死亡的BBinder对象。 numPending = mPendingWeakDerefs.size(); if (numPending > 0) { for (size_t i = 0; i < numPending; i++) { BBinder* obj = mPendingStrongDerefs[i]; obj->decStrong(mProcess.get()); } mPendingWeakDerefs.clear(); } } result = talkWithDriver(); if (result >= NO_ERROR) { size_T IN = mIn.dataAvail(); if (IN < sizeof(int32_T)) { continue; } cmd = mIn.readInt32(); result = executeCommand(cmd); //处理消息 } ...... } while(result != -ECONNERFUSED && result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false); }