忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。
-- 服装学院的IT男
以前做应用开发的时候一直对 SurfaceFlinger 感觉到陌生,甚至有点“畏惧”,觉得这是自己“不配接触”和学不会的领域。
最近花了点时间开始接触这块,整理出几篇记录,个人对 SurfaceFlinger 分为3块:
-
- Surface 系统 这部分简单的梳理出 Surface 系统的成员类构建流程,和简单梳理工作模型
-
- VSysnc 相关 个人觉得这块也是 SurfaceFlinger 中很重要的概念
-
- SurfaceFlinger 合成 这部分就是最后的核心了,目前还没有能力写出来,后续补充
当前系列为第一部分 Surface 系统的学习记录,分为5篇,由于不是从事这块,所以是通过查阅资料,书籍,加日志,trace,debug 等方式学习,内容不是很深入,肯定会有很多细节没有提到,不过对于主流程和出现了的内容肯定能保证正确性。
也希望职业生涯中能整理出更加详细深入的 SurfaceFlinger 系列文章。
适合人群: SurfaceFlinger 小白,应用开发,想简单了解 SurfaceFlinger 的同学
Surface系统-1-应用与SurfaceFlinger建立链接
Surface系统-2-SurfaceControl的创建(java层)
Surface系统-3-SurfaceControl的创建(native层)
Surface系统-4-BLASTBufferQueue和Surface的创建
Surface系统-5-BLASTBufferQueue工作流程概览
本篇同时已收录于Activity短暂的一生系列
正文
本篇介绍应用端是如何 SurfaceFlinger 建立链接,进行通信。 它们直接使用 SurfaceSession 通信,SurfaceSession 的创建时机发生在应用第一个窗口显示(addWindow流程)流程。
1 java 层 SurfaceSession 的创建
APP 端触发 addWindow 流程是通过匿名 Binder -> Session 这个类与 WindowManagerService 通信的。 在 WindowManagerService::addWindow 方法会先创建 WindowState 对象,此时也会将 Session 作为参数传递。 然后又会执行 执行 WindowState::attach 方法,这里会触发 SurfaceSession 的创建逻辑。 代码如下:
# WindowState
// 客户端的 Session
final Session mSession;
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState parentWindow, int appOp, WindowManager.LayoutParams a, int viewVisibility,
int ownerId, int showUserId, boolean ownerCanAddInternalSystemWindow,
PowerManagerWrapper powerManagerWrapper) {
super(service);
mTmpTransaction = service.mTransactionFactory.get();
// session 赋值
mSession = s;
......
}
// 在 WMS 的addWindow 方法中马上会调用 WindowState::attach
void attach() {
......
if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
mSession.windowAddedLocked();
}
继续看 Session::windowAddedLocked
# Session
// 应用端和 SurfaceFlinger 通信的 Session
SurfaceSession mSurfaceSession;
void windowAddedLocked() {
......
if (mSurfaceSession == null) {
if (DEBUG) {
Slog.v(TAG_WM, "First window added to " + this + ", creating SurfaceSession");
}
// 应用第一次添加窗口,需要创建 SurfaceSession
mSurfaceSession = new SurfaceSession();
}
mNumWindow++;
}
应用端和 WMS 通信是通过 Session ,现在看到 Session 下持有着一个与 SurfaceFlinger 通信的 SurfaceSession 对象。
# SurfaceSession
// native的指针
private long mNativeClient; // SurfaceComposerClient*
/** Create a new connection with the surface flinger. */
public final class SurfaceSession {
mNativeClient = nativeCreate();
}
java 层的 SurfaceSession 非常简单,构造方法也是触发 native 的创建,上层只保存对应的指针即可。 这里发现 google 加了个注释,表示对应 native 层的是一个 SurfaceComposerClient。
所以上层的 SurfaceSession 本质就是一个底层的 SurfaceComposerClient 。
对应的 JNI 为 android_view_SurfaceSession.cpp
# android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
// 创建SurfaceComposerClient
SurfaceComposerClient* client = new SurfaceComposerClient();
// 增加对象的引用计数,防止在JNI方法执行结束后被释放
client->incStrong((void*)nativeCreate);
// 将SurfaceComposerClient对象的地址转换为jlong类型,并返回
return reinterpret_cast<jlong>(client);
}
2. native 层 SurfaceComposerClient 的创建
# SurfaceComposerClient.h
class SurfaceComposerClient : public RefBase
{
friend class Composer;
public:
......
protected:
int mStatus = NO_ERROR;
......
private:
......
virtual void onFirstRef();
mutable Mutex mLock;
// 状态
status_t mStatus;
// 对应的 ISurfaceComposerClient
sp<ISurfaceComposerClient> mClient;
}
# SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT) {}
-
- SurfaceComposerClient 是 RefBase 子类
-
- 创建 SurfaceComposerClient 时设置了状态为:NO_INIT
-
- mClient 变量其实就是 SurfaceFlinger 的一个 BP 端
这里可以画出 SurfaceComposerClient 的类图:
因为 SurfaceComposerClient 是 RefBase 子类所以在对象构建的时候会触发 onFirstRef() 方法。
# SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
// 1. 拿到 SurfaceComposerAIDL 服务
sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
// 创建对象
sp<ISurfaceComposerClient> conn;
// 2. 创建对应 BP 代理
binder::Status status = sf->createConnection(&conn);
if (status.isOk() && conn != nullptr) {
// 设置给当前变量
mClient = conn;
// 修改状态
mStatus = NO_ERROR;
}
}
}
这里分为2步:
-
- 拿到 SurfaceComposerAIDL 服务
-
- 创建 Clinet 赋值给 mClient
2.1 拿到 SurfaceComposerAIDL 服务
先看看 ComposerServiceAIDL 是什么
# ComposerServiceAIDL.h
// 静态类
class ComposerServiceAIDL : public Singleton<ComposerServiceAIDL> {
// 保存SurfaceFlinger服务
sp<gui::ISurfaceComposer> mComposerService;
......
ComposerServiceAIDL();
// 获取SurfaceFlinger服务
bool connectLocked();
......
public:
// Get a connection to the Composer Service. This will block until
// a connection is established. Returns null if permission is denied.
// 返回SurfaceFlinger服务
static sp<gui::ISurfaceComposer> getComposerService();
};
-
- ComposerServiceAIDL 是个单例类
-
- 定义了 mComposerService 保存 ISurfaceComposer
-
- 定义了 getComposerService 和 connectLocked 两个方法
ComposerServiceAIDL::getComposerService 方法定义如下
# SurfaceComposerClient.cpp
/*static*/ sp<gui::ISurfaceComposer> ComposerServiceAIDL::getComposerService() {
// 获取单例
ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
std::scoped_lock lock(instance.mMutex);
// 如果对应的变量为空则执行 connectLocked 方法赋值
if (instance.mComposerService == nullptr) {
// 获取 binder 服务
if (ComposerServiceAIDL::getInstance().connectLocked()) {
ALOGD("ComposerServiceAIDL reconnected");
WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
}
}
// 返回
return instance.mComposerService;
}
也就是说执行 ComposerServiceAIDL::getComposerService 目的就是返回其成员变量 mComposerService ,如果值为空就执行 ComposerServiceAIDL::connectLocked 进行赋值再返回。
那么需要看看 ComposerServiceAIDL::connectLocked 做了什么。
# SurfaceComposerClient.cpp
bool ComposerServiceAIDL::connectLocked() {
const String16 name("SurfaceFlingerAIDL");
// 拿到 SurfaceFlingerAIDL
mComposerService = waitForService<gui::ISurfaceComposer>(name);
if (mComposerService == nullptr) {
return false; // fatal error or permission problem
}
......
return true;
}
之前的获取的是服务是 "SurfaceFlinger" 新版本现在是 "SurfaceFlingerAIDL" 。 在 SurfaceFlinger 初始化的时候,这2个服务现在都是注册了的,注册的代码在 main_surfaceflinger.cpp 的 main 方法中执行。
现在单例类 ComposerServiceAIDL 下的 mComposerService 的值就是 SurfaceFlingerAIDL 服务了。
2.2 创建 Clinet
# SurfaceFlinger.cpp
binder::Status SurfaceComposerAIDL::createConnection(sp<gui::ISurfaceComposerClient>* outClient) {
// * 创建 Client
const sp<Client> client = sp<Client>::make(mFlinger);
if (client->initCheck() == NO_ERROR) {
// 出参赋值
*outClient = client;
return binder::Status::ok();
} else {
*outClient = nullptr;
return binderStatusFromStatusT(BAD_VALUE);
}
}
做了一件事:创建匿名 Binder (Client) 返回给出参。 而且可以看到创建 Client 传递了 SurfaceFlinger 本身,那也就是说这个 Client 会持有真正是 SurfaceFlinger 。
这个 Client 是 ISurfaceComposerClient 的子类,具体代码如下:
# Client.h
class Client : public gui::BnSurfaceComposerClient {
public:
explicit Client(const sp<SurfaceFlinger>& flinger);
......
private:
......
// constant
sp<SurfaceFlinger> mFlinger;
}
// 对应实现
# Client.cpp
Client::Client(const sp<SurfaceFlinger>& flinger)
: mFlinger(flinger)
{......}
可知Client 是个 BN 服务,通过变量 mFlinger 持有 SurfaceFlinger
-Client 继承于 BnSurfaceComposerClient ,这种 Bn 开头的肯定是 Binder 本地端了,其父类是 ISurfaceComposerClient 如下:
# ISurfaceComposerClient.h
class BnSurfaceComposerClient : public SafeBnInterface<ISurfaceComposerClient> {
......
};
这里可以画出Client的类图:
所以可以确定这里创建的 Client 就是 SurfaceFlinger 的本地代理,也就是执行 SurfaceComposerAIDL::createConnection 方法是为了创建获取一个 SurfaceFlinger 的本地代理,用于后续应用端与 SurfaceFlinger 进行通信。而这个 Client 最终被赋值给 SurfaceComposerClient 的成员变量 mClient 。
3 小结
完整的调用链如下:
WindowManagerService::addWindow
WindowState::init
WindowState::attach
Session::windowAddedLocked
SurfaceSession::init
SurfaceSession::nativeCreate -- 进入native层
SurfaceComposerClient::init -- android_view_SurfaceSession.cpp
SurfaceComposerClient::onFirstRef
ComposerServiceAIDL::getComposerService -- 拿到 SurfaceComposerAIDL 服务
ComposerServiceAIDL::connectLocked
SurfaceComposerAIDL::createConnection -- 创建 Client
Client::init -- 传递 SF
客户端通过 SurfaceSession 来与 SurfaceFlinger 通信,只保留 SurfaceFlinger 的类图关系如下:
上层的 SurfaceSession 通过指针对应 native 层的 SurfaceComposerClient 间接持有 SurfaceFlinger 。
看到一篇博客绘制的完整类图如下: