The inter process communication (IPC) mechanism of Android system is the way for the server and client in binder to obtain the service manager interface

In the previous article on how service manager becomes a binder daemon of Android interprocess communication (IPC) mechanism, we introduced how service manager becomes a binder daemon. As a daemon, the responsibility of service manager is to serve the server and client. Then, how can the server and client obtain the service manager interface and enjoy the services it provides? This article will briefly analyze the process of server and client obtaining service manager.

Before reading this article, I hope readers will first read the references mentioned in the brief introduction and learning plan of Android interprocess communication (IPC) mechanism binder, Android's binder mechanism in simple terms, so as to deepen their understanding of this article.

As we know, service manager plays the role of both daemon and server in binder mechanism. However, it is different from general server. For an ordinary server, if the client wants to obtain the remote interface of the server, it must obtain it through the getservice interface provided by the remote interface of the service manager. This itself is a process of inter process communication using the binder mechanism. For the service manager server, if the client wants to obtain the service manager remote interface, it does not need to obtain it through the inter process communication mechanism, because the service manager remote interface is a special binder reference, and its reference handle must be 0.

The function to obtain the remote interface of service manager is defaultservicemanager, which is declared in frameworks / base / include / binder / iservicemanager H in the document:

sp<IServiceManager> defaultServiceManager();

Implemented in frameworks / base / LIBS / binder / iservicemanager Cpp file:

Gdefaultservicemanagerlock and gdefaultservicemanager are global variables defined in frameworks / base / LIBS / binder / static Cpp file:

It can be seen from this function that gdefaultservicemanager is a singleton mode. When calling the defaultservicemanager function, if gdefaultservicemanager has been created, it will be returned directly, otherwise it will be through the interface_ Cast < iservicemanager > (processstate:: self() - > getcontextobject (null)) to create one and save it in the gdefaultservicemanager global variable.

Continue with the interface_ Before the implementation of cast < iservicemanager > (processstate:: self() - > getcontextobject (null)), let's take a look at a class diagram, which can help us understand the creation process of the service manager remote interface.

Reference: readers of Android's binder mechanism in simple terms should be able to understand this figure more easily. This figure shows that the bpservicemanager class inherits the bpinterface < iservicemanager > class. Bpinterface is a template class defined in frameworks / base / include / binder / iiinterface H in the document:

Iservicemanager class inherits iinterface class, while iinterface class and bprefbase class inherit refbase class respectively. In the bprefbase class, there is a member variable mremote, whose type is ibinder *, and the implementation class is bpbinder, which represents a binder reference, and the reference handle value is saved in the mhandle member variable of the bpbinder class. The bpbinder class interacts with the binder driver through the ipcthreadstate class, and ipcthreadstate opens the / dev / binder device file through its member variable mprocess. The type of mprocess member variable is processstate. After the processstate class opens the device / dev / binder, the open file descriptor is saved in the mdriverfd member variable for subsequent use.

After understanding these concepts, you can continue to analyze the process of creating a service manager remote interface. The ultimate goal is to create a bpservicemanager instance and return its iservicemanager interface. The following statements are used to create a service manager remote interface:

gDefaultServiceManager = interface_ cast<IServiceManager>( ProcessState::self()->getContextObject(NULL));

It looks short, but there is a mystery. For details, please read the reference of Android binder mechanism in simple terms, which is briefly described here.

The first is to call processstate:: self function, which is a static member function of processstate. Its function is to return a globally unique processstate instance variable, that is, singleton mode. This variable is called gprocess. If gprocess has not been created, the creation operation will be performed. In the constructor of processstate, the device file / dev / binder will be opened through the open file operation function, and the returned device file descriptor will be saved in the member variable mdriverfd.

Then call the gprocess - > getcontextobject function to obtain a binder reference with a handle value of 0, that is, bpbinder. Therefore, the statement to create the service manager remote interface can be simplified as follows:

gDefaultServiceManager = interface_ cast<IServiceManager>(new BpBinder(0));

Let's look at the function interface_ The implementation of cast < iservicemanager >, which is a template function defined in framework / base / include / binder / iiinterface H in the document:

The interface here is iservicemanager, so the iservicemanager:: asinterface function is called. Iservicemanager:: asinterface is through declare_ Meta_ The interface (servicemanager) macro is declared in the iservicemanager class and is located in framework / base / include / binder / iservicemanager H in the document:

DECLARE_ Meta_ INTERFACE(ServiceManager);

Expand to:

Iservicemanager:: asinterface is implemented through implement_ Meta_ Interface (servicemanager, "Android. OS. Iservicemanager") macro, which is located in framework / base / LIBS / binder / iservicemanager Cpp file:

IMPLEMENT_ Meta_ INTERFACE(ServiceManager,"android.os.IServiceManager");

Expand to:

It is estimated that the employee who wrote this code changed jobs from Microsoft to Google. Here we focus on the implementation of iservicemanager:: asinterface:

The parameter obj passed in here is the new bpbinder (0) just created. The member function querylocalinterface in the bpbinder class inherits from the base class ibinder. The ibinder:: querylocalinterface function is located in framework / base / LIBS / binder / binder Cpp file:

It can be seen that in iservicemanager:: asinterface function, the following statement will eventually be called:

intr = new BpServiceManager(obj);

Namely:

intr = new BpServiceManager(new BpBinder(0));

Returning to the defaultservicemanager function, the final result is:

gDefaultServiceManager = new BpServiceManager(new BpBinder(0));

In this way, the service manager remote interface is created. It is essentially a bpservicemanager, containing a binder reference with a handle value of 0.

In the binder mechanism of Android system, how can the server and client use the service manager remote interface?

For the server, it calls the iservicemanager:: addservice interface to interact with the binder driver, that is, it calls bpservicemanager:: addservice. Bpservicemanager:: addservice will call the member function remote of its base class bprefbase to obtain the originally created bpbinder instance, and then call the bpbinder:: transact member function. In the bpbinder:: transact function, the ipcthreadstate:: transact member function will be called again. Here is the final place to interact with the binder driver. Recall the previous class diagram. Ipcthreadstate has a pocessstate type middle variable mprocess, and mprocess has a member variable mdriverfd, which is the open file descriptor of the device file / dev / binder. Therefore, ipcthreadstate is equivalent to indirectly owning the open file descriptor of the device file / dev / binder. Therefore, You can interact with the binder driver.

For the client, the interface iservicemanager:: getservice is called to interact with the binder driver. The specific process is the same as that of the above server using service manager, which will not be described here.

For the specific implementation of iservicemanager:: addservice and iservicemanager:: getservice, in the following two articles, we will go deep into the binder driver layer and conduct detailed source code analysis to better understand the binder inter process communication mechanism. Please pay attention.

The above is the sorting of Android binder communication materials. We will continue to supplement relevant materials in the future. Thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>