Ò»¡¢²âÊÔ´úÂ룺
¡«/Android/external/binder/server ----FregServer.cpp ~/Android/external/binder/common ----IFregService.cpp ----IFregService.h ~/Android/external/binder/client ----FregClient.cpp |
Binder¿â(libbinder)´úÂ룺
~/Android/frameworks/base/libs/binder ----BpBinder.cpp ----Parcel.cpp ----ProcessState.cpp ----Binder.cpp ----IInterface.cpp ----IPCThreadState.cpp ----IServiceManager.cpp ----Static.cpp ~/Android/frameworks/base/include/binder ----Binder.h ----BpBinder.h ----IInterface.h ----IPCThreadState.h ----IServiceManager.h ----IBinder.h ----Parcel.h ----ProcessState.h |
Çý¶¯²ã´úÂ룺
¡«/Android//kernel/goldfish/drivers/staging/android ----binder.c ----binder.h |
Service Manager´úÂ룺
¡«/Android/frameworks/base/cmd/servicemanager ----binder.c ----service_manager.c ----binder.h |
¶þ¡¢Ô´Âë·ÖÎö
1¡¢FregClient½ø³Ì£¬»ñÈ¡ServiceManager´úÀí¶ÔÏ󡣲ο¼FregServer½ø³Ì£¬»ñÈ¡ServiceManager´úÀí¶ÔÏó
~/Android/external/binder/client |
----FregClient.cpp
int main() { sp<IBinder> binder = defaultServiceManager()->getService(String16(FREG_SERVICE)); if(binder == NULL) { LOGE("Failed to get freg service: %s.\n", FREG_SERVICE); return -1; } sp<IFregService> service = IFregService::asInterface(binder); if(service == NULL) { LOGE("Failed to get freg service interface.\n"); return -2; } ............ } |
Ê×Ïȵ÷ÓÃBinder¿âÌṩµÄº¯ÊýdefaultServiceManagerÔÚFregClient½ø³ÌÖлñµÃÒ»¸öService
Manager´úÀí¶ÔÏ󣬽Ó×ÅÔÙµ÷ÓÃËüµÄ³ÉÔ±º¯ÊýgetServiceÀ´»ñµÃÒ»¸öÃû³ÆÎªFREG_SERVICEµÄService×é¼þµÄ´úÀí¶ÔÏó£¬ÀàÐÍΪBpBinder¡£È»ºóÔÙÐèҪͨ¹ýIFregServiceÀàµÄ¾²Ì¬³ÉÔ±º¯ÊýasInterface½«Ëü·â×°³ÉÒ»¸öBpFregServiceÀàÐ͵ĴúÀí¶ÔÏó¡£
2¡¢FregClient½ø³Ì£¬·â×°½ø³Ì¼äͨÐÅÊý¾Ý¡£²Î¿¼FregServer½ø³Ì£¬·â×°½ø³Ì¼äͨÐÅÊý¾Ýhttp://blog.csdn.net/jltxgcy/article/details/26059215¡£
ÎÒÃÇÊ×ÏÈ·ÖÎöÏÂService Manager´úÀí¶ÔÏóµÄ³ÉÔ±º¯ÊýgetServiceʵÏÖÈçÏ£º
~/Android/external/binder/client |
---IServiceManager.cpp
class BpServiceManager : public BpInterface<IServiceManager> { public: ......... virtual sp<IBinder> getService(const String16& name) const { unsigned n; for (n = 0; n < 5; n++){ sp<IBinder> svc = checkService(name); if (svc != NULL) return svc; LOGI("Waiting for service %s...\n", String8(name).string()); sleep(1); } return NULL; } ........... };
|
Õâ¸öº¯Êý×î¶à»á³¢ÊÔ5´ÎÀ´»ñµÃÒ»¸öÃû³ÆÎªnameµÄService×é¼þµÄ´úÀí¶ÔÏó¡£Èç¹ûÉÏÒ»´Î»ñµÃʧ°Ü£¬ÄÇô¾Íµ÷ÓÃsleepʹµÃµ±Ç°Ïß³Ì˯Ãß1ºÁÃ룬ȻºóÔÙÖØÐÂÈ¥»ñÈ¡£¬·ñÔò¾ÍÖ±½Ó½«»ñµÃµÄService×é¼þµÄ´úÀí¶ÔÏ󷵻ظøµ÷ÓÃÕß¡£
µ÷ÓÃcheckServiceÀ´»ñµÃÒ»¸öÃû³ÆÎªnameµÄService×é¼þµÄ´úÀí¶ÔÏó¡£ÊµÏÖÈçÏ£º
~/Android/external/binder/client |
----IServiceManager.cpp
class BpServiceManager : public BpInterface<IServiceManager> { public: ........ virtual sp<IBinder> checkService( const String16& name) const { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());//android.os.IServiceManager data.writeString16(name);//shy.luo.FregService remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);//remoteΪBpBinder¶ÔÏó return reply.readStrongBinder(); } ......... }; |
3¡¢ FregClient½ø³Ì£¬·¢ËÍBC_TRANSACTION£¬Ë¯¾õµÈ´ý¡£²Î¿¼FregServer½ø³Ì£¬·¢ËÍBC_TRANSACTION£¬Ë¯Ãߵȴýhttp://blog.csdn.net/jltxgcy/article/details/26076149¡£
º¯ÊýÒÔºóµÄÖ´ÐÐÁ÷³Ì£¬ºÍÒÔÏÂÁ½ÆªÎÄÕÂÏàÀàËÆ£¬Ö»ÊÇÒ»¸öÊÇADD_SERVICE_TRANSACTION£¬Ò»¸öÊÇCHECK_SERVICE_TRANSACTION¡£
4¡¢Service Manager½ø³Ì£¬´¦ÀíBC_TRANSACTION£¬·µ»ØBR_TRANSACTION¡£²Î¿¼Service
Manager½ø³Ì£¬´¦ÀíBC_TRANSACTION£¬·µ»ØBR_TRANSACTIONhttp://blog.csdn.net/jltxgcy/article/details/26151113¡£
Ëæ×ÅÖ´ÐеÄÉîÈ룬svcmgr_handler·½·¨£¬³öÏÖÁ˲»Í¬µÄÖ´Ðйý³Ì¡£ÊµÏÖÈçÏ£º
¡«/Android/frameworks/base/cmd/servicemanager |
----service_manager.c
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; .......... if (txn->target != svcmgr_handle) return -1; ......... strict_policy = bio_get_uint32(msg);//strict_policyΪSTRICT_MODE_PENALTY_GATHER 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) {//CHECK_SERVICE_TRANSACTION£¬¼´SVC_MGR_CHECK_SERVICE case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len);//sΪshy.luo.FregService£¬lenΪËüµÄ³¤¶È ptr = do_find_service(bs, s, len);
//Service Manager½ø³ÌµÄÒýÓöÔÏó(ÒýÓÃÁËFregServer½ø³ÌµÄʵÌå¶ÔÏó)µÄ¾ä±úÖµ if (!ptr) break; bio_put_ref(reply, ptr);
//½«Ç°Ãæ»ñµÃµÄÒ»¸ö¾ä±úÖµ·â×°³ÉÒ»¸öbinder_object½á¹¹Ì壬²¢ÇÒдÈëµ½binder_io½á¹¹ÌåreplyÖÐ return 0; ......... } ......... }
|
µ÷ÓÃdo_find_serviceÔÚÒÑ×¢²áService×é¼þÁбísvclistÖвéÕÒÓëËü¶ÔÓ¦µÄÒ»¸ösvcinfo½á¹¹Ì壬ʵÏÖÈçÏ£º
¡«/Android/frameworks/base/cmd/servicemanager |
----service_manager.c
void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len) { struct svcinfo *si; si = find_svc(s, len);//sΪshy.luo.FregService£¬lenΪËüµÄ³¤¶È // LOGI("check_service('%s') ptr = %p\n", str8(s), si ? si->ptr : 0); if (si && si->ptr) { return si->ptr;//·µ»ØÒ»¸öÒýÓÃÁË×¢²áµ½Service ManagerÖÐService×é¼þµÄBinderÒýÓöÔÏóµÄ¾ä±úÖµ } else { return 0; } } |
Ê×Ïȵ÷ÓÃfind_svcÀ´²éÕÒÓë×Ö·û´®s¶ÔÓ¦µÄÒ»¸ösvcinfo½á¹¹Ìåsi¡£ÎÒÃÇÒѾ·ÖÎö¹ýº¯Êýfind_svcµÄʵÏÖÁË£¬Ëüͨ¹ý±éÀúÒÑ×¢²áService×é¼þÁбísvclistÀ´²éÕÒÓë×Ö·û´®s¶ÔÓ¦µÄÒ»¸ösvcinfo½á¹¹Ìå¡£Èç¹ûÕÒµ½ÁËÓë×Ö·û´®¶ÔÓ¦µÄsvcinfo½á¹¹Ìåsi£¬²¢ÇÒËüµÄ³ÉÔ±±äÁ¿ptrµÄÖµ²»Îª0£¬ÄÇô¾Í½«ËüµÄ³ÉÔ±±äÁ¿ptrµÄÖµ·µ»Ø¸øµ÷ÓÃÕß¡£
½á¹¹ÌåsvcinfoµÄ³ÉÔ±±äÁ¿ptr±£´æµÄÒ»¸öÒýÓÃÁË×¢²áµ½Service
ManagerÖÐService×é¼þµÄBinderÒýÓöÔÏóµÄ¾ä±úÖµ¡£µ±Service Manager½«Õâ¸ö¾ä±úÖµ·µ»Ø¸øBinderÇý¶¯³ÌÐòʱ£¬BinderÇý¶¯³ÌÐò¾Í¿ÉÒÔ¸ù¾ÝËüÕÒµ½ÏàÓ¦µÄBinderÒýÓöÔÏ󣬽Ó×ÅÕÒµ½¸ÃBinderÒýÓöÔÏóËùÒýÓÃBinderʵÌå¶ÔÏó¡£
·µ»Øsvcmgr_handler£¬¼ÌÐøÖ´ÐÐbio_put_refº¯Êý£¬½«Ç°Ãæ»ñµÃµÄÒ»¸ö¾ä±úÖµ·â×°³ÉÒ»¸öbinder_object½á¹¹Ì壬²¢ÇÒдÈëµ½binder_io½á¹¹ÌåreplyÖУ¬ÊµÏÖÈçÏ£º
¡«/Android/frameworks/base/cmd/servicemanager |
----binder.c
void bio_put_ref(struct binder_io *bio, void *ptr)//bioΪreply,ptrΪ¾ä±úÖµ { struct binder_object *obj; if (ptr)//²»ÎªNULL obj = bio_alloc_obj(bio);//·ÖÅäÁËbinder_object½á¹¹Ì壬¶ø²»ÊÇbinder_io,binder_ioÒÔǰÒѾ·ÖÅä¹ýÁË else obj = bio_alloc(bio, sizeof(*obj)); if (!obj) return; obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; obj->type = BINDER_TYPE_HANDLE; obj->pointer = ptr; obj->cookie = 0; } |
ÓÉÓÚ´«½øÀ´µÄ²ÎÊýptrµÄÖµ²»µÈÓÚ0£¬Òò´Ëµ÷ÓÃbio_alloc_objÔÚbinder_io½á¹¹ÌåbioµÄÊý¾Ý»º³åÇøÖзÖÅäÒ»¸öbinder_object½á¹¹Ìåobj¡£ÊµÏÖÈçÏ£º
¡«/Android/frameworks/base/cmd/servicemanager |
----binder.c
static struct binder_object *bio_alloc_obj(struct binder_io *bio)//bioΪreply { struct binder_object *obj; obj = bio_alloc(bio, sizeof(*obj));//ÔÚbinder_io½á¹¹ÌåbioµÄÊý¾Ý»º³åÇøÖзÖÅäÒ»¸öbinder_object½á¹¹Ìåobj if (obj && bio->offs_avail) { bio->offs_avail--;//Æ«ÒÆÊý×é´óС¼õ1 *bio->offs++ = ((char*) obj) - ((char*) bio->data0);//Æ«ÒÆÊý×éÄÚÈÝÖ¸Ïò¸Õ²ÅµÄbinder_object½á¹¹Ìåobj return obj; } bio->flags |= BIO_F_OVERFLOW; return 0; } |
¡«/Android/frameworks/base/cmd/servicemanager |
----binder.c
static void *bio_alloc(struct binder_io *bio, uint32_t size) { size = (size + 3) & (~3); if (size > bio->data_avail) { bio->flags |= BIO_F_OVERFLOW; return 0; } else { void *ptr = bio->data;//¿ªÊ¼Î»Öà bio->data += size;//·ÖÅäÍêbinder_objectºóµÄλÖà bio->data_avail -= size;//¿ÉÓÃÊý¾ÝÒª¼õÉÙsize return ptr; } } |
»Øµ½svcmgr_handlerÖУ¬ÏÖÔÚÒª·µ»Ø¸øBinderÇý¶¯³ÌÐòµÄ½ø³Ì¼äͨÐŽá¹ûÊý¾Ý±£´æÔÚbinder_io½á¹¹ÌåreplyÖÐÁË¡£½Ó×ÅÓÖ·µ»Øº¯Êýbinder_parseÖУ¬×îºóµ÷Óú¯Êýbinder_send_reply½«binder_io½á¹¹ÌåreplyµÄÄÚÈÝ·µ»Ø¸øBinderÇý¶¯³ÌÐò¡£
5¡¢Service Manager½ø³Ì£¬·¢ËÍBC_REPLY£¬Ë¯Ãߵȴý¡£²Î¿¼Service
Manager½ø³Ì£¬·¢ËÍBC_REPLY£¬Ë¯Ãߵȴýhttp://blog.csdn.net/jltxgcy/article/details/26216521¡£
Ëæ×ÅÖ´ÐеÄÉîÈ룬binder_transaction·½·¨£¬³öÏÖÁ˲»Í¬µÄÖ´Ðйý³Ì¡£ÊµÏÖÈçÏ£º
----binder.c
static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply) { struct binder_transaction *t; struct binder_work *tcomplete; ...... struct binder_proc *target_proc; struct binder_thread *target_thread = NULL; struct binder_node *target_node = NULL; struct list_head *target_list; wait_queue_head_t *target_wait; struct binder_transaction *in_reply_to = NULL; ........ uint32_t return_error; ........ if (reply) { in_reply_to = thread->transaction_stack;
//Ê×ÏÈ´ÓÏß³ÌthreadµÄÊÂÎñ¶ÑÕ»Öн«¸Ãbinder_transaction½á¹¹ÌåÈ¡³öÀ´£¬²¢ÇÒ±£´æÔÚ±äÁ¿in_reply_toÖÐ if (in_reply_to == NULL) { ...... return_error = BR_FAILED_REPLY; goto err_empty_call_stack; } binder_set_nice(in_reply_to->saved_priority); if (in_reply_to->to_thread != thread) { ........ return_error = BR_FAILED_REPLY; in_reply_to = NULL; goto err_bad_call_stack; } thread->transaction_stack = in_reply_to->to_parent; target_thread = in_reply_to->from;//Ä¿±êÏß³Ì if (target_thread == NULL) { return_error = BR_DEAD_REPLY; goto err_dead_binder; } if (target_thread->transaction_stack != in_reply_to) { ......... return_error = BR_FAILED_REPLY; in_reply_to = NULL; target_thread = NULL; goto err_dead_binder; } target_proc = target_thread->proc;//ÕÒµ½ÁËÄ¿±ê½ø³Ì } else { ........ } if (target_thread) { ......... target_list = &target_thread->todo;
//·Ö±ð½«ËüµÄtodo¶ÓÁкÍwaitµÈ´ý¶ÓÁÐ×÷ΪĿ±êtodo¶ÓÁÐtarget_listºÍÄ¿±êwaitµÈ´ý¶ÓÁÐtarget_wait target_wait = &target_thread->wait;
//·Ö±ð½«ËüµÄtodo¶ÓÁкÍwaitµÈ´ý¶ÓÁÐ×÷ΪĿ±êtodo¶ÓÁÐtarget_listºÍÄ¿±êwaitµÈ´ý¶ÓÁÐtarget_wait } else { ......... } ......... /* TODO: reuse incoming transaction for reply */ t = kzalloc(sizeof(*t), GFP_KERNEL);//·ÖÅäÁËbinder_transaction½á¹¹Ìå ........ tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);//·ÖÅäÁËbinder_work½á¹¹Ìå if (tcomplete == NULL) { return_error = BR_FAILED_REPLY; goto err_alloc_tcomplete_failed; } ....... if (!reply && !(tr->flags & TF_ONE_WAY)) t->from = thread;//service_managerµÄÖ÷Ïß³Ì else t->from = NULL; t->sender_euid = proc->tsk->cred->euid;//service_manager½ø³ÌºÅ t->to_proc = target_proc;//Ä¿±ê½ø³Ì t->to_thread = target_thread;//Ä¿±êÏß³Ì t->code = tr->code;//0 t->flags = tr->flags;//0 t->priority = task_nice(current); t->buffer = binder_alloc_buf(target_proc, tr->data_size, tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));//·ÖÅäÁËbinder_buffer½á¹¹Ìå if (t->buffer == NULL) { return_error = BR_FAILED_REPLY; goto err_binder_alloc_buf_failed; } t->buffer->allow_user_free = 0;//²»ÔÊÐíÊÍ·Å ....... t->buffer->transaction = t; t->buffer->target_node = target_node;//NULL if (target_node) binder_inc_node(target_node, 1, 0, NULL);//Ôö¼ÓÄ¿±êBinderʵÌå¶ÔÏóµÄÇ¿ÒýÓüÆÊý offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
//Æ«ÒÆÊý×éÔÚdataÖÐÆðʼλÖã¬Î»ÓÚÊý¾Ý»º³åÇøÖ®ºó if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
//Êý¾Ý»º³åÇø¿½±´µ½dataÖÐ binder_user_error("binder: %d:%d got transaction with invalid " "data ptr\n", proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
//Æ«ÒÆÊý×鿽±´µ½dataÖУ¬Æ«ÒÆÊý×éλÓÚÊý¾Ý»º³åÇøÖ®ºó binder_user_error("binder: %d:%d got transaction with invalid " "offsets ptr\n", proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } ........... off_end = (void *)offp + tr->offsets_size; for (; offp < off_end; offp++) {//Æ«ÒÆÊý×éÀïÃæÃ»ÓÐÄÚÈÝ struct flat_binder_object *fp; ....... fp = (struct flat_binder_object *)(t->buffer->data + *offp); switch (fp->type) { ...... case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle);
//Service Manager½ø³ÌµÄÒýÓöÔÏó(ÒýÓÃÁËFregServer½ø³ÌµÄʵÌå¶ÔÏó) ....... if (ref->node->proc == target_proc) {//FregService½ø³ÌºÍFregClient½ø³Ì²»ÏàµÈ ....... } else { struct binder_ref *new_ref; new_ref = binder_get_ref_for_node(target_proc, ref->node);
//FregClient½ø³ÌµÄÒýÓöÔÏó(ÒýÓÃÁËFregServer½ø³ÌµÄʵÌå¶ÔÏó) ......... fp->handle = new_ref->desc;//FregClient½ø³ÌµÄÒýÓöÔÏó¾ä±ú¸³Öµ¸øhandle binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); ........ } } break; ....... } if (reply) { BUG_ON(t->buffer->async_transaction != 0); binder_pop_transaction(target_thread, in_reply_to);//TODO } else if (!(t->flags & TF_ONE_WAY)) { ......... } else { ......... } t->work.type = BINDER_WORK_TRANSACTION; list_add_tail(&t->work.entry, target_list);//¼ÓÈ뵽Ŀ±êÏ̵߳Ätodo tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; list_add_tail(&tcomplete->entry, &thread->todo);//¼ÓÈëµ½±¾Ï̵߳Ätodo if (target_wait) wake_up_interruptible(target_wait);//»½ÐÑÄ¿±êÏß³Ì return; } |
Òª´«µÝµÄbinder_transaction½á¹¹Ì壬´«µÝµÄflat_binder_objectµÄ¸÷¸ö³ÉÔ±ÈçÏ£º
flagsΪ0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS£¬typeΪBINDER_TYPE_HANDLE£¬handleΪFregClient½ø³ÌµÄÒýÓöÔÏó£¨ÒýÓÃÁËFregServer½ø³ÌµÄʵÌå¶ÔÏ󣩾ä±úÖµ£¬cookieΪ0¡£
6¡¢FregClient½ø³Ì£¬´¦ÀíBC_REPLY£¬·µ»ØBR_REPLY¡£²Î¿¼FregServer½ø³Ì£¬´¦ÀíBC_REPLY£¬·µ»ØBR_REPLYhttp://blog.csdn.net/jltxgcy/article/details/26339313¡£
7¡¢FregClient½ø³Ì£¬·µ»Øµ½checkServiceÖУ¬´´½¨FregClient½ø³ÌµÄ´úÀí¶ÔÏó£¬×îºó´´½¨Ò»¸öBpFregServiceÀàÐ͵ĴúÀí¶ÔÏ󡣲ο¼Android
Binder½ø³Ì¼äͨÐÅ---FregServer½ø³Ì£¬Æô¶¯BinderÏ̳߳Øhttp://blog.csdn.net/jltxgcy/article/details/26354311¡£
ʵÏÖÈçÏ£º
~/Android/external/binder/client |
----IServiceManager.cpp
class BpServiceManager : public BpInterface<IServiceManager> { public: ........ virtual sp<IBinder> checkService( const String16& name) const { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());//android.os.IServiceManager data.writeString16(name);//shy.luo.FregService remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);//remoteΪBpBinder¶ÔÏó return reply.readStrongBinder();//FregClient½ø³ÌµÄ´úÀí¶ÔÏó } ......... }; |
·µ»Øºóµ÷ÓÃParcel¶ÔÏóreplyµÄ³ÉÔ±º¯ÊýreadStrongBinderÀ´»ñµÃÒ»¸öBinder´úÀí¶ÔÏó¡£ÊµÏÖÈçÏ£º
¡«/Android/frameworks/base/libs/binder |
----Parcel.cpp
sp<IBinder> Parcel::readStrongBinder() const { sp<IBinder> val; unflatten_binder(ProcessState::self(), *this, &val);//À´»ñµÃÕâ¸öflat_binder_object½á¹¹Ìå return val; } |
µ÷ÓÃunflatten_binderº¯Êý£¬ÊµÏÖÈçÏ£º
status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out) { const flat_binder_object* flat = in.readObject(false);//in¾ÍÊÇreply if (flat) { switch (flat->type) { ......... case BINDER_TYPE_HANDLE: *out = proc->getStrongProxyForHandle(flat->handle); ...... } } return BAD_TYPE; } |
µ÷ÓÃgetStrongProxyForHandleʵÏÖÈçÏ£º
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle);
//¼ì²é³ÉÔ±±äÁ¿mHandleToObjectÊÇ·ñÒѾ´æÔÚÒ»¸öÓë¾ä±úÖµhandle¶ÔÓ¦µÄhandle_entry½á¹¹Ìå 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)) {
//Èç¹û½ø³ÌÉÐδΪ¾ä±úÖµhandle´´½¨¹ýBinder´úÀí¶ÔÏ󣬻òÕß´´½¨ÁËBinder´úÀí¶ÔÏóµ«ÒѾÏú»ÙÁË b = new BpBinder(handle); //Binder´úÀí¶ÔÏó£¬handleΪ1 e->binder = b;//±£´æÔÙeµÄ³ÉÔ±±äÁ¿binderÖÐ if (b) e->refs = b->getWeakRefs();//½«ÈõÒýÓüÆÊý¶ÔÏó±£´æÔÚeµÄ³ÉÔ±±äÁ¿refsÖÐ result = b;//·µ»Ø½á¹û } else {//Èç¹û½ø³ÌÒѾ´´½¨ÁËBinder´úÀí¶ÔÏ󣬲¢ÇÒûÓÐÏú»Ù£¬ÄÇôֱ½Ó·µ»Ø // 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);//ÉèÖ÷µ»Ø½á¹ûresult e->refs->decWeak(this);//¼õÉÙÈõÒýÓüÆÊý£¬ÒòΪattemptIncWeakÔö¼ÓÁËÈõÒýÓüÆÊý } } return result; } |
´´½¨FregClient½ø³ÌµÄ´úÀí¶ÔÏó¡£
Ö´ÐÐÍêcheckSevice£¬·µ»Ømainº¯Êý¡£ÊµÏÖÈçÏ£º
~/Android/external/binder/client |
----FregClient.cpp
int main() { sp<IBinder> binder = defaultServiceManager()->getService(String16(FREG_SERVICE)); if(binder == NULL) { LOGE("Failed to get freg service: %s.\n", FREG_SERVICE); return -1; } sp<IFregService> service = IFregService::asInterface(binder); if(service == NULL) { LOGE("Failed to get freg service interface.\n"); return -2; } ............ } |
IFregServiceÀàµÄ¾²Ì¬³ÉÔ±º¯ÊýasInterfaceÊÇͨ¹ýºêIMPLEMENT_META_INTERFACEÀ´¶¨ÒåµÄ£¬ËüµÄʵÏÖÈçÏ£º
android::sp<IFregService> IFregService::asInterface(const android::sp<android::IBinder>& obj) { android::sp<IFregService> intr; if (obj != NULL) { intr = static_cast<IFregService*>( obj->queryLocalInterface(IFregService::descriptor).get());//·µ»ØNULL if (intr == NULL) { intr = new BpFregService(obj); //´´½¨ÁËBpFregServiceÀàÐ͵ĴúÀí¶ÔÏó } £ý return intr; } |
²ÎÊýobjÖ¸ÏòµÄÊÇÇ°Ãæ»ñµÃµÄÒ»¸öBinder´úÀí¶ÔÏ󣬼´Ò»¸öBpBinder¶ÔÏó¡£È»ºó½«Õâ¸öBinder´úÀí¶ÔÏó·â×°³ÉÒ»¸öBpFregServiceÀàÐ͵ĴúÀí¶ÔÏ󣬲¢ÇÒ½«ËüµÄIFregService½Ó¿Ú·µ»Ø¸øµ÷ÓÃÕß¡£
Èý¡¢Ä¿Ç°´æÔڵĸ÷ÖÖ¶ÔÏó
Service Manager½ø³ÌµÄ±¾µØ¶ÔÏó£»
Service Manager½ø³ÌµÄʵÌå¶ÔÏó£»
FregServer½ø³ÌµÄÒýÓöÔÏó(ÒýÓÃÁËService Manager½ø³ÌµÄʵÌå¶ÔÏó)£»
FregServer½ø³ÌµÄ´úÀí¶ÔÏó¡£
FregServer½ø³ÌµÄ±¾µØ¶ÔÏó£»
FregServer½ø³ÌµÄʵÌå¶ÔÏó£»
Service Manager½ø³ÌµÄÒýÓöÔÏó(ÒýÓÃÁËFregServer½ø³ÌµÄʵÌå¶ÔÏó)£»
FregClient½ø³ÌµÄÒýÓöÔÏó(ÒýÓÃÁËFregServer½ø³ÌµÄʵÌå¶ÔÏó)£»
FregClient½ø³ÌµÄ´úÀí¶ÔÏó£»
BpFregServiceÀàÐ͵ĴúÀí¶ÔÏ󣨳ÉÔ±º¯Êýremote()¿ÉÒÔ»ñÈ¡FregClient½ø³ÌµÄ´úÀí¶ÔÏ󣩣»
|