之前写了几篇文章来分析Android的窗口机制,我们知道不管什么窗口最终都会通过WMS的addWindow方法进行添加,这个方法中会为每一个符合要求的窗口创建一个WindowState用来描述,今天要分析的就是这些窗口创建好了之后和surfaceFlinger进程建立连接的过程
直接从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方法
void attach() {
if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
mSession.windowAddedLocked(mAttrs.packageName);
}
这个mSession是通过参数传递过来的,它的类型是IWindowSession,是一个Binder服务端,是app端通过调用WMS的openSession方法创建的
void windowAddedLocked(String packageName) {
mPackageName = packageName;
mRelayoutTag = "relayoutWindow: " + mPackageName;
if (mSurfaceSession == null) {
...
mSurfaceSession = new SurfaceSession();
...
}
mNumWindow++;
}
mNumWindow这个变量代表当前系统window的个数,windowAddedLocked这个方法中创建了一个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中
通过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函数
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接口
看看如何创建的
/*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
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,主要作用是将BpBinder转化为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函数
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中
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建立连接的过程:
我们还可以得出如下对象的对应关系:
每一个Window对应WMS的一个WindowState,每一个WindowState对应一个SurfaceSession,每一个SurfaceSession对应一个SurfaceComposerClient,保存在其mNativeClient中,
每一个SurfaceComposerClient对应一个SurfaceFlinger进程的Client