Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
´´½¨Ò»¸öBpFregServiceÀàÐ͵ĴúÀí¶ÔÏó
 
×÷Õß jltxgcyµÄ²©¿Í£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-07-24
  2314  次浏览      27
 

Ò»¡¢²âÊÔ´úÂ룺

¡«/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·½·¨£¬³öÏÖÁ˲»Í¬µÄÖ´Ðйý³Ì¡£ÊµÏÖÈçÏ£º

<!DOCTYPE HTML>

----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½ø³ÌµÄ´úÀí¶ÔÏ󣩣»

   
2314 ´Îä¯ÀÀ       27
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ


Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ


ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ