With the "ServiceManager how to respond to Checkservice request" exploration, research AddService Pro, the middle process no longer say, only the key nodes listed:
frameworks/native/cmds/servicemanager/service_manager.c:347
int Main (intChar * *argv) { ... Binder_loop (BS, Svcmgr_handler); ...}
frameworks/native/cmds/servicemanager/binder.c:372
void binder_loop (struct binder_state *BS, binder_handler func) { ... for (;;) { ... 0 , (uintptr_t) Readbuf, bwr.read_consumed, func); ... }
frameworks/native/cmds/servicemanager/binder.c:204
intBinder_parse (structBinder_state *bs,structBinder_io *bio, uintptr_t ptr, size_t size, binder_handler func) {... Casebr_transaction: {structBinder_transaction_data *txn = (structBinder_transaction_data *) ptr; ...if(func) {unsigned rdata[ the/4]; structbinder_io msg; structBinder_io reply; intRes; Bio_init (&reply, Rdata,sizeof(Rdata),4); BIO_INIT_FROM_TXN (&msg, TXN); Res= Func (BS, TXN, &msg, &reply); Binder_send_reply (BS,&reply, txn->Data.ptr.buffer, RES); } ptr+=sizeof(*TXN); Break; } ...returnR;}
The memory data structure at this time is:
frameworks/native/cmds/servicemanager/service_manager.c:244
intSvcmgr_handler (structBinder_state *BS,structBinder_transaction_data *Txn,structBinder_io *msg,structBinder_io *reply) { structSvcinfo *si; uint16_t*s; size_t Len; uint32_t handle; uint32_t Strict_policy; intallow_isolated; ...Switch(txn->code) {... Casesvc_mgr_add_service:s= Bio_get_string16 (msg, &len);//"Service.testservice" if(s = =NULL) { return-1; } Handle=bio_get_ref (msg); Allow_isolated= Bio_get_uint32 (msg)?1:0;//0 if(Do_add_service (BS, S, Len, handle, txn->Sender_euid, allow_isolated, Txn-sender_pid)) return-1; Break; ...default: Aloge ("Unknown Code%d\n", txn->code); return-1; } bio_put_uint32 (reply,0); return 0;}
Svc_mgr_add_service data from MSG read from the "Server for AddService organization request data" is easy to disassemble, need to look at Bio_get_ref (...), frameworks/native/cmds/ servicemanager/binder.c:627
uint32_t bio_get_ref (struct binder_io *bio) { struct flat_binder_object *obj; = _bio_get_obj (bio); if (! obj) return 0 ; if (Obj->type = = Binder_type_handle ) return obj->handle; return 0 ;}
frameworks/native/cmds/servicemanager/binder.c:611
Static structFlat_binder_object *_bio_get_obj (structBinder_io *bio) {size_t n; size_t off= bio->data-bio->data0; /*Todo:be Smarter about this?*/ for(n =0; N < bio->offs_avail; n++) { if(Bio->offs[n] = =off)returnBio_get (bio,sizeof(structflat_binder_object)); } Bio->data_avail =0; Bio->flags |=Bio_f_overflow; returnNULL;}
The data pointer passed through the previous bio_get_xxx,msg has been moved to the Flat_binder_object entity, as shown in the orange arrows indicating the movement of the data pointer before the MSG is initialized to the execution Bio_get_ref (msg). _bio_get_obj (...) Responsible for returning this flat_binder_object entity.
frameworks/native/cmds/servicemanager/service_manager.c:194
intDo_add_service (structBinder_state *BS,Constuint16_t *s, size_t Len, uint32_t handle, uid_t uid,intallow_isolated, pid_t spid) { //s= "Service.testservice", Allow_isolated=0, handle=? structSvcinfo *si; ... si=Find_svc (S, Len); if(SI) {if(si->handle) {Aloge ("add_service ('%s ',%x) uid=%d-already registered, override\n", Str8 (S, Len), handle, UID); Svcinfo_death (BS, SI); } si->handle =handle;} Else { //Focus here, if the service has not been add, then create a node for it, save the name and handleSi =malloc(sizeof(*si) + (len +1) *sizeof(uint16_t)); if(!si) {Aloge ("add_service ('%s ',%x) Uid=%d-out of memory\n", Str8 (S, Len), handle, UID); return-1; } si->handle =handle; Si->len =Len; memcpy (Si->name, S, (Len +1) *sizeof(uint16_t)); Si->name[len] =' /'; Si->death.func = (void*) Svcinfo_death; Si->death.ptr =si; Si->allow_isolated =allow_isolated; Si->next =svclist; Svclist=si; } binder_acquire (BS, handle); Binder_link_to_death (BS, handle,&si->death); return 0;}
By this end, the final landing code was surprisingly simple: it simply saved the name and binder of the service and strung them up to the list. Wait for the client Checkservice to return handle. The total sense of mystery is still unresolved, this handle is the server-side organization of the Flat_binder_object data exactly how to connect the client and server? The role of ServiceManager should be associated with C/s, the next can be directly through the binder communication, but flat_binder_object inside just save a few pointers to the server, How do clients rely on this binder data link to the server? It appears that a specific service request and response will have to be studied to find the final answer.
Binder Learning Notes (vii)--servicemanager How to respond to AddService requests