Android图形框架之SurfaceComposerClient初始化过程分析

21 阅读3分钟

0 引言

在 Android 图形系统中,Native App 通过Binder 与 SurfaceFlinger 实现通信,完成图形数据的交互和显示。本文将分析一段 Native 代码及其内部源码,来讨论其与 SurfaceFlinger 通信的建立过程。

以下代码是一个 Native App 初始化 SurfaceComposerClient 并检查其状态的例子:

sp<SurfaceComposerClient> surfaceComposerClient = new SurfaceComposerClient;
status_t err = surfaceComposerClient->initCheck();
if (err != OK) {
    ALOGD("SurfaceComposerClient::initCheck error: %#x\n", err);
    return -1;
}

我们知道,SurfaceComposerClient 的初始化过程实际上是其与 SurfaceFlinger 之间通过 Binder 机制建立通信的关键环节。下面就进入源码中,详细分析它的初始化过程。

1 SurfaceComposerClient构造函数分析

new SurfaceComposerClient的过程中会调用SurfaceComposerClient类的构造函数:

SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT) {}

从构造函数看好像没有做任何工作,但实际上由于SurfaceComposerClient的基类是RefBase,所以在第一次使用智能指针引用它的过程中会调用onFirstRef函数:

void SurfaceComposerClient::onFirstRef() {
    sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        binder::Status status = sf->createConnection(&conn);
        if (status.isOk() && conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

这个函数主要做了两个工作:

  1. 获取SurfaceComposerAIDL服务,对应代码:ComposerServiceAIDL::getComposerService()
  2. 调用SurfaceComposerAIDL服务的createConnection方法与conn建立连接。

2 获取SurfaceComposerAIDL服务

getComposerService()函数是ComposerServiceAIDL类的,它是个单例类,其内部持有SurfaceFlinger的SurfaceFlingerAIDL服务(该服务名称为SurfaceFlingerAIDL,本质是SurfaceComposerAIDL服务)。下面是getComposerService函数的代码:

/*static*/ sp<gui::ISurfaceComposer> ComposerServiceAIDL::getComposerService() {
    ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
    std::scoped_lock lock(instance.mMutex);
    if (instance.mComposerService == nullptr) {
        if (ComposerServiceAIDL::getInstance().connectLocked()) {
            ALOGD("ComposerServiceAIDL reconnected");
            WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
        }
    }
    return instance.mComposerService;
}

可以看到该函数调用了ComposerServiceAIDL类的connectLocked函数:

bool ComposerServiceAIDL::connectLocked() {
    // 获取SurfaceFlingerAIDL服务
    const String16 name("SurfaceFlingerAIDL");
    mComposerService = waitForService<gui::ISurfaceComposer>(name);
    if (mComposerService == nullptr) {
        return false; // fatal error or permission problem
    }

    // 创建Binder死亡监听器并建立连接
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerServiceAIDL& mComposerService;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("ComposerService aidl remote (surfaceflinger) died [%p]", who.unsafe_get());
            mComposerService.composerServiceDied();
        }

    public:
        explicit DeathObserver(ComposerServiceAIDL& mgr) : mComposerService(mgr) {}
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerServiceAIDL*>(this));
    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
    return true;
}

connectLocked() 的核心作用是:

  1. 获取 SurfaceFlingerAIDL 服务的代理对象,确保客户端可以通过 AIDL 与 SurfaceFlinger 通信。
  2. 通过死亡监听机制监控服务端的生命周期,确保服务端异常退出时能够及时处理。

3 调用createConnection方法

getComposerService()函数分析完了,继续分析SurfaceComposerAIDL服务的createConnection方法(SurfaceFlinger.cpp):

binder::Status SurfaceComposerAIDL::createConnection(sp<gui::ISurfaceComposerClient>* outClient) {
    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);
    }
}

函数 SurfaceComposerAIDL::createConnection 的主要作用是创建一个 ISurfaceComposerClient类 的具体实现对象Client,它负责管理客户端和 SurfaceFlinger 的交互。

分析到这里,我们可以知道:SurfaceComposerClient的初始化过程实际上是通过单例类ComposerServiceAIDL获取到SurfaceFlinger的SurfaceComposerAIDL服务,通过调用该服务的createConnection方法来创建一个用于交互的Client对象。

4 总结

根据上面对源码的分析,我们可以得到如下的UML图:

image.png

以及Native App与SurfaceFlinger进程的通信初始化示意图:

image.png

5 参考资料

  1. Android14 显示系统剖析3 ———— Native App 与 SurfaceFinger 建立 Binder 通信过程分析