1 前言
上一篇文章中我们已经创建了一个Native示例应用,从使用者的角度了解了图形显示系统API的基本使用,从这篇文章开始我们将基于这个示例应用深入图形显示系统API的内部实现逻辑,分析运作流程。
本篇将聚焦应用和SurfaceFlinger的活动,即应用是如何与SurfaceFlinger这个服务建立连接并进行通信的。让我们开始吧!
注:本篇涉及的代码位置:
/frameworks/native/libs/gui/
/frameworks/native/libs/gui/include/gui/
/frameworks/native/libs/gui/include/private/gui/
/frameworks/native/services/surfaceflinger/
2 应用和SurfaceFlinger的通信
应用运行一开始便首先要去创建一个Native Surface,此时即开始了与SurfaceFlinger的互动,分步来看创建Surface的过程:
- SurfaceFlinger系统服务的Binder RPC架构
在分析详细的代码前,我想先展示一下 SurfaceFlinger系统服务的Binder RPC架构,其中涉及哪些类?哪些接口?它们之间的关系如何?在宏观上去对这些对象的关系做了解,有助于我们理解具体的代码分析。
先看一张基本的类图:
SurfaceFlinger作为典型的Binder系统服务,遵循Binder服务设计的一般原则:
Interface接口:ISurfaceComposer 、ISurfaceComposerClient
Bp客户端:BpSurfaceComposer、BpSurfaceComposerClient
Bn服务端:BnSurfaceComposer、BnSurfaceComposerClient
服务实现:SurfaceFlinger、Client
具体Binder的原理在此就不展开讲了,相信你在网络上可以搜索到很多优秀的讲解文章。
这里请先留意两点:
- ComposerService中有成员mComposerService,它代表了SurfaceFlinger服务的代理客户端;
- SurfaceComposerClient中有成员mClient,它代表了SurfaceFlinger服务进程中的Client的代理客户端(这里应该是涉及所谓的匿名Binder的概念)
推荐两篇博文:https://blog.csdn.net/lewif/article/details/50696510
https://my.oschina.net/u/3897543/blog/4750360
- 创建SurfaceComposerClient并建立与SurfaceFlinger的连接
应用首先去创建SurfaceComposerClient对象,透过这个对象建立和SurfaceFlinger的连接并进行后续的互动:
sp surfaceComposerClient = new SurfaceComposerClient;
status_t err = surfaceComposerClient->initCheck();
if (err != NO_ERROR) {
ALOGD("SurfaceComposerClient::initCheck error: %#x\n", err);
return;
}
SurfaceComposerClient 的定义非常简单,继承RefBase,其中成员mClient持有远程服务的代理客户端,基本操作都是以它作为桥梁传递到SurfaceFlinger的,如下:
// /frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h
class SurfaceComposerClient : public RefBase
{
public:
SurfaceComposerClient();
SurfaceComposerClient(const sp& client);
virtual ~SurfaceComposerClient();
......
private:
sp mClient;
}
SurfaceComposerClient 的构造函数也十分简单,进行mStatus的初始化,其中mClient也可以外部传递进来初始值,或在onFirstRef的时候进行设置:
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT)
{
}
SurfaceComposerClient::SurfaceComposerClient(const sp& client)
: mStatus(NO_ERROR), mClient(client)
{
}
对象第一次引用onFirstRef的时候,才真正的去建立和SurfaceFlinger的连接:
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp conn;
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
先看一下ComposerService的定义,这是一个Singleton,它持有SurfaceFlinger服务的代理客户端:sp
// /frameworks/native/libs/gui/include/private/gui/ComposerService.h
// This holds our connection to the composer service (i.e. SurfaceFlinger).
class ComposerService : public Singleton
{
sp mComposerService; // composer service的代理端
sp mDeathObserver;
Mutex mLock;
ComposerService();
bool connectLocked();
void composerServiceDied();
friend class Singleton;
public:
// Get a connection to the Composer Service. This will block until
// a connection is established. Returns null if permission is denied.
static sp getComposerService();
};
ComposerService在构建时,调用connectLocked获取SurfaceFlinger(composer service)服务的代理客户端:
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
// ComposerService的构造函数,调用到connectLocked去创建和SurfaceFlinger的连接
ComposerService::ComposerService()
: Singleton() {
Mutex::Autolock _l(mLock);
connectLocked();
}
bool ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
mComposerService = waitForService(name); // 通过ServiceManager去获取SurfaceFlinger这个系统服务
if (mComposerService == nullptr) {
return false; // fatal error or permission problem
}
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService& mComposerService;
virtual void binderDied(const wp& who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get());
mComposerService.composerServiceDied();
}
public:
explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
};
mDeathObserver = new DeathObserver(*const_cast(this));
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
return true;
}
上面connectLocked方法可以看到调用waitForService去向ServiceManager请求名称为SurfaceFlinger的系统服务,成功后就取得了SurfaceFlinger这个系统服务的远程代理客户端,之后就可以透过这个代理跨进程与SurfaceFlinger进行互动了。
DeathObserver是一个监听器,用于监听远程服务的状态,当远程服务异常退出Died,触发该监听器,进而呼叫到mComposerService.composerServiceDied()做一些清理保护
void ComposerService::composerServiceDied()
{
Mutex::Autolock _l(mLock);
mComposerService = nullptr;
mDeathObserver = nullptr;
}
再回到SurfaceComposerClient::onFirstRef方法中,透过ComposerService::getComposerService()获取到SurfaceFlinger服务的代理客户端后,接下来就是去初始化mClient了
// /frameworks/native/libs/gui/SurfaceComposerClient.cpp
sp conn;
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
进而调用到了
// /frameworks/native/libs/gui/include/gui/ISurfaceComposer.h
/*
* Create a connection with SurfaceFlinger.
*/
virtual sp createConnection() = 0;
createConnection是一个典型的Binder C/S架构下的跨进程调用,傻瓜式的理解调用流程:
// 客户端端发送信息
BpSurfaceComposer::createConnection() {
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
return interface_cast(reply.readStrongBinder());
}
==>
// 服务端接收到信息
status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
status_t credentialCheck = CheckTransactCodeCredentials(code);
if (credentialCheck != OK) {
return credentialCheck;
}
status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
....
}
BnSurfaceComposer::onTransact() {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp b = IInterface::asBinder(createConnection());
reply->writeStrongBinder(b);
return NO_ERROR;
}
}
==>
// 服务具体实现
sp SurfaceFlinger::createConnection() {
const sp client = new Client(this);
return client->initCheck() == NO_ERROR ? client : nullptr;
}
SurfaceFlinger::createConnection方法中创建一个Client对象,Client继承自BnSurfaceComposerClient实现ISurfaceComposerClient接口,可以利用Binder机制传递回客户端。而且Client对象中含有SurfaceFlinger成员,这样SurfaceComposerClient::mClient就和SurfaceFlinger建立了连接。
Tips:
SurfaceFlinger进程中创建的Client对象,透过Binder IPC机制返回到了应用进程中,这里的具体原理感兴趣的可以研究下IInterface::asBinder / writeStrongBinder / readStrongBinder / interface_cast 这些方法。这里我们就傻瓜式的理解为SurfaceComposerClient::mClient是SurfaceFlinger进程中Client对象的代理客户端,使用SurfaceComposerClient::mClient就可以呼叫到SurfaceFlinger进程中Client对象的方法。
前面的讲解看起来纷纷扰扰,简单的、抽象的概括就是如下图所示:
- 创建SurfaceComposerClient对象;
- SurfaceComposerClient::onFirstRef方法中透过ComposerService::getComposerService()获取到SurfaceFlinger服务的代理客户端;
- 调用SurfaceFlinger服务的代理客户端的createConnection方法,进而跨进程调用到SurfaceFlinger::createConnection方法;
- SurfaceFlinger::createConnection方法中创建一个Client对象,并透过Binder返回给SurfaceComposerClient::mClient;
之后再调用SurfaceComposerClient中的方法时就可以通过mClient这个客户端去呼叫到SurfaceFlinger服务的功能了
结合上面的类图和下面的时序图,大概总结如下
3 小结
这一篇文章中讲解了应用进程中如何建立和SurfaceFlinger沟通的桥梁,即得到SurfaceFlinger的远程代理客户端,之后就通过这个代理客户端向SurfaceFlinger发送请求或获取信息。
必读:
Android 12(S) 图形显示系统 - 开篇