1.ServiceManager的启动 ServiceManager作为所有服务大管家总共有三个方法值得关注。
main()启动ServiceManager并且注册为大管家(handled = 0)
do_add_service()其他服务将自己加入到ServiceManager中
do_find_service()需要使用到服务端的应用来查询服务,并且获取服务代理
1.1 启动servicemanager进程 1.1.1 解析init.rc启动servicemanger ServiceManager是由init进程通过解析init.rc文件而创建的,其所对应的可执行程序servicemanager, 所对应的源文件是service_manager.c,进程名为servicemanager。
1 2 3 4 5 6 7 8 9 10 // system/core/rootdir/init.rc service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart healthd onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm
1.1.2 调用servicemanager的main方法 调用servicemanager的main方法,启动ServiceManager的入口函数是 service_manager.c中的main()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 int main (int argc, char **argv) { struct binder_state *bs ; bs = binder_open(128 *1024 ); if (!bs) { ALOGE("failed to open binder driver\n" ); return -1 ; } if (binder_become_context_manager(bs)) { ALOGE("cannot become context manager (%s)\n" , strerror(errno)); return -1 ; } selinux_enabled = is_selinux_enabled(); sehandle = selinux_android_service_context_handle(); selinux_status_open(true ); if (selinux_enabled > 0 ) { if (sehandle == NULL ) { ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n" ); abort (); } if (getcon(&service_manager_context) != 0 ) { ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n" ); abort (); } } union selinux_callback cb ; cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); cb.func_log = selinux_log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); binder_loop(bs, svcmgr_handler); return 0 ; }
1.1.3 binder_open() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 struct binder_state *binder_open (size_t mapsize) { struct binder_state *bs ; struct binder_version vers ; bs = malloc (sizeof (*bs)); if (!bs) { errno = ENOMEM; return NULL ; } bs->fd = open("/dev/binder" , O_RDWR); if (bs->fd < 0 ) { fprintf (stderr ,"binder: cannot open device (%s)\n" , strerror(errno)); goto fail_open; } if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1 ) || (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) { fprintf (stderr , "binder: kernel driver version (%d) differs from user space version (%d)\n" , vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION); goto fail_open; } bs->mapsize = mapsize; bs->mapped = mmap(NULL , mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0 ); if (bs->mapped == MAP_FAILED) { fprintf (stderr ,"binder: cannot map device (%s)\n" , strerror(errno)); goto fail_map; } return bs; ...... }
1.1.4 binder_become_context_manager() 1 2 3 4 5 int binder_become_context_manager (struct binder_state *bs) { return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0 ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 static long binder_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) { ...... switch (cmd) { case BINDER_WRITE_READ: ret = binder_ioctl_write_read(filp, cmd, arg, thread); if (ret) goto err; break ; case BINDER_SET_MAX_THREADS: if (copy_from_user(&proc->max_threads, ubuf, sizeof (proc->max_threads))) { ret = -EINVAL; goto err; } break ; case BINDER_SET_CONTEXT_MGR: ret = binder_ioctl_set_ctx_mgr(filp); if (ret) goto err; break ; case BINDER_THREAD_EXIT: binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n" , proc->pid, thread->pid); binder_free_thread(proc, thread); thread = NULL ; break ; case BINDER_VERSION: { struct binder_version __user *ver = ubuf; if (size != sizeof (struct binder_version)) { ret = -EINVAL; goto err; } if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) { ret = -EINVAL; goto err; } break ; } default : ret = -EINVAL; goto err; } ret = 0 ; ...... }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 static int binder_ioctl_set_ctx_mgr (struct file *filp) { int ret = 0 ; struct binder_proc *proc = filp->private_data; struct binder_context *context = proc->context; kuid_t curr_euid = current_euid(); if (context->binder_context_mgr_node) { pr_err("BINDER_SET_CONTEXT_MGR already set\n" ); ret = -EBUSY; goto out; } ret = security_binder_set_context_mgr(proc->tsk); if (ret < 0 ) goto out; if (uid_valid(context->binder_context_mgr_uid)) { if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) { pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n" , from_kuid(&init_user_ns, curr_euid), from_kuid(&init_user_ns, context->binder_context_mgr_uid)); ret = -EPERM; goto out; } } else { context->binder_context_mgr_uid = curr_euid; } context->binder_context_mgr_node = binder_new_node(proc, 0 , 0 ); if (!context->binder_context_mgr_node) { ret = -ENOMEM; goto out; } context->binder_context_mgr_node->local_weak_refs++; context->binder_context_mgr_node->local_strong_refs++; context->binder_context_mgr_node->has_strong_ref = 1 ; context->binder_context_mgr_node->has_weak_ref = 1 ; out: return ret; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 static struct binder_node *binder_new_node (struct binder_proc *proc, binder_uintptr_t ptr, binder_uintptr_t cookie) { struct rb_node **p = &proc->nodes.rb_node; struct rb_node *parent = NULL ; struct binder_node *node ; while (*p) { parent = *p; node = rb_entry(parent, struct binder_node, rb_node); if (ptr < node->ptr) p = &(*p)->rb_left; else if (ptr > node->ptr) p = &(*p)->rb_right; else return NULL ; } node = kzalloc(sizeof (*node), GFP_KERNEL); if (node == NULL ) return NULL ; binder_stats_created(BINDER_STAT_NODE); rb_link_node(&node->rb_node, parent, p); rb_insert_color(&node->rb_node, &proc->nodes); node->debug_id = ++binder_last_id; node->proc = proc; node->ptr = ptr; node->cookie = cookie; node->work.type = BINDER_WORK_NODE; INIT_LIST_HEAD(&node->work.entry); INIT_LIST_HEAD(&node->async_todo); binder_debug(BINDER_DEBUG_INTERNAL_REFS, "%d:%d node %d u%016llx c%016llx created\n" , proc->pid, current->pid, node->debug_id, (u64)node->ptr, (u64)node->cookie); return node; }
1.1.5 binder_loop 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 void binder_loop (struct binder_state *bs, binder_handler func) { int res; struct binder_write_read bwr ; uint32_t readbuf[32 ]; bwr.write_size = 0 ; bwr.write_consumed = 0 ; bwr.write_buffer = 0 ; readbuf[0 ] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof (uint32_t )); for (;;) { bwr.read_size = sizeof (readbuf); bwr.read_consumed = 0 ; bwr.read_buffer = (uintptr_t ) readbuf; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0 ) { ALOGE("binder_loop: ioctl failed (%s)\n" , strerror(errno)); break ; } res = binder_parse(bs, 0 , (uintptr_t ) 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 ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int binder_write (struct binder_state *bs, void *data, size_t len) { struct binder_write_read bwr ; int res; bwr.write_size = len; bwr.write_consumed = 0 ; bwr.write_buffer = (uintptr_t ) data; bwr.read_size = 0 ; bwr.read_consumed = 0 ; bwr.read_buffer = 0 ; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0 ) { fprintf (stderr ,"binder_write: ioctl failed (%s)\n" , strerror(errno)); } return res; }
1 2 3 4 5 6 7 8 9 10 11 static long binder_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) { ...... switch (cmd) { case BINDER_WRITE_READ: ret = binder_ioctl_write_read(filp, cmd, arg, thread); if (ret) goto err; break ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 static int binder_ioctl_write_read (struct file *filp, unsigned int cmd, unsigned long arg, struct binder_thread *thread) { int ret = 0 ; struct binder_proc *proc = filp->private_data; unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; struct binder_write_read bwr ; if (size != sizeof (struct binder_write_read)) { ret = -EINVAL; goto out; } if (copy_from_user(&bwr, ubuf, sizeof (bwr))) { ret = -EFAULT; goto out; } binder_debug(BINDER_DEBUG_READ_WRITE, "%d:%d write %lld at %016llx, read %lld at %016llx\n" , proc->pid, thread->pid, (u64)bwr.write_size, (u64)bwr.write_buffer, (u64)bwr.read_size, (u64)bwr.read_buffer); if (bwr.write_size > 0 ) { ret = binder_thread_write(proc, thread, bwr.write_buffer, bwr.write_size, &bwr.write_consumed); trace_binder_write_done(ret); if (ret < 0 ) { bwr.read_consumed = 0 ; if (copy_to_user(ubuf, &bwr, sizeof (bwr))) ret = -EFAULT; goto out; } } if (bwr.read_size > 0 ) { ret = binder_thread_read(proc, thread, bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); trace_binder_read_done(ret); if (!list_empty(&proc->todo)) wake_up_interruptible(&proc->wait); if (ret < 0 ) { if (copy_to_user(ubuf, &bwr, sizeof (bwr))) ret = -EFAULT; goto out; } } ...... if (copy_to_user(ubuf, &bwr, sizeof (bwr))) { ret = -EFAULT; goto out; } out: return ret; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 static int binder_thread_write (struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed) { uint32_t cmd; struct binder_context *context = proc->context; void __user *buffer = (void __user *)(uintptr_t )binder_buffer; void __user *ptr = buffer + *consumed; void __user *end = buffer + size; while (ptr < end && thread->return_error == BR_OK) { if (get_user(cmd, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof (uint32_t ); trace_binder_command(cmd); if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { binder_stats.bc[_IOC_NR(cmd)]++; proc->stats.bc[_IOC_NR(cmd)]++; thread->stats.bc[_IOC_NR(cmd)]++; } switch (cmd) { ...... case BC_ENTER_LOOPER: binder_debug(BINDER_DEBUG_THREADS, "%d:%d BC_ENTER_LOOPER\n" , proc->pid, thread->pid); if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { thread->looper |= BINDER_LOOPER_STATE_INVALID; binder_user_error("%d:%d ERROR: BC_ENTER_LOOPER called after BC_REGISTER_LOOPER\n" , proc->pid, thread->pid); } thread->looper |= BINDER_LOOPER_STATE_ENTERED; break ; ...... }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 static int binder_thread_read (struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed, int non_block) { void __user *buffer = (void __user *)(uintptr_t )binder_buffer; void __user *ptr = buffer + *consumed; void __user *end = buffer + size; int ret = 0 ; int wait_for_proc_work; if (*consumed == 0 ) { if (put_user(BR_NOOP, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof (uint32_t ); } retry: wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo); if (wait_for_proc_work) proc->ready_threads++; ..... if (wait_for_proc_work) { if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED))) { binder_user_error("%d:%d ERROR: Thread waiting for process work before calling BC_REGISTER_LOOPER or BC_ENTER_LOOPER (state %x)\n" , proc->pid, thread->pid, thread->looper); wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2 ); } binder_set_nice(proc->default_priority); if (non_block) { if (!binder_has_proc_work(proc, thread)) ret = -EAGAIN; } else ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread)); } ...... }
2.获取service_manager 获取Service Manager是通过defaultServiceManager()方法来完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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.1 ProcessState::self() 1 2 3 4 5 6 7 8 9 10 sp<ProcessState> ProcessState::self () { Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL ) { return gProcess; } gProcess = new ProcessState; return gProcess; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER) , mThreadCountDecrement(PTHREAD_COND_INITIALIZER) , mExecutingThreadsCount(0 ) , mMaxThreads(DEFAULT_MAX_BINDER_THREADS) , mManagesContexts(false ) , mBinderContextCheckFunc(NULL ) , mBinderContextUserData(NULL ) , mThreadPoolStarted(false ) , mThreadPoolSeq(1 ) { if (mDriverFD >= 0 ) { mVMStart = mmap(0 , BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0 ); ...... }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 static int open_driver () { int fd = open("/dev/binder" , O_RDWR); if (fd >= 0 ) { size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); ...... } else { ALOGW("Opening '/dev/binder' failed: %s\n" , strerror(errno)); } return fd; }
2.2 ProcessState::getContextObject 1 2 3 4 5 6 sp<IBinder> ProcessState::getContextObject (const sp<IBinder>& ) { return getStrongProxyForHandle(0 ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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 ) { 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 { result.force_set(b); e->refs->decWeak(this ); } } return result; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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); }
2.3 interface_cast 2.3.1 模板定义
1 2 3 4 5 6 7 template <typename INTERFACE>inline sp<INTERFACE> interface_cast (const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
对于asInterface()函数,通过搜索代码,你会发现根本找不到这个方法是在哪里定义这个函数的, 其实是
通过模板函数来定义的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #define DECLARE_META_INTERFACE(INTERFACE) \ static const android::String16 descriptor; \ static android::sp<I##INTERFACE> asInterface( \ const android::sp<android::IBinder>& obj); \ virtual const android::String16& getInterfaceDescriptor () const ; \ I##INTERFACE(); \ virtual ~I##INTERFACE(); \ #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() { } \
2.3.2 IServiceManager头文件使用模板方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class IServiceManager : public IInterface{ public : DECLARE_META_INTERFACE(ServiceManager); static const android::String16 descriptor; static android::sp< IServiceManager > asInterface (const android::sp<android::IBinder>& obj) virtual const android::String16& getInterfaceDescriptor () const ; IServiceManager (); virtual ~IServiceManager();
该过程主要是声明asInterface(),getInterfaceDescriptor()方法。
2.3.3 IMPLEMENT_META_INTERFACE实现文件使用模板
1 2 IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager" );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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) { 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() { }
2.4 BpServiceManager()
1 2 3 4 5 6 7 8 class BpServiceManager : public BpInterface<IServiceManager>{ public : BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { } }
1 2 3 4 5 6 template <typename INTERFACE>inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) { }
1 2 3 4 5 6 7 8 9 10 11 12 BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL ), mState(0 ) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); if (mRemote) { mRemote->incStrong(this ); mRefs = mRemote->createWeak(this ); } }
将ServiceManager的Bpbinder给到mRemote, 然后就可以客户端就可以通过mRemote来完成通信了。
版权声明: 此文章版权归Jack Ou所有,如有转载,请註明来自原作者