Analysis of connection process between Android application and surfaceflinger service

Analysis of connection process between Android application and surfaceflinger service

Invalid Sign

From the previous article on the display process of the boot screen of the Android system, we can know that the boot animation of the Android system is mainly realized by a bootanimation object. When this bootanimation object is constructed, it will create a surfacecombierclient object internally to be responsible for creating a connection to the surfaceflinger service.

The constructor of bootanimation class is implemented in the file frameworks / base / CMDS / bootanimation / bootanimation.cpp, as follows:

BootAnimation::BootAnimation() : Thread(false)
{
    mSession = new SurfaceComposerClient();
}

Msession is a member variable of the bootanimation class. It is a strong pointer of type surfacecomposerclient, that is, sp. For the relevant knowledge of smart pointer of Android system, please refer to the implementation principle analysis of smart pointer (lightweight pointer, strong pointer and weak pointer) of Android system.

Inside the surfacecomposerclient class, there is a member variable mclient of type SP, as shown in Figure 1:

The member variable mclient of surfacecomponentclient class actually points to a binder proxy object of type bpsurfacecomponentclient, and the binder proxy object of type bpsurfacecomponentclient refers to a binder local object of type client. In the previous article "overview of the relationship between Android application and surfaceflinger service" and "learning plan", it is mentioned that the binder local object of type client is created by surfaceflinger service and runs in surfaceflinger service to represent a client using surfaceflinger service, that is, an Android application related to UI.

Since the client class and bpsurfacecombierclient class are a binder local object class and a binder proxy object class respectively, they are implemented according to the binder interprocess communication library provided by the Android system in the application framework layer. Their implementation structure diagrams are shown in Figure 2 and figure 3 respectively:

Figure 2 implementation structure of client class

Figure 3 implementation structure diagram of bpsurfacecomposerclient class

In Figure 2 and figure 3, many classes of binder interprocess communication library are involved. Readers need to have a certain understanding and understanding of binder interprocess communication mechanism of Android system. In the previous series of articles on Binder's brief introduction and learning plan of Android interprocess communication (IPC), we have learned binder's interprocess communication mechanism of Android system, which will not be detailed here.

Figure 2 and figure 3 give us the most important information that both the client class and the bpsurfacecomponentclient class implement the binder interface of type isurfacecomponentclient. The isurfacecomposerclient interface has two important member functions getcontrolblock and createsurface, which are defined in the file frameworks / base / include / surfacelinker / isurfacecomposerclient. H, as shown below:

class ISurfaceComposerClient : public IInterface
{
public:
    ......
 
    virtual sp<IMemoryHeap> getControlBlock() const = 0;
    ......
 
    /*
     * Requires ACCESS_SURFACE_FLINGER permission
     */
    virtual sp<ISurface> createSurface( surface_data_t* data,int pid,const String8& name,DisplayID display,uint32_t w,uint32_t h,PixelFormat format,uint32_t flags) = 0;
    ......
 
};

Among them, the member function getcontrolblock is used to obtain an anonymous shared memory created by the surfaceflinger service to transfer UI metadata, and the member function createsurface is used to request the surfaceflinger service to create a surface. As you can know from the previous article overview of the relationship between Android applications and surfaceflinger service and learning plan, The anonymous shared memory used to transfer UI metadata will eventually be structured into a sharedclient object, which exists at most one in each application process. In the next two articles, we will analyze in detail the implementation of the member functions getcontrolblock and createsurface of the isurfacecombinclient interface.

After understanding the relationship between surfacecomposerclient, client and bpsurfacecomposerclient, we can analyze how bootanimation, the boot animation application of Android system, establishes a connection with surfaceflinger service.

As can be seen from Figure 1, the surfacecomponentclient class inherits the refbase class. Therefore, when the bootanimation class creates a surfacecomponentclient object in the constructor and assigns this object to the smart pointer msession of type SP, the member function onfirstref of the surfacecomponentclient class will be called, During the calling process of the member function onfirstref of the surfacecomposerclient class, a connection will be established between the application bootimation and the surfaceflinger service, as shown in Figure 4:

Next, we will analyze each step in detail.

Step 1. SurfaceComposerClient::onFirstRef

void SurfaceComposerClient::onFirstRef()
{
    sp<ISurfaceComposer> sm(getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            ......
            mStatus = NO_ERROR;
        }
    }
}

The member function onfirstref of the surfacecomposerclient class is implemented in the file frameworks / base / LIBS / surfacelinker_ Client / surfacecomposerclient.cpp file.

The member function getcomposerservice of surfacecombierclient class is used to obtain a proxy interface of surfaceflinger service. Its implementation is as follows:

sp<ISurfaceComposer> ComposerService::getComposerService() {
    return ComposerService::getInstance().mComposerService;
}

Composerservice class is a singleton mode. When we call its static function getInstance for the first time, it will obtain a proxy interface of surfaceflinger service in the constructor and save it in its member variable mcomposerservice, as shown below:

ComposerService::ComposerService()
: Singleton<ComposerService>() {
    const String16 name("SurfaceFlinger");
    while (getService(name,&mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    mServerCblkMemory = mComposerService->getCblk();
    mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
            mServerCblkMemory->getBase());
}

In the constructor of composerservice class, in addition to obtaining the proxy interface of surfaceflinger service, an anonymous shared memory mservercblkmemory is also obtained through the member function getcblk of the proxy interface. This anonymous shared memory is created by the surfaceflinger service to describe the information of the system display screen, such as the number, size, direction, density and so on. Because this information can be passed through a surface_ flinger_ cblk_ T object, so the constructor of composerservice class finally structures a piece of anonymous shared memory previously obtained from the surfaceflinger service into a surface_ flinger_ cblk_ T object and saved in the member variable mservercblk of the composerservice class.

Returning to the member function onfirstref of the surfacecombinclient class, since the surfaceflinger service implements the isurfacecombiner interface, we can assign the proxy interface of the surfaceflinger service obtained earlier to a strong pointer sm of type isurfacecombiner, and call its member function createconnection to request the surfaceflinger service to create a connection, That is, create a binder object of type client and return a proxy interface conn of the binder object. After the surfacecomposerclient class obtains the client proxy interface conn returned by the surfaceflinger service, it saves it in its own member variable mclient, so that when the animation application bootanimation is started, it can request surfaceflinger to create and render the surface.

Next, we will continue to analyze the implementation of the member function createconnection of the surfaceflinger service so that we can understand how it creates a connection for Android applications.

Step 2. SurfaceFlinger::createConnection

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}

The member function createconnection of surfaceflinger class is implemented in the file frameworks / base / services / surfacelinker / surfaceflinger.cpp. Its implementation is very simple. It just creates a binder object client of type client and obtains an isurfacecomponentclient interface. Finally, the isurfacecomponentclient interface, that is, a client proxy object, Returns to the boot animation application bootanimation.

Next, we will continue to analyze the creation process of the client object, that is, the implementation of the constructor of the client class.

Step 3. new Client

Client::Client(const sp<SurfaceFlinger>& flinger)
    : mFlinger(flinger),mNameGenerator(1)
{
}

The client class has two member variables mfringer and mnamegenerator, whose types are SP and int32 respectively_ t. The former points to the surfaceflinger service, while the latter is used to generate the name of each surface created by the surfaceflinger service for Android applications. For example, suppose an Android application requests surfaceflinger to create two surfaces, then the name of the first surface is described by the number 1, the second surface is described by the number 2, and so on. From the previous article on the relationship between Android application and surfaceflinger service and learning plan, it can be known that an Android application can create up to 31 surfaces.

Back to the member function createconnection of the surfaceflinger class, it returns an isurfacecomponentclient interface pointing to a client object to the boot animation application bootanimation. After bootanimation, the boot animation application can encapsulate it into a binder proxy object with a class of bpsurfacecomponentclient.

Step 4. return BpSurfaceComposerClient

The encapsulation process of binder proxy object of type bpsurfacecombinclient is implemented in the member function createconnection of binder proxy object class bpsurfacecombiner of surfaceflinger service, as shown below:

class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
    ......
 
    virtual sp<ISurfaceComposerClient> createConnection()
    {
        uint32_t n;
        Parcel data,reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION,data,&reply);
        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
    }
 
    ......
}

interface_ Cast is a template function, which is defined in the framework / base / include / binder / iiinterface. H file:

template<typename INTERFACE>  
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
{  
    return INTERFACE::asInterface(obj);  
}  

It can be seen from here that when the template parameter is isurfacecomponentclient, the template function interface_ In fact, cast encapsulates a binder proxy object described by parameter obj, that is, a bpbinder object, into a bpsurfacecomposerclient object by calling the static member function asinterface of the isurfacecomposerclient class.

The static member function asinterface of the isurfacecomposerclient class is composed of frameworks / base / LIBS / surfacelinker_ Implement in the client / isurfacecomponentclient.cpp file_ Meta_ Interface macro, as shown below:

IMPLEMENT_Meta_INTERFACE(SurfaceComposerClient,"android.ui.ISurfaceComposerClient");

IMPLEMENT_ Meta_ After the interface macro is expanded, the implementation of the static member function asinterface of the isurfacecomponentclient class is as follows:

android::sp<ISurfaceComposerClient> ISurfaceComposerClient::asInterface(const android::sp<android::IBinder>& obj)       {                                                                                       
    android::sp<ISurfaceComposerClient> intr;                                                      
      
    if (obj != NULL) {                                                                       
        intr = static_cast<ISurfaceComposerClient*>(                                                    
                    obj->queryLocalInterface(ISurfaceComposerClient::descriptor).get());  
          
        if (intr == NULL) {                  
            intr = new BpSurfaceComposerClient(obj);                                          
        }                                            
    }  
    return intr;                                    
}     

The parameter obj is passed in from the member function createconnection of the bpsurfacecomposer class. It actually points to a bpbinder object. When we call the member function querylocalinterface of a bpbinder object, we get a null pointer. Therefore, the static member function asinterface of the isurfacecomponentclient class will finally encapsulate a bpbinder object pointed to by the parameter obj into a bpsurfacecomponentclient object and return it to the caller.

For a more specific encapsulation process of bpsurfacecomponentclient object, please refer to the encapsulation process of bpservicemanager object described in the previous article on the way for server and client to obtain service manager interface in Android system interprocess communication (IPC) mechanism binder.

So far, bootanimation, the boot animation application, establishes a connection with the surfaceflinger service through the surfacecomposerclient class.

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
分享
二维码
< <上一篇
下一篇>>