Binder Learning Note (v) how does--parcel package data?

Source: Internet
Author: User

In the previous article has encountered parcel, from the name to know that he is responsible for data packaging. In Checkservice's request/response system, parcel only packaged basic data types, such as Int32, String16 ... The latter is also used to package the abstract data type Flat_binder_object, which is slightly more complicated, so it is necessary to take it out for a separate study. We are from Parcel::writeinterfacetoken (...) After that, its layer invocation relationships are as follows, in the Frameworks/native/libs/binder/parcel.cpp file, with the number of rows and function names:

582     writeinterfacetoken (...) 748         Parcel::writeint32 (int32_t val)1149            Parcel::writealigned (Val)

All of the basic data types are packaged at last by writealigned (...). Implementation, its internal logic is also very simple,

frameworks/native/libs/binder/parcel.cpp:1149

template<classT>status_t parcel::writealigned (t val) {Compile_time_assert_function_scope (Pad_size_unsafe (sizeof(T)) = =sizeof(T)); if((mdatapos+sizeof(Val)) <=mdatacapacity) {restart_write:*reinterpret_cast<t*> (Mdata+mdatapos) = Val;//Append Val to Mdata        returnFinishwrite (sizeof(Val)); } status_t Err= Growdata (sizeof(Val));//If the mdata space is not enough, the first expansion    if(Err = = No_error)GotoRestart_write; returnerr;}

Mdata is a memory stack, Writexxx writes the data to the stack, if the mdata space is not enough, first to mdata expansion, and the original data moved to a new space, and then write the new data to the stack.

Parcel::writestrongbinder (...) The logic is more complex, and its invocation relationship is as follows:

Frameworks/native/libs/binder/parcel.cpp

872    Parcel::writestrongbinder (const sp<ibinder>& val)205        Parcel::flatten_ Binder (const/*proc*/,  constout = this)

See Flatten_binder (...), frameworks/native/libs/binder/parcel.cpp:205

status_t Flatten_binder (Constsp<processstate>&/*proc*/,    Constsp<ibinder>& Binder, parcel* out) {Flat_binder_object obj; Obj.flags=0x7f|Flat_binder_flag_accepts_fds; if(Binder! =NULL) {IBinder*local = binder->Localbinder (); if(!local) {//Remote type Binder encapsulation logicBpbinder *proxy = binder->Remotebinder (); if(Proxy = =NULL) {Aloge ("NULL proxy"); }            Constint32_t handle = proxy? Proxy->handle ():0; Obj.type=Binder_type_handle; Obj.binder=0;/*Don ' t pass uninitialized stack data to a remote process*/Obj.handle=handle; Obj.cookie=0; } Else{//local type Binder wrapper logicObj.type =Binder_type_binder; Obj.binder= Reinterpret_cast<uintptr_t> (local->getweakrefs ()); Obj.cookie= reinterpret_cast<uintptr_t> (local); }    } Else{Obj.type=Binder_type_binder; Obj.binder=0; Obj.cookie=0; }    returnFinish_flatten_binder (binder, obj, out);}

It does different data encapsulation based on the type of binder that is passed in, and in frameworks/native/include/binder/ibinder.h:139, you can see that IBinder declares two virtual functions:

class  Public Virtual refbase{public:    ...     Virtual bbinder*        Localbinder ();     Virtual bpbinder*       Remotebinder ();    ...};

And the default implementation is defined in FRAMEWORKS/NATIVE/LIBS/BINDER/BINDER.CPP:47:

bbinder* Ibinder::localbinder () {    return  NULL;} Bpbinder* ibinder::remotebinder () {    return  NULL;}

Flat_binder_object This data structure in the Binder study Note (iv)--servicemanager How to respond to Checkservice request ServiceManager How to organize reply data, It is defined in external/kernel-headers/original/uapi/linux/binder.h:57. The data for the different binder packages is as follows:

Then Flatten_binder (...) Call Finish_flatten_binder (...), frameworks/native/libs/binder/parcel.cpp:199

Static status_t finish_flatten_binder (    const/*binder*/const  out ) {    returnoutfalse);}

Continue calling WriteObject (...), frameworks/native/libs/binder/parcel.cpp:1035

status_t Parcel::writeobject (Constflat_binder_object& Val,BOOLnullmetadata) {    Const BOOLEnoughdata = (mdatapos+sizeof(Val)) <=mdatacapacity; Const BOOLEnoughobjects = Mobjectssize <mobjectscapacity; if(Enoughdata &&enoughobjects) {restart_write://If there is enough space, he appends the Flat_binder_object entity assembled in front to the Mdata*reinterpret_cast<flat_binder_object*> (Mdata+mdatapos) =Val; ...if(Nullmetadata | | Val.binder! =0) {      //mobjects record the offset position of each flat_binder_object appended to the MdataMobjects[mobjectssize] =Mdatapos; Acquire_object (Processstate::self (), Val, This, &mopenashmemsize); Mobjectssize++; }        returnFinishwrite (sizeof(Flat_binder_object)); } ...}

Summary: Parcel The data area is divided into two parts: Mdata and Mobjects , all data is appended to the mdata, whether it is the underlying data type or the object entity , Mobjects . is an offset array that records all stored in the Mdata Flat_binder_object in the the offset of the entity. The Parcel data model is as follows:

Binder Learning Note (v) how does--parcel package data?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.