Get the App
SLTechnology News&Howtos  ›  Internet Technology  › 

How does ​ connect client and Service communication after establishment

Shulou Source: shulou.com Published: 2022-06-01 04:10:01 10月01日 Update

Today, the editor will share with you how to connect the established client and Service communication related knowledge points, the content is detailed, the logic is clear, I believe most people still know too much about this knowledge, so share this article for your reference, I hope you can get something after reading this article, let's take a look at it.

Here, take CameraService::connect () as an example.

@ Camera.cpp

Sp Camera::connect ()

{

LOGV ("connect")

Sp c = new Camera ()

Const sp& cs = getCameraService ()

If (cs! = 0) {

C-> mCamera = cs- > connect (c); / / this statement will enter BpCameraService::connect ()

}

Return c

}

@ ICameraService.cpp

Virtual sp connect (const sp& cameraClient)

{

Parcel data, reply

Data.writeInterfaceToken (ICameraService::getInterfaceDescriptor ())

Data.writeStrongBinder (cameraClient- > asBinder ())

Remote ()-> transact (BnCameraService::CONNECT, data, & reply)

Return interface_cast (reply.readStrongBinder ())

}

Here remote is a BpBinder object mapped by our CameraService

Virtual sp ICameraService:: connect () will call BpBinder::transact ()

à IPCThreadState::self ()-> transact (), and write it to binder driver

Binder driver will eventually wake up the reader thread running in IPCThreadState::joinThreadPool () in the media_server process.

Void IPCThreadState::joinThreadPool (bool isMain)

{...

Do {

...

Result = talkWithDriver ()

Size_t IN = mIn.dataAvail ()

If (IN

< sizeof(int32_t)) continue; cmd = mIn.readInt32(); result = executeCommand(cmd); } while (result != -ECONNREFUSED && result != -EBADF); … } 这一次,talkWithDriver()函数会返回BpCameraService:: connect ()生成的数据包,并调用executeCommand()函数执行命令。在本例中,命令为BR_TRANSACTION。 status_t IPCThreadState::executeCommand(int32_t cmd) { ...... switch(cmd){ ...... case BR_TRANSACTION: { binder_transaction_data tr; ...... Parcel reply; ...... if (tr.target.ptr) { sp b((BBinder*)tr.cookie); const status_t error = b->

Transact (tr.code, buffer, & reply, 0)

}

...

If ((tr.flags & TF_ONE_WAY) = = 0) {

LOG_ONEWAY ("Sending reply to d!", mCallingPid)

SendReply (reply, 0)

}

...

}

Break

.

} / / end of switch

...

}

The branch part where if (tr.target.ptr) is true is the most important. It takes an address from the binder kernel driver and converts it to a pointer of type BBinder (which is put into the binder kernel driver when the IServiceManager::addService () function is executed). Remember, CameraService inherits from BBinder. This pointer is actually the same pointer as the CameraService instance. So the next transact () function will be called to CaermaService::onTransact (), and then to the BnCameraService::onTransact () virtual function.

@ CameraService.cpp

Status_t CameraService::onTransact (

Uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

Switch (code) {

Case BnCameraService::CONNECT:

IPCThreadState* ipc = IPCThreadState::self ()

Const int pid = ipc- > getCallingPid ()

Const int self_pid = getpid ()

If (pid! = self_pid) {

/ / we're called from a different process, do the real check

If (! checkCallingPermission (

String16 ("android.permission.CAMERA")

{

Const int uid = ipc- > getCallingUid ()

LOGE ("Permission Denial:"

"can't use the camera pid=%d, uid=%d", pid, uid)

Return PERMISSION_DENIED

}

}

Break

}

Status_t err = BnCameraService::onTransact (code, data, reply, flags)

Return err

}

@ ICameraService.cpp

Status_t BnCameraService::onTransact (

Uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

Switch (code) {

Case CONNECT: {

CHECK_INTERFACE (ICameraService, data, reply)

Sp cameraClient = interface_cast (data.readStrongBinder ())

Sp camera = connect (cameraClient); / / Real handler

Reply- > writeStrongBinder (camera- > asBinder ())

Return NO_ERROR

} break

Default:

Return BBinder::onTransact (code, data, reply, flags)

}

}

At this point, a function call from client to service is completed.

Note that in this function, the system will call CameraService::connect ()

These are all the contents of the article "how to connect client and Service communications after establishment". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Tags: Functions pointers knowledge articles communications content kernels commands drivers different big important next branches addresses most instances actually objects Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno Shulou Technology Apple MariaDB macOS MySQL