AndroidQ window和SurfaceFlinger建立连接分析

之前写了几篇文章来分析Android的窗口机制,我们知道不管什么窗口最终都会通过WMS的addWindow方法进行添加,这个方法中会为每一个符合要求的窗口创建一个WindowState用来描述,今天要分析的就是这些窗口创建好了之后和surfaceFlinger进程建立连接的过程

直接从WMS的addWindow方法开始

WMS.addWindow

public int addWindow(Session session, IWindow client, int seq,
            LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
            InsetsState outInsetsState) {
            /*一系列窗口权限检查*/
			......
				//为每一个符合要求的窗口创建WindowState
				final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid,
                    session.mCanAddInternalSystemWindow);
            ......
            win.attach();
			......

}

描述窗口的WindowState创建好了之后会调用它的attach方法

WindowState.attach

void attach() {
        if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
        mSession.windowAddedLocked(mAttrs.packageName);
    }

这个mSession是通过参数传递过来的,它的类型是IWindowSession,是一个Binder服务端,是app端通过调用WMS的openSession方法创建的

Session.windowAddedLocked

void windowAddedLocked(String packageName) {
        mPackageName = packageName;
        mRelayoutTag = "relayoutWindow: " + mPackageName;
        if (mSurfaceSession == null) {
            ...
            mSurfaceSession = new SurfaceSession();
            ...
        }
        mNumWindow++;
    }

mNumWindow这个变量代表当前系统window的个数,windowAddedLocked这个方法中创建了一个SurfaceSession,来看看SurfaceSession的构造方法

SurfaceSession

private long mNativeClient; // SurfaceComposerClient*
/** Create a new connection with the surface flinger. */
public SurfaceSession() {
        mNativeClient = nativeCreate();
    }

看它的注释,创建一个和surfaceflinger的连接,nativeCreate这个native方法就是建立window和surfaceflinger连接的关键,mNativeClient保存了native层SurfaceComposerClient的指针

nativeCreate方法定义在android_view_SurfaceSession中

nativeCreate

通过JNI调到了native层

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    SurfaceComposerClient* client = new SurfaceComposerClient();
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);
}

创建了SurfaceComposerClient,这个类在前面几篇Vsync文章中分析过,可以理解为上层调用SurfaceFlinger进程的client端,这个类的构造函数没做什么事,我们主要来看它的onFirstRef函数

SurfaceComposerClient::onFirstRef

void SurfaceComposerClient::onFirstRef() {
    //步骤1
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
       //步骤2
        conn = sf->createConnection();
        if (conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

这个函数分两步来看,先看步骤1,创建一个ISurfaceComposer对象,这一看就是Binder接口

看看如何创建的

ComposerService::getComposerService()

/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == nullptr) {
        ComposerService::getInstance().connectLocked();
		...
    }
    return instance.mComposerService;
}

这个函数中又调用了ComposerService的connectLocked函数来创建ISurfaceComposer

connectLocked

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != nullptr);

     /*创建binder死亡回调相关..*/
     ......
}

这个函数很好理解,获取SurfaceFlinger服务,传了一个mComposerService地址获取,很明显就是将获取到的SurfaceFlinger服务放到mComposerService里面,mComposerService是ComposerService的成员变量

这里的getService定义在IServiceManager.h中,主要作用就是通过servicemanager获取binder服务,client端和server端不在同一进程,获取到的其实是Bp端代理,native层有一个很重要的函数interface_cast,它的作用类似java层的asInterface,主要作用是将IInterface转化为BpInterface,这些Binder相关的知识这里不细说了,总之这里的getService函数最终得到的就是BpSurfaceComposer,这是surfaceFlinger服务的Bp端,有了它就可以和surfaceFlinger进行binder通信了

好了,ComposerService::connectLocked这个函数主要作用就是创建BpSurfaceComposer,并保存在mComposerService中

步骤1分析完了,创建了BpSurfaceComposer,它继承自ISurfaceComposer

void SurfaceComposerClient::onFirstRef() {
    //步骤1
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
       //步骤2
        conn = sf->createConnection();
        if (conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

再来看看步骤2,conn = sf->createConnection(),调用BpSurfaceComposer的createConnection函数,返回ISurfaceComposerClient,这也是一个Binder接口,其实最终返回的也是BpSurfaceComposerClient

先来看看BpSurfaceComposer的createConnection函数

BpSurfaceComposer.createConnection

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

通过remote()->transact进行Binder调用,将返回的ISurfaceComposerClient转换为BpSurfaceComposerClient

接着看Binder服务端实现的createConnection函数,surfaceFlinger继承BnSurfaceComposer,所以实现在surfaceFlinger中

SurfaceFlinger.createConnection

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    return initClient(new Client(this));
}

代码很简单,new了一个Client作为initClient的参数,initClient函数中调用了Client的initCheck,initCheck函数直接返回NO_ERROR,所以initClient直接将new出来的Client返回给了client端

可以发现创建Client时将SurfaceFlinger传递了过去

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

Client的构造函数很简单,什么也没做,就是保存了SurfaceFlinger的引用,Client继承BnSurfaceComposerClient,作为Binder服务端,可以想到Client做的事情还是需要SurfaceFlinger来做的,去看Client.cpp源码发现,所有方法中其实还是调用mFlinger->XXX,Client只是一个空架子

步骤2分析完了,主要就是在SurfaceFlinger进程创建了一个Client对象,并返回,返回到SurfaceComposerClient这边再通过interface_cast转换为了BpSurfaceComposerClient,保存在了SurfaceComposerClient的mClient变量中,自此window和surfaceFlinger的连接就建立了

其实步骤1和步骤2创建了两个SurfaceFlinger进程的Bp端,一个是BpSurfaceComposer,这个Bp端是直接调用SurfaceFlinger的函数,还有一个BpSurfaceComposerClient,这个Bp端是通过SurfaceFlinger进程的Client对象间接调用SurfaceFlinger的函数

总结一下上层window和surfaceflinger建立连接的过程:

  1. 每一个window最终都会调用WMS的addWindow方法进行添加,并且创建一个WindowState来描述窗口信息
  2. 接着调用WindowState的attach方法,通过Session的windowAddedLocked方法创建SurfaceSession对象
  3. SurfaceSession对象构造方法中调用nativeCreate方法创建native层的SurfaceComposerClient对象,并保存其指针在自己的mNativeClient中
  4. SurfaceComposerClient对象首次创建时通过初始化函数onFirstRef分两步建立与surfaceflinger进程的连接
  5. 步骤1,创建surfaceflinger的Bp端BpSurfaceComposer,步骤2,通过BpSurfaceComposer调用surfaceflinger的createConnection函数在surfaceflinger进程中创建Bn端Client对象,并返回,SurfaceComposerClient中保存的是Client的Bp端BpSurfaceComposerClient,保存在其mClient变量中

我们还可以得出如下对象的对应关系:
每一个Window对应WMS的一个WindowState,每一个WindowState对应一个SurfaceSession,每一个SurfaceSession对应一个SurfaceComposerClient,保存在其mNativeClient中,
每一个SurfaceComposerClient对应一个SurfaceFlinger进程的Client

发布了49 篇原创文章 · 获赞 72 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34211365/article/details/105433812