ServiceManager的实现位于:
4.2:/frameworks/base/cmds/servicemanager/
4.3:frameworks/native/cmds/servicemanager/
service servicemanager /system/bin/servicemanager class core //core类服务 user system //用户名 group system //用户组 critical //重要service, 如果4分钟内crush4次以上,则重启系统并进入recovery onrestart restart zygote //servicemanager重启以后,自动重启zygote onrestart restart media //同上 onrestart restart surfaceflinger //同上 onrestart restart drm //同上ServiceManager是一个可执行文件,所以,我们从main函数看起(frameworks/base/cmds/servicemanager/servicemanager.c):
int main(int argc, char **argv) { struct binder_state *bs; void *svcmgr = BINDER_SERVICE_MANAGER; bs = binder_open(128*1024); if (binder_become_context_manager(bs)) { ALOGE("cannot become context manager (%s)\n", strerror(errno)); return -1; } svcmgr_handle = svcmgr; binder_loop(bs, svcmgr_handler);//svcmgr_handle为具体的请求处理逻辑 return 0; }简单来说,ServiceManager的启动分为三个步骤:
struct binder_state *binder_open(unsigned mapsize) { struct binder_state *bs; bs = malloc(sizeof(*bs)); if (!bs) { errno = ENOMEM; return 0; } bs->fd = open("/dev/binder", O_RDWR);//上一节讲过,这里会转入内核态,执行binder_open,创建binder_proc if (bs->fd < 0) { fprintf(stderr,"binder: cannot open device (%s)\n", strerror(errno)); goto fail_open; } bs->mapsize = mapsize;//mapsize = 128KB bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);//上一节讲过,这里会转入内核态,执行binder_mmap //在内核态创建相同size的缓冲区,并分配第一个物理页面,计算内核缓冲区地址和用户缓冲区地址的偏移量 if (bs->mapped == MAP_FAILED) { fprintf(stderr,"binder: cannot map device (%s)\n", strerror(errno)); goto fail_map; } /* TODO: check version */ return bs; fail_map: close(bs->fd); fail_open: free(bs); return 0; }如果上一节binder driver部分的内容有比较好的理解的话,这边的代码应该比较好理解的,顺便看看binder_state的实现:
struct binder_state { int fd; void *mapped; unsigned mapsize; };
int binder_become_context_manager(struct binder_state *bs) { return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); }灰常简单的实现,有木有? 让我们来回忆一下,上一节的内容,ioctl的调用会转入到binder driver的binder_ioctl函数来处理BINDER_SET_CONTEXT_MGR:
case BINDER_SET_CONTEXT_MGR: if (binder_context_mgr_node != NULL) { printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n"); ret = -EBUSY; goto err; } ret = security_binder_set_context_mgr(proc->tsk); if (ret < 0) goto err; if (binder_context_mgr_uid != -1) { if (binder_context_mgr_uid != current->cred->euid) { printk(KERN_ERR "binder: BINDER_SET_" "CONTEXT_MGR bad uid %d != %d\n", current->cred->euid, binder_context_mgr_uid); ret = -EPERM; goto err; } } else binder_context_mgr_uid = current->cred->euid; binder_context_mgr_node = binder_new_node(proc, NULL, NULL);//binder_context_mgr_node->proc = servicemanager if (binder_context_mgr_node == NULL) { ret = -ENOMEM; goto err; } binder_context_mgr_node->local_weak_refs++; binder_context_mgr_node->local_strong_refs++; binder_context_mgr_node->has_strong_ref = 1; binder_context_mgr_node->has_weak_ref = 1; break;忽略安全检查等代码,上面的代码就是设定了全局变量binder_context_mgr_node,并增加引用计数。
void binder_loop(struct binder_state *bs, binder_handler func) { int res; struct binder_write_read bwr; unsigned readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0; readbuf[0] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof(unsigned));//binder driver会通过binder_thread_write函数处理BC_ENTER_LOOPER指令 for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (unsigned) readbuf; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//读取client/service的请求 if (res < 0) { ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno)); break; } res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);//处理请求 if (res == 0) { ALOGE("binder_loop: unexpected reply?!\n"); break; } if (res < 0) { ALOGE("binder_loop: io error %d %s\n", res, strerror(errno)); break; } } }
class IServiceManager : public IInterface { public: DECLARE_META_INTERFACE(ServiceManager); /** * Retrieve an existing service, blocking for a few seconds * if it doesn't yet exist. */ virtual sp<IBinder> getService( const String16& name) const = 0; /** * Retrieve an existing service, non-blocking. */ virtual sp<IBinder> checkService( const String16& name) const = 0; /** * Register a service. */ virtual status_t addService( const String16& name, const sp<IBinder>& service, bool allowIsolated = false) = 0; /** * Return list of all existing services. */ virtual Vector<String16> listServices() = 0; enum { GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, CHECK_SERVICE_TRANSACTION, ADD_SERVICE_TRANSACTION, LIST_SERVICES_TRANSACTION, }; };从接口中,我们看到SeviceManager提供了4个功能:
class BpServiceManager : public BpInterface<IServiceManager> { public: BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { } virtual sp<IBinder> getService(const String16& name) const { ...... //实现啥的,我们后面再看 } virtual sp<IBinder> checkService( const String16& name) const { ...... } virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) { ...... } virtual Vector<String16> listServices() { ...... } };
sp<IServiceManager> defaultServiceManager() { if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//单例模式 { AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); } } return gDefaultServiceManager; }这里可以把defaultServiceManager分解为三个步骤:
sp<ProcessState> ProcessState::self() { Mutex::Autolock _l(gProcessMutex);//又是单例模式,因为是进程信息,所以,一个进程只能有一个实例 if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess; }1.2 ProcessState的构造函数:
ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) { // XXX Ideally, there should be a specific define for whether we // have mmap (or whether we could possibly have the kernel module // availabla). #if !defined(HAVE_WIN32_IPC) // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); close(mDriverFD); mDriverFD = -1; } #else mDriverFD = -1; #endif } LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); }是不是觉得有点熟悉?又看到mmap了,但是mDriverFD是哪来的呢?上面很容易忽略的地方有个open_driver(),让我们来看看。
static int open_driver() { int fd = open("/dev/binder", O_RDWR); if (fd >= 0) { fcntl(fd, F_SETFD, FD_CLOEXEC); int vers; status_t result = ioctl(fd, BINDER_VERSION, &vers); if (result == -1) { ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); close(fd); fd = -1; } if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { ALOGE("Binder driver protocol does not match user space protocol!"); close(fd); fd = -1; } size_t maxThreads = 15; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1) { ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); } } else { ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); } return fd; }现在,更加熟悉了:
int fd = open("/dev/binder", O_RDWR);所以,ProcessState::self()做了两件事:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) { return getStrongProxyForHandle(0); }2.2 getStrongProxyForHandle
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)//handle = 0 { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { // We need to create a new BpBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { 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; }2.3 lookupHandleLocked
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) //handle = 0 { const size_t N=mHandleToObject.size(); if (N <= (size_t)handle) { handle_entry e; e.binder = NULL; e.refs = NULL; status_t err = mHandleToObject.insertAt(e, N, handle+1-N); if (err < NO_ERROR) return NULL; } return &mHandleToObject.editItemAt(handle); }那么mHandleToObject是什么(framworks/native/include/binder/PCState.h):
Vector<handle_entry>mHandleToObject;好吧,还得看看handle_entry是什么:
struct handle_entry { IBinder* binder; RefBase::weakref_type* refs; };所以,mHandleToObject是一个cache,如果handle参数对应的handle_entry已经存在,则返回handle_entry,否则先向mHandleToObject存入空的handle_entry项,再返回空的handle_entry项。
IBinder* b = e->binder;//所以,这里b可能为空 if (b == NULL || !e->refs->attemptIncWeak(this)) {//b也有可能已经被释放 //构造新的BpBinder b = new BpBinder(handle); //注意:handle=0 e->binder = b; //给e赋值 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); }
BpBinder::BpBinder(int32_t handle) : mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(NULL) { ALOGV("Creating BpBinder %p handle %d\n", this, mHandle); extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle); }虽然,很多次提到BpBinder,但还是第一次看到BpBinder的真容。BpBinder其实很简单,只要记得mHandle成员即可,它和内核态的binder_ref.desc相对应。不过,mHandle=0对BpBinder来说是个特例,因为它可以在内核态没有其对应binder_ref的情况下,进行binder通信。因为binder driver直接把所有mHandle=0的BpBinder直接关联到到全局binder_context_mgr_node,省略了binder_ref这个“中继器”。
interface_cast<IServiceManager>(new BpBinder(0))3.1 interface_cast宏(frameworks/native/include/binder/IInterface):
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }这里的INTERFACE 为IServiceManager。
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");IMPLEMENT_META_INTERFACE的宏的声明(frameworks/native/include/binder/IInterface.h):
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const android::String16 I##INTERFACE::descriptor(NAME); \ const android::String16& \ I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ 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; \ } \ I##INTERFACE::I##INTERFACE() { } \ I##INTERFACE::~I##INTERFACE() { } \代入android.os.IServiceManager,效果如下:
const android::String16 IServiceManager::descriptor("android.os.IServiceManager"); const android::String16& IServiceManager::getInterfaceDescriptor() const { return IServiceManager::descriptor; } android::sp<IServiceManager> IServiceManager::asInterface( const android::sp<android::IBinder>& obj) // obj = new BpBinder(0); { android::sp<IServiceManager> intr; if (obj != NULL) { intr = static_cast<IServiceManager*>( obj->queryLocalInterface( IServiceManager::descriptor).get()); if (intr == NULL) { intr = new BpServiceManager(obj); } } return intr; } IServiceManager::IServiceManager() { } IServiceManager::~IServiceManager() { }3.3 BpBinder.queryLocalInterface()
sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor) { return NULL; }因为BpBinder其实是一个binder proxy,当然是没有local对象的。
obj->queryLocalInterface(IServiceManager::descriptor).get()返回NULL,所以,intr = null,最终:
intr = new BpServiceManager(obj);然后,返回BpServiceManager实例。
virtual sp<IBinder> getService(const String16& name) const { unsigned n; for (n = 0; n < 5; n++){//只要5次checkService有一次成功,getService就成功 sp<IBinder> svc = checkService(name); if (svc != NULL) return svc; ALOGI("Waiting for service %s...\n", String8(name).string()); sleep(1); } return NULL; }原来getSerivce就是对checkService的封装,为了提高checkService的成功率,而给了checkService最多5次的尝试机会。个人理解,Binder通信机制的可靠性还是比较可以接受的,所以,这里多次尝试checkSerivce的目的还是为了减少因Service未能及时启动并将自己注册到ServiceManager中而导致checkservice失败的概率。考虑到Android核心Service的启动时机,实际上第一次尝试checkService应该就会成功。
virtual sp<IBinder> checkService( const String16& name) const { Parcel data, reply;//因为篇幅的关系,Parcel类不做分析,简单来说,一个数据容器而已 data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name);//name为请求的service name,以MediaPlayer为例,name="media.player" remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); return reply.readStrongBinder(); }这里的remote()函数继承自BpRefBase:
inline IBinder* remote() { return mRemote; }而BpServiceManager的mRemote为BpBinder。
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);//mHandle = 0; code = CHECK_SERVICE_TRANSACTION
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
可以看到,BpBinder->transact的调用了IPCThreadState的同名函数。先来看看IPCThreadState::self()的实现。
IPCThreadState* IPCThreadState::self() { if (gHaveTLS) { restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); if (st) return st; return new IPCThreadState; } if (gShutdown) return NULL; pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { if (pthread_key_create(&gTLS, threadDestructor) != 0) { pthread_mutex_unlock(&gTLSMutex); return NULL; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart; }这个函数的实现涉及到TLS(Thread Local Storage),TLS简单来说,就是同一个变量在不同的线程中相互独立。具体到上面的代码来说,gTLS是同一个变量,但是函数
pthread_getspecific(k);//k = gTLS的返回值却随着调用线程的不同而不同。相同的还有pthread_setpecific函数。因为IPCThreadState是一个线程内唯一的变量,所以TLS机制很好的满足了代码的需求。相似的,java语言也通过Thread_local类提供了TLS的支持。不过C/C++语言的TLS机制是基于TCB(Thread Control Block)实现,而Java的TLS则是基于Thread类的localValues成员和inheritableValues成员实现。
IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()),//注意,mProcess的赋值 mMyThreadId(androidGetTid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0) { pthread_setspecific(gTLS, this);//把自己保存到LTS中 clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256); }回到2,现在的代码可以理解为:
status_t status = IPCThreadState->transact(mHandle, code, data, reply, flags);//mHandle = 0; code = CHECK_SERVICE_TRANSACTION
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;//支持回复文件binder ...... if (err == NO_ERROR) { ...... err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); } ...... if ((flags & TF_ONE_WAY) == 0) { ...... if (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } ...... } } else { err = waitForResponse(NULL, NULL);//第二个NULL,表示无需read //上一节中也讲到,binder driver被设计为不允许异步Binder回复请求 } return err; }从函数名来看,writeTransactionData函数向Binder driver写入数据,而waitForResponse函数,负责等待并读取binder driver的返回。
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 driver通信了 tr.target.handle = handle;//handle = 0 tr.code = code; //code = CHECK_SERVICE_TRANSACTION tr.flags = binderFlags; tr.cookie = 0; tr.sender_pid = 0;//不必在意sender_pid和sender_euid,稍后binder driver会给他们正确的赋值 tr.sender_euid = 0; const status_t err = data.errorCheck(); if (err == NO_ERROR) { //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 { return (mLastError = err); } mOut.writeInt32(cmd);//cmd = BC_TRANSACTION mOut.write(&tr, sizeof(tr));//mOut是IPCThreadState的成员,Parcel类型 return NO_ERROR; }这里构造了一个binder_transaction_data结构体,并对其进行了赋值,这个操作是进行binder通信的必要准备,但是,这个binder_transaction_data居然没有被发送给binder driver而是存入了mOut?这个是什么情况?
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { int32_t cmd; int32_t err; while (1) { if ((err=talkWithDriver()) < NO_ERROR) break;//这里面有大文章 ...... if (mIn.dataAvail() == 0) continue; cmd = mIn.readInt32(); ...... switch (cmd) { ...... case BR_REPLY: { binder_transaction_data tr; err = mIn.read(&tr, sizeof(tr)); ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY"); if (err != NO_ERROR) goto finish; if (reply) { if ((tr.flags & TF_STATUS_CODE) == 0) { reply->ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); } else { err = *static_cast<const status_t*>(tr.data.ptr.buffer); freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); } } else { freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); continue; } } goto finish; ...... } } finish: ...... return err; }waitForResponse一进来就调用了函数talkWithDriver函数,那就先看看它的实现吧。
status_t IPCThreadState::talkWithDriver(bool doReceive)//default,doReceive=true { if (mProcess->mDriverFD <= 0) { return -EBADF; } binder_write_read bwr; // Is the read buffer empty? const bool needRead = mIn.dataPosition() >= mIn.dataSize();//输入缓冲无数据,所以需要从binder driver读取数据 // We don't want to write anything if we are still reading // from data left in the input buffer and the caller // has requested to read the next data. const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0; bwr.write_size = outAvail; bwr.write_buffer = (long unsigned int)mOut.data();//记得么? writeTransactionData函数中,在mOut中保存了一个binder_transaction_data结构体 // This is what we'll read. if (doReceive && needRead) { bwr.read_size = mIn.dataCapacity(); bwr.read_buffer = (long unsigned int)mIn.data(); } else { bwr.read_size = 0; bwr.read_buffer = 0; } ...... bwr.write_consumed = 0; bwr.read_consumed = 0; status_t err; do { ...... if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)//终于看到了ioctl err = NO_ERROR; else err = -errno; ...... } while (err == -EINTR); //因为binder driver中是通过wait_event_interrupt函数进行等待,所以系统中断会导致binder_thread_read在读取到数据前返回 //所以,当err=-EINTR时,需要再次调用ioctl读取数据 ...... if (err >= NO_ERROR) {//根据ioctl的执行结果,调整mIn和mOut的状态 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; }talkWithDriver函数,像它的名字一样,真正完成了与binder driver的交互,实现了数据的发送和等待。关于
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)可以回忆前面IPCThreadState::self()和ProcesssState::self()的实现,mProcess是当前进程的信息,而mDriverFD则是“dev/binder”的文件描述符。确定一下,当前bwr的状态:
bwr.write_size = mOut.data;//sizeof(writeTransactionData); bwr.write_buffer = mOut.data(); //binder_transaction_data的地址 bwr.write_consumed = 0; bwr.read_size = mIn.dataCapacity(); //265 bwr.read_buffer = mIn.data(); //empty buffer bwr.read_consumed=0;
void binder_loop(struct binder_state *bs, binder_handler func) { int res; struct binder_write_read bwr; unsigned readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0; readbuf[0] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof(unsigned)); for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (unsigned) readbuf; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//读取到请求以后,ioctl返回 ...... res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);//回忆一下Service manager的启动,我们知道func = svcmgr_handler ...... } }service manager进程通过直接直接调用ioctl函数来等待client的请求。因为我们刚才通过BpServiceManager类从Client进程发送请求,所以,我们知道ioctl函数返回时,bwr的状况应该是这样的:
binder_transaction_data tr;
tr.code = CHECK_SERVICE_TRANSACTION
bwr.read_consumed=sizeof(binder_transaction_data);bwr.read_buffer=readbuf=tr;
再回忆一下,1. BpServiceManager.checkService的实现:
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name);//name为请求的service name,以MediaPlayer为例,name="media.player"buffer中应该保存了“android.os.IServiceManager”和请求的service name(e.g. "media.player")
int binder_parse(struct binder_state *bs, struct binder_io *bio, uint32_t *ptr, uint32_t size, binder_handler func) { int r = 1; uint32_t *end = ptr + (size / 4); while (ptr < end) { uint32_t cmd = *ptr++; ...... switch(cmd) {//cmd = BR_TRANSACTION ...... case BR_TRANSACTION: { struct binder_txn *txn = (void *) ptr; ...... if (func) { unsigned rdata[256/4]; struct binder_io msg; struct binder_io reply; int res; bio_init(&reply, rdata, sizeof(rdata), 4);//因为rdata是一个空缓冲,所以从rdata初始化的reply目前也是空的,稍后将用于保存请求处理结果 bio_init_from_txn(&msg, txn);//txn=bwr.read_buffer,即请求数据,用请求数据初始化msg结构体 res = func(bs, txn, &msg, &reply);//func = svcmgr_handler binder_send_reply(bs, &reply, txn->data, res);//回复请求处理结果 } ptr += sizeof(*txn) / sizeof(uint32_t); break; } ...... } } return r; }11. svcmgr_handler
int svcmgr_handler(struct binder_state *bs, struct binder_txn *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si; uint16_t *s; unsigned len; void *ptr; uint32_t strict_policy; int allow_isolated; if (txn->target != svcmgr_handle) return -1; // Equivalent to Parcel::enforceInterface(), reading the RPC // header with the strict mode policy mask and the interface name. // Note that we ignore the strict_policy and don't propagate it // further (since we do no outbound RPCs anyway). strict_policy = bio_get_uint32(msg);//一般strict_policy = 0 s = bio_get_string16(msg, &len);//s=“android.os.IServiceManager” if ((len != (sizeof(svcmgr_id) / 2)) || memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { fprintf(stderr,"invalid id %s\n", str8(s)); return -1; } switch(txn->code) {//code=SVC_MGR_CHECK_SERVICE case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE://SVC_MGR_GET_SERVICE和SVC_MGR_CHECK_SERVICE是等效的 s = bio_get_string16(msg, &len);//读取service name ptr = do_find_service(bs, s, len, txn->sender_euid);//根据service name查找service if (!ptr) break; bio_put_ref(reply, ptr);//ptr为handle, 把ptr保存到reply中 return 0; ...... } default: ALOGE("unknown code %d\n", txn->code); return -1; } bio_put_uint32(reply, 0); return 0; }从代码中可以看到无论客户端的请求是什么,都需要先验证interface token:
s = bio_get_string16(msg, &len);//s=“android.os.IServiceManager” if ((len != (sizeof(svcmgr_id) / 2)) || memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { fprintf(stderr,"invalid id %s\n", str8(s)); return -1; }我们知道Client端写入的interface token是“android.os.IServiceManager”:
const android::String16 IServiceManager::descriptor("android.os.IServiceManager");
const android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());这应该是为了防止错误的客户端代理调用调用ServiceManager的BpHandler(即mHandle=0的BpBinder)。
void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len, unsigned uid) { struct svcinfo *si; si = find_svc(s, len); if (si && si->ptr) { if (!si->allow_isolated) { // If this service doesn't allow access from isolated processes, // then check the uid to see if it is isolated. unsigned appid = uid % AID_USER;//AID_USER = 100000 if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {//AID_ISOLATED_START=99000, AID_ISOLATED_END=99999 return 0; } } return si->ptr; } else { return 0; } }do_find_service函数通过调用find_svc函数,检索service name对应的service handle。另外,还需要涉及到请求进程的用户进程情况,如果呼叫进程是一个Service并且设置了
android:isolatedProcess="true"
,就属于这种情况。
struct svcinfo *find_svc(uint16_t *s16, unsigned len) { struct svcinfo *si; for (si = svclist; si; si = si->next) {//从svclist中搜索service if ((len == si->len) && !memcmp(s16, si->name, len * sizeof(uint16_t))) { return si; } } return 0; }这个函数,没什么好解释的。
void binder_send_reply(struct binder_state *bs, struct binder_io *reply, void *buffer_to_free, int status) { struct { uint32_t cmd_free; void *buffer; uint32_t cmd_reply; struct binder_txn txn; } __attribute__((packed)) data; data.cmd_free = BC_FREE_BUFFER; //首先发送BC_FREE_BUFFER,释放内核态缓冲区 data.buffer = buffer_to_free; data.cmd_reply = BC_REPLY;//发送回复请求 data.txn.target = 0;//BC_REPLY指令会忽略target,cookie,code参数 data.txn.cookie = 0; data.txn.code = 0; if (status) {//status = 0,所以执行else data.txn.flags = TF_STATUS_CODE; data.txn.data_size = sizeof(int); data.txn.offs_size = 0; data.txn.data = &status; data.txn.offs = 0; } else { data.txn.flags = 0; data.txn.data_size = reply->data - reply->data0; data.txn.offs_size = ((char*) reply->offs) - ((char*) reply->offs0); data.txn.data = reply->data0; data.txn.offs = reply->offs0; } binder_write(bs, &data, sizeof(data)); }这里reply结构体中保存了一个binder_object结构体:
struct binder_object { uint32_t type; uint32_t flags; void *pointer; void *cookie; };对比下上一节中的flat_binder_object对象:
struct flat_binder_object { /* 8 bytes for large_flat_header. */ unsigned long type; unsigned long flags; /* 8 bytes of data. */ union { void *binder; /* local object */ signed long handle; /* remote object */ }; /* extra data associated with local object */ void *cookie; };可以说,binder_object就是flat_binder_object对象的copy.
int binder_write(struct binder_state *bs, void *data, unsigned len) { struct binder_write_read bwr; int res; bwr.write_size = len; bwr.write_consumed = 0; bwr.write_buffer = (unsigned) data; bwr.read_size = 0; bwr.read_consumed = 0; bwr.read_buffer = 0; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//调用ioctl,通过BINDER_WRITE_READ指令返回数据 if (res < 0) { fprintf(stderr,"binder_write: ioctl failed (%s)\n", strerror(errno)); } return res; }调用ioctl以后,binder_write返回返回到14. binder_send_reply函数。根据上一节,对于binder driver的分析,我们知道进入内核态以后,binder_ioctl函数会先调用binder_thread_write函数,然后,binder_thread_write函数又会调用binder_transaction函数,binder_transaction函数则会对于flat_binder_object对象处理,在client进程内创建新的binder_ref指向特定的binder_node,然后,修改flat_binder_object.handle为新创建的binder_ref.desc,然后调用wakeup_event_interruputed函数唤醒Client进程,最后以binder_transaction->binder_thread_write->binder_ioctl的顺序返回到用户态的binder_write函数,binder_write函数再返回到binder_send_reply函数。
do { ...... if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)//终于看到了ioctl err = NO_ERROR; else err = -errno; ...... } while (err == -EINTR); //因为binder driver中是通过wait_event_interrupt函数进行等待,所以系统中断会导致binder_thread_read在读取到数据前返回 //所以,当err=-EINTR时,需要再次调用ioctl读取数据 ...... if (err >= NO_ERROR) {//根据ioctl的执行结果,调整mIn和mOut的状态 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; }然后,mIn从bwr.read_consumed缓冲区中读取数据。然后,返回到7. IPCThreadState->waitForResponse函数:
case BR_REPLY: { binder_transaction_data tr; err = mIn.read(&tr, sizeof(tr)); ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY"); if (err != NO_ERROR) goto finish; if (reply) { if ((tr.flags & TF_STATUS_CODE) == 0) { reply->ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); } else { err = *static_cast<const status_t*>(tr.data.ptr.buffer); freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); } } else { freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); continue; } } goto finish;本函数内,先从mIn中读取数据到tr结构体内,再从tr结构体内提取数据,赋值给reply结构体。
reply.readStrongBinder();以上函数会读取flat_binder_object的handle值,构建BpBinder实例并返回。
virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());//无论什么请求,interfaceToken都是需要发送的 data.writeString16(name);//service name data.writeStrongBinder(service);// BBinder地址 data.writeInt32(allowIsolated ? 1 : 0); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; }因为上一个函数checkService已经解释了数据传递到过程,所以,这里就不再多解释,直接进入到service manager的处理函数:
int svcmgr_handler(struct binder_state *bs, struct binder_txn *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si; uint16_t *s; unsigned len; void *ptr; uint32_t strict_policy; int allow_isolated; ...... switch(txn->code) { case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len);//service name ptr = bio_get_ref(msg);//handle allow_isolated = bio_get_uint32(msg) ? 1 : 0; if (do_add_service(bs, s, len, ptr, txn->sender_euid, allow_isolated)) return -1; break; ...... } bio_put_uint32(reply, 0);//回复0,表示请求处理成功 return 0; }3. do_add_service
int do_add_service(struct binder_state *bs, uint16_t *s, unsigned len, void *ptr, unsigned uid, int allow_isolated) { struct svcinfo *si; ...... if (!svc_can_register(uid, s)) {//检查注册的service是否合法 ALOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n", str8(s), ptr, uid); return -1; } si = find_svc(s, len); if (si) {//service已经注册 if (si->ptr) { ALOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED, OVERRIDE\n", str8(s), ptr, uid); svcinfo_death(bs, si); } si->ptr = ptr; } else {//尚未注册 si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { ALOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n", str8(s), ptr, uid); return -1; } si->ptr = ptr; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = '\0'; si->death.func = svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->next = svclist; svclist = si;//保存到svclist } binder_acquire(bs, ptr);//增加binder_ref和binder_node的引用计数 binder_link_to_death(bs, ptr, &si->death);//注册binder_ref的死亡通知 return 0; }因为service manager对于注册的servie有限制,所以在注册service前,需要前调用svc_can_register函数。
int svc_can_register(unsigned uid, uint16_t *name) { unsigned n; if ((uid == 0) || (uid == AID_SYSTEM))//root和system可以注册 return 1; for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)//否则必须匹配特定的uid和service name才能注册 if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name)) return 1; return 0; }这里需要交待一下allowed变量:
static struct { unsigned uid; const char *name; } allowed[] = { { AID_MEDIA, "media.audio_flinger" }, { AID_MEDIA, "media.player" }, { AID_MEDIA, "media.camera" }, { AID_MEDIA, "media.audio_policy" }, { AID_DRM, "drm.drmManager" }, { AID_NFC, "nfc" }, { AID_BLUETOOTH, "bluetooth" }, { AID_RADIO, "radio.phone" }, { AID_RADIO, "radio.sms" }, { AID_RADIO, "radio.phonesubinfo" }, { AID_RADIO, "radio.simphonebook" }, /* TODO: remove after phone services are updated: */ { AID_RADIO, "phone" }, { AID_RADIO, "sip" }, { AID_RADIO, "isms" }, { AID_RADIO, "iphonesubinfo" }, { AID_RADIO, "simphonebook" }, { AID_MEDIA, "common_time.clock" }, { AID_MEDIA, "common_time.config" }, };所以,如果设备开发者需要添加非system应用的service,需要修改allowed变量。
struct svcinfo { struct svcinfo *next;//下一各svcinfo void *ptr;//handle struct binder_death death; int allow_isolated; unsigned len;//service name的长度 uint16_t name[0];//service name };
struct binder_death { void (*func)(struct binder_state *bs, void *ptr); void *ptr; };如果si非空,则需要替换handle:
if (si->ptr) { ALOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED, OVERRIDE\n", str8(s), ptr, uid); svcinfo_death(bs, si);//释放旧的binder_ref } si->ptr = ptr;这里需要解释下svcinfo_death函数。
void svcinfo_death(struct binder_state *bs, void *ptr) { struct svcinfo *si = ptr; ALOGI("service '%s' died\n", str8(si->name)); if (si->ptr) { binder_release(bs, si->ptr); si->ptr = 0; } }svcinfo_death函数即上一节中提到的binder死亡通知到处理函数,它需要做得事情是,释放BpBinder。但是ServiceManager并没有使用BpBinder,所以它会直接调用binder_release函数,这个函数提供了更直接的实现方式。
void binder_release(struct binder_state *bs, void *ptr) { uint32_t cmd[2]; cmd[0] = BC_RELEASE; cmd[1] = (uint32_t) ptr; binder_write(bs, cmd, sizeof(cmd)); }binder_release函数通过发送BC_RELEASE指令来递减内核态binder_ref的引用计数,当binder_ref的引用计数为0时,binder_ref就会被释放,进而其对应binder_node的引用技术就会减1.同样的,当引用计数为0,binder_node就会被释放。
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { ALOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n", str8(s), ptr, uid); return -1; } si->ptr = ptr; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = '\0'; si->death.func = svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->next = svclist; svclist = si;//保存到svclist
void svcinfo_death(struct binder_state *bs, void *ptr) { struct svcinfo *si = ptr; ALOGI("service '%s' died\n", str8(si->name)); if (si->ptr) { binder_release(bs, si->ptr); si->ptr = 0; } }
binder_acquire(bs, ptr);//增加binder_ref和binder_node的引用计数 binder_link_to_death(bs, ptr, &si->death);//注册binder_ref的死亡通知 return 0;7. binder_link_to_death
void binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death) { uint32_t cmd[3]; cmd[0] = BC_REQUEST_DEATH_NOTIFICATION; cmd[1] = (uint32_t) ptr; cmd[2] = (uint32_t) death; binder_write(bs, cmd, sizeof(cmd)); }发送BC_REQUEST_DEATH_NOTIFICATION指令,以注册死亡通知。然后,service manager在binder_parse函数中处理
int binder_parse(struct binder_state *bs, struct binder_io *bio,
uint32_t *ptr, uint32_t size, binder_handler func)
{
int r = 1;
uint32_t *end = ptr + (size / 4);
while (ptr < end) {
uint32_t cmd = *ptr++;
.......
switch(cmd) {
case BR_DEAD_BINDER: {
struct binder_death *death = (void*) *ptr++;//death即刚才注册时写入的death
death->func(bs, death->ptr);//death->func即svcinfo_death函数,而svcinfo_deatch会调用binder_release函数
break;
}
......
}
}
return r;
}
现在,再回到3. do_add_service函数,该函数返回0,返回到2. svcmgr_handle函数。而svcmgr_handle函数调用
bio_put_uint32(reply, 0);//回复0,表示请求处理成功后返回到binder_parse函数,binder_parse函数调用binder_send_reply把0发送给BpServiceManager。
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); //err为servicemanager发送的0 return err == NO_ERROR ? reply.readExceptionCode() : err;
virtual Vector<String16> listServices() { Vector<String16> res; int n = 0; for (;;) { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeInt32(n++); status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply); if (err != NO_ERROR) break; res.add(reply.readString16()); } return res; }
我们可以看到,listService函数是通过循环实现的,每次返回一个service name。同样的,直接看serivcemanager的处理逻辑。
2. svcmgr_handler
int svcmgr_handler(struct binder_state *bs, struct binder_txn *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si; uint16_t *s; unsigned len; void *ptr; uint32_t strict_policy; int allow_isolated; ...... switch(txn->code) { case SVC_MGR_LIST_SERVICES: { unsigned n = bio_get_uint32(msg); si = svclist; while ((n-- > 0) && si) si = si->next; if (si) {//service bio_put_string16(reply, si->name);//返回指定service的service name return 0; } return -1;//n >= 所有注册的service的数量 } ...... } ...... }返回到client进程的BpServiceManager,在退出循环以前,每次循环可以通过
reply.readString16()获得一个service name,然后在退出循环后,返回所有获得的service name