Android applications and connection process SurfaceFlinger analysis services

Android applications and connection process SurfaceFlinger analysis services

Android system boot animation is achieved by the application bootanimation, which is located in / system / bin directory, which may refer to the specific implementation of the Android system startup screen is displayed analysis article. Why choose Android boot animation system to analyze the connection process SurfaceFlinger Android applications and service it? First of all, responsible for implementing the application bootanimation boot animation is an Android application, except that it is using the C ++ language development; secondly, the application bootanimation is associated with the UI, ie it uses the Java language to develop the standard Android application Like the program, need to use SurfaceFlinger services to create and render your own Surface, namely boot animation; third, because the application does not involve bootanimation user input that does not require interaction (touch screen, keyboard, etc.) to the user, so that it can the most succinct way to reflect the relationship SurfaceFlinger Android applications and services.

From the start-up screen in front of the Android system displays process analysis article may know, boot animation Android system is primarily a BootAnimation object to implement this BootAnimation objects at construction time, it creates a SurfaceComposerClient objects in the interior to be responsible for creating a to SurfaceFlinger services connection.

BootAnimation class constructor implemented in the file frameworks / base / cmds / bootanimation / BootAnimation.cpp, as follows:

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

 mSession BootAnimation class member variables, which is a type of strong SurfaceComposerClient pointer, i.e. sp . Knowledge of smart pointers Android system, can refer to Android smart pointers (pointer lightweight, strong and weak pointers pointer) implementation of the principle of analysis article.

Inside SurfaceComposerClient class, there is a type of sp Member variable mClient, shown in Figure 1:

image

SurfaceComposerClient class member variables of mClient point is actually a type of BpSurfaceComposerClient Binder proxy object, and this type Binder BpSurfaceComposerClient proxy object reference is a type of Binder Client local object. In front Relations Overview and learning programs SurfaceFlinger Android applications and services mentioned in the article, the type of Binder Client SurfaceFlinger local object is responsible for creating the service and runs SurfaceFlinger service, used to represent the use of a service SurfaceFlinger the client, that is a Android app UI-related.

Since the Client class and are a class BpSurfaceComposerClient Binder Binder local proxy object class and a class of objects, which are in accordance with inter-process Binder Android application framework system layer provides a communication library implemented, they are implemented configuration diagram of FIG. 2 and 3:

image

FIG 2 Client implementation structure of the class

image

FIG 3 BpSurfaceComposerClient class implementation structure of FIG.

In Figures 2 and 3, involves a relatively large number of inter-process communication type Binder library, readers need to have an understanding and awareness of the process among Binder Android system communication mechanism. Between the front of the Android-process communication (IPC) mechanism Binder brief introduction and learning plans a series of articles, we have learned Binder inter-process communication mechanism of the Android system, not described in detail here.

图2和图3给我们最重要的信息是Client类和BpSurfaceComposerClient类均实现了类型为ISurfaceComposerClient的Binder接口。ISurfaceComposerClient接口有两个重要的成员函数getControlBlock和createSurface,它们定义在文件frameworks/base/include/surfaceflinger/ISurfaceComposerClient.h中,如下所示:

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;
    ......
 
};

其中,成员函数getControlBlock用来获得由SurfaceFlinger服务创建的一块用来传递UI元数据的匿名共享内存,而成员函数createSurface用来请求SurfaceFlinger服务创建一个Surface.从前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文可以知道,用来传递UI元数据的匿名共享内存最终会被结构化为一个SharedClient对象,这个SharedClient对象在每个应用程序进程中至多存在一个。在接下来的两篇文章中,我们再详细分析ISurfaceComposerClient接口的成员函数getControlBlock和createSurface的实现。

理解了SurfaceComposerClient、Client以及BpSurfaceComposerClient这三个类的关系之后,接下来我们就可以分析Android系统的开机动画应用程序bootanimation是如何与SurfaceFlinger服务建立连接的。

从图1可以知道,SurfaceComposerClient类继承了RefBase类,因此,当BootAnimation类在构造函数创建了一个SurfaceComposerClient对象,并且将这个对象赋值给类型为sp 的智能指针mSession时,就会导致SurfaceComposerClient类的成员函数onFirstRef被调用,而SurfaceComposerClient类的成员函数onFirstRef在调用的过程中,就会在应用程序bootanimation与SurfaceFlinger服务建立一个连接,这个过程如图4所示:

image

接下来,我们就详细分析每一个步骤。

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;
        }
    }
}

SurfaceComposerClient类的成员函数onFirstRef实现在文件frameworks/base/libs/surfaceflinger_client/SurfaceComposerClient.cpp文件中。

SurfaceComposerClient类的成员函数getComposerService用来获得SurfaceFlinger服务的一个代理接口,它的实现如下所示:

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

ComposerService类是单例模式,当我们第一次调用它的静态函数getInstance的时候,它就会在构造函数中获得SurfaceFlinger服务的一个代理接口,并且保存在它的成员变量mComposerService中,如下所示:

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());
}

在ComposerService类的构造函数中,除了会获得SurfaceFlinger服务的代理接口之外,还会通过这个代理接口的成员函数getCblk来获得一块匿名共享内存mServerCblkMemory。这块匿名共享内存是由SurfaceFlinger服务创建的,用来描述系统显示屏的信息,例如,显示屏的个数、大小、方向、密度等等信息。由于这些信息可以通过一个surface_flinger_cblk_t对象来描述,因此,ComposerService类的构造函数最后就将前面从SurfaceFlinger服务获得的一块匿名共享内存结构化为一个surface_flinger_cblk_t对象,并且保存在ComposerService类的成员变量mServerCblk中。

回到SurfaceComposerClient类的成员函数onFirstRef中,由于SurfaceFlinger服务实现了ISurfaceComposer接口,因此,我们可以将前面获得的SurfaceFlinger服务的代理接口赋值给一个类型为ISurfaceComposer的强指针sm,并且调用它的成员函数createConnection来请求SurfaceFlinger服务创建一个连接,即创建一个类型为Client的Binder对象,并且将这个Binder对象的一个代理接口conn返回来。SurfaceComposerClient类获得了SurfaceFlinger服务返回来的Client代理接口conn之后,就将它保存自己的成员变量mClient中,这样开机动画应用程序bootanimation后续就可以通过它来请求SurfaceFlinger创建和渲染Surface了。

接下来,我们就继续分析SurfaceFlinger服务的成员函数createConnection的实现,以便可以了解它是如何为Android应用程序创建一个连接的。

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;
}

SurfaceFlinger类的成员函数createConnection实现在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,它的实现很简单,只是创建了一个类型为Client的Binder对象client,并且获得它的一个ISurfaceComposerClient接口,最后将这个ISurfaceComposerClient接口,即一个Client代理对象,返回给开机动画应用程序bootanimation。

接下来,我们再继续分析Client对象的创建过程,,即Client类的构造函数的实现。

Step 3. new Client

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

Client类有两个成员变量mFlinger和mNameGenerator,它们的类型分别为sp 和int32_t,前者指向了SurfaceFlinger服务,而后者用来生成SurfaceFlinger服务为Android应用程序所创建的每一个Surface的名称。例如,假设一个Android应用程序请求SurfaceFlinger创建了两个Surface,那么第一个Surface的名称就由数字1来描述,而第二个Surface就由数字2来描述,依次类推。从前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划这篇文章可以知道,一个Android应用程序最多可以创建31个Surface。

回到SurfaceFlinger类的成员函数createConnection中,它将一个指向了一个Client对象的ISurfaceComposerClient接口返回到开机动画应用程序bootanimation之后,开机动画应用程序bootanimation就可以将它封装成一个类型为BpSurfaceComposerClient的Binder代理对象。

Step 4. return BpSurfaceComposerClient

类型为BpSurfaceComposerClient的Binder代理对象的封装过程实现在SurfaceFlinger服务的Binder代理对象类BpSurfaceComposer的成员函数createConnection中,如下所示:

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是一个模板函数,它定义在framework/base/include/binder/IInterface.h文件中:

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

从这里就可以看出,当模板参数为ISurfaceComposerClient的时候,模板函数interface_cast实际就是通过调用ISurfaceComposerClient类的静态成员函数asInterface来将参数obj所描述的一个Binder代理对象,即一个BpBinder对象,封装成一个BpSurfaceComposerClient对象。

 ISurfaceComposerClient类的静态成员函数asInterface是由frameworks/base/libs/surfaceflinger_client/ISurfaceComposerClient.cpp文件中的IMPLEMENT_META_INTERFACE宏来定义的,如下所示:

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

IMPLEMENT_META_INTERFACE宏展开后,得到ISurfaceComposerClient类的静态成员函数asInterface的实现如下所示:

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;                                    
}     

 参数obj是从BpSurfaceComposer类的成员函数createConnection传进来的,它指向的实际上是一个BpBinder对象。当我们调用一个BpBinder对象的成员函数queryLocalInterface时,获得的是一个NULL指针,因此,ISurfaceComposerClient类的静态成员函数asInterface最后就会将参数obj所指向的一个BpBinder对象封装成一个BpSurfaceComposerClient对象,并且返回给调用者。

        More specifically, the encapsulation process object may refer to the previous BpSurfaceComposerClient On Android system inter-process communication (IPC) mechanism of Server and Client Binder packaging process obtained BpServiceManager Service Manager object is a road interfaces described herein.

        At this point, the boot animation application bootanimation on by SurfaceComposerClient class to establish a connection with the service SurfaceFlinger.

Guess you like

Origin www.cnblogs.com/linhaostudy/p/12382081.html