In Checkservice's investigation we know that the client requests the service name to ServiceManager, ServiceManager traverses the local list based on the service name, and finds a matching handle to return to the client. This handle is clearly registered by the server, what is this handle? To understand this problem first, we must study how the server and ServiceManager work together to complete a addservice operation. We start with the service-side code. Testservice.cpp:30
int main () {SP < processstate > proc (processstate::self ()); SP < Iservicemanager > SM = Defaultservicemanager (); //sm = new Bpservicemanager (new Bpbinder (0)) sm->addservice (String16 ( service.testservice ), new Bntestservice ()); Processstate::self () ->startthreadpool (); Ipcthreadstate::self () ->jointhreadpool (); return 0 ;}
What was returned in the Defaultservicemanager ()? As already known in the article, SM is new Bpservicemanager (new Bpbinder (0)), so find Bpservicemanager::addservice (...), frameworks/native/libs/ binder/iservicemanager.cpp:155
Virtualstatus_t AddService (Conststring16& name,Constsp<ibinder>&Service,BOOLallowisolated) { //name= "Service.testservice", Service=new bntestservice (), Allowisolated=falseParcel data, reply; Data.writeinterfacetoken (Iservicemanager::getinterfacedescriptor ()); DATA.WRITESTRING16 (name); Data.writestrongbinder (service); Data.writeint32 (allowisolated?1:0); status_t Err= Remote ()->transact (add_service_transaction, data, &reply); returnErr = = No_error?Reply.readexceptioncode (): Err; }
Parcel data organization rules see How is parcel packaged? 》。 The service that is packaged here is the new Bntestservice () that is passed in by the main function, is it type remote or local? From the naming point I guess it's local (bpxxx represents proxy,bnxxx on behalf of native). Take a look at the inheritance of Bntestservice: Bntestservice inherits from Bninterface<itestservice>,bninterface from Bbinder, Bbinder overrides the virtual function Localbinder () {return this;} In binder.cpp:191. So this parcel data is:
Binder->localbinder () Returns the this pointer of binder, so it is the incoming service parameter, which is new Bntestservice ().
Next in Bpservicemanager::addservice (...) The function calls the remote ()->transact (...) The process of organizing data has been analyzed in the binder client how to organize checkservice data and is no longer explained in detail, only the key nodes are listed:
frameworks/native/libs/binder/iservicemanager.cpp:155
Virtual status_t addService (constconst sp<ibinder>& service, BOOL allowisolated) { //Name= "Service.testservice", Service=new bntestservice (), Allowisolated=false Parcel data, reply; ... = Remote ()->transact (add_service_transaction, data, &reply); ... }
frameworks/native/libs/binder/bpbinder.cpp:159
status_t bpbinder::transact ( const parcel& data, parcel* reply, uint32_t flags) { //code=add_service_transaction, flags=0 // Once A binder has died, it'll never come back to life. ... = Ipcthreadstate::self (),transact ( mhandle, code, data, reply, flags); ...}
frameworks/native/libs/binder/ipcthreadstate.cpp:548
status_t ipcthreadstate::transact (int32_t handle, const parcel& data, Parcel * reply, uint32_t flags) { //Handle=0, code=add_service_transaction, flags=0 status_t Err = Data.errorcheck (); | = Tf_accept_fds; ... = Writetransactiondata (bc_transaction, flags, handle, code, data, NULL); ... return err;}
frameworks/native/libs/binder/ipcthreadstate.cpp:904
status_t ipcthreadstate::writetransactiondata (int32_t cmd, uint32_t binderflags, int32_t handle, uint32_t code, Constparcel& data, status_t*Statusbuffer) { //Cmd=bc_transaction, Binderflags=tf_accept_fds, handle=0,// code=add_service_transaction, Binder_transaction_data tr; Tr.target.ptr=0;/*Don ' t pass uninitialized stack data to a remote process*/Tr.target.handle=handle; Tr.code=Code; Tr.flags=Binderflags; Tr.cookie=0; Tr.sender_pid=0; Tr.sender_euid=0; ... tr.data_size=data.ipcdatasize (); Tr.data.ptr.buffer=Data.ipcdata (); Tr.offsets_size= Data.ipcobjectscount () *sizeof(binder_size_t); Tr.data.ptr.offsets=data.ipcobjects (); ... mout.writeint32 (cmd); Mout.write (&TR,sizeof(tr)); returnNo_error;}
It is organized into the final request data for:
Binder Learning Notes (vi)--binder How the server organizes AddService data