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

5/30/2024

本文基于 aosp android-14.0.0_r15 版本讲解。

上节给出了,与 SurfaceFlinger 交互的 Native App 示例程序。本节主要分析示例程序中 Native App 与 SurfaceFinger 建立 Binder 通信的过程。

# 1. 先搂一眼 SurfaceFlinger

我们的 Native App 需要和 SurfaceFlinger 建立 Binder 通信,在分析代码之前,我们先了解一下 SurfaceFlinger 的实现。

当系统 init 进程启动之后,会开始解析 system/core/rootdir/init.rc 文件,在 init.rc 文件中,申明了启动 core 的一系列服务:

...
on boot
...
    class_start core
...
1
2
3
4
5

其中包含了 surfaceflinger 服务(进程)。其信息定义在 frameworks/native/services/surfaceflinger/surfaceflinger.rc:

service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    capabilities SYS_NICE
    onrestart restart --only-if-running zygote
    task_profiles HighPerformance
    socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
    socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
    socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
1
2
3
4
5
6
7
8
9
10

通过 surfaceflinger.rc 文件我们可以知道 surfaceflinger 进程对应的可执行文件是 /system/bin/surfaceflinger

通过搜索 Android.bp 文件可以找到 /system/bin/surfaceflinger 对应的源码是 frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp 中的 main 函数:

// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {

    // 注册 SIGPIPE 信号的处理函数
    signal(SIGPIPE, SIG_IGN);

    // binder 线程初始化
    hardware::configureRpcThreadpool(1 /* maxThreads */,
            false /* callerWillJoin */);

    // 启动 Graphics Allocator Hal 服务
    startGraphicsAllocatorService();

    //设置 Binder 线程最多为 4
    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    ProcessState::self()->setThreadPoolMaxThreadCount(4);


    // 设置线程优先级
    // 有兴趣的同学可以看看 https://paul.pub/android-process-schedule/
    // Set uclamp.min setting on all threads, maybe an overkill but we want
    // to cover important threads like RenderEngine.
    if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {
        ALOGW("Failed to set uclamp.min during boot: %s", strerror(errno));
    }


    // 设置 binder 线程池的优先级
    // The binder threadpool we start will inherit sched policy and priority
    // of (this) creating thread. We want the binder thread pool to have
    // SCHED_FIFO policy and priority 1 (lowest RT priority)
    // Once the pool is created we reset this thread's priority back to
    // original.
    int newPriority = 0;
    int origPolicy = sched_getscheduler(0);
    struct sched_param origSchedParam;

    int errorInPriorityModification = sched_getparam(0, &origSchedParam);
    if (errorInPriorityModification == 0) {
        int policy = SCHED_FIFO;
        newPriority = sched_get_priority_min(policy);

        struct sched_param param;
        param.sched_priority = newPriority;

        errorInPriorityModification = sched_setscheduler(0, policy, &param);
    }

    // 关注点 1 
    // 初始化驱动,启动 Binder 线程池
    // start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();

    // Reset current thread's policy and priority
    if (errorInPriorityModification == 0) {
        errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
    } else {
        ALOGE("Failed to set SurfaceFlinger binder threadpool priority to SCHED_FIFO");
    }

    // 关注点 2
    // 初始化一个 SurfaceFlinger 对象
    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();

    // Set the minimum policy of surfaceflinger node to be SCHED_FIFO.
    // So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run
    // at least with SCHED_FIFO policy and priority 1.
    if (errorInPriorityModification == 0) {
        flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);
    }
    
    // 设置进程为高优先级以及前台调度策略
    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

    set_sched_policy(0, SP_FOREGROUND);


    // 关注点 3
    // SurfaceFlinger 初始化
    // initialize before clients can connect
    flinger->init();

    
    // 关注点 4
    // 发布 Binder 服务
    // publish surface flinger

    // 注册了一个叫 SurfaceFlinger 的 binder 服务
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);


    // 注册了一个叫 SurfaceFlingerAIDL 的 binder 服务
    // publish gui::ISurfaceComposer, the new AIDL interface
    sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger);
    sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    // 关注点5
    // 启动 DisplayService 服务 https://www.jianshu.com/p/fa115146949f
    startDisplayService(); // dependency on SF getting registered above

    // 进程调度模式设置为实时进程的FIFO
    if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
        ALOGW("Failed to set SCHED_FIFO during boot: %s", strerror(errno));
    }
    
    // 关注点 6
    // 启动 SurfaceFlinger,进入无限循环
    // run surface flinger in this thread
    flinger->run();

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

代码中做了较为详细的注释,我们主要分析标注了关注点的 6 个地方.

# 1.1 关注点 1,初始化 Binder 驱动

    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();
1
2
  • ProcessState::self() 初始化 Binder 驱动,
  • ps->startThreadPool() 开启线程池

这部分内容我们在Binder 服务注册过程情景分析之 C++ 篇 (opens new window) 已经做过详细分析了,这里就不再重复了。

# 1.2 关注点 2,初始化 SurfaceFlinger 对象

    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
1

createSurfaceFlinger 函数的实现如下:

// /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp
sp<SurfaceFlinger> createSurfaceFlinger() {
    static DefaultFactory factory;

    return sp<SurfaceFlinger>::make(factory);
}
1
2
3
4
5
6

这里通过工厂模式去 new 了一个 SurfaceFlinger 对象。

SurfaceFlinger 类的定义如下:

class SurfaceFlinger : public BnSurfaceComposer,
                       public PriorityDumper,
                       private IBinder::DeathRecipient,
                       private HWC2::ComposerCallback,
                       private ICompositor,
                       private scheduler::ISchedulerCallback {
                        

                        // ......
}
1
2
3
4
5
6
7
8
9
10

SurfaceFlinger 相关类类图如下:

20240630153256

目前我们主要关注两个父类 ISurfaceComposer 和 ComposerCallback:

  • ISurfaceComposer 是一个接口,定义了 SurfaceFlinger 作为一个 Binder 服务对外提供的服务
  • ComposerCallback 是 HWC 模块的回调,这个包含了三个很关键的回调函数,
    • onComposerHotplug 函数表示显示屏热插拔事件
    • onComposerHalRefresh 函数表示 Refresh 事件
    • onComposerHalVsync 表示 Vsync 信号事件。

# 1.3 关注点3, init SurfaceFlinger

    flinger->init();
1

这里调用 init 函数初始化 SurfaceFlinger,具体实现如下:

std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;

// /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");
    addTransactionReadyFilters();
    Mutex::Autolock lock(mStateLock);
    // 构建 RenderEngine,用于 Client 合成
    // Get a RenderEngine for the given display / config (can't fail)
    // TODO(b/77156734): We need to stop casting and use HAL types when possible.
    // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
    auto builder = renderengine::RenderEngineCreationArgs::Builder()
                           .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
                           .setImageCacheSize(maxFrameBufferAcquiredBuffers)
                           .setUseColorManagerment(useColorManagement)
                           .setEnableProtectedContext(enable_protected_contents(false))
                           .setPrecacheToneMapperShaderOnly(false)
                           .setSupportsBackgroundBlur(mSupportsBlur)
                           .setContextPriority(
                                   useContextPriority
                                           ? renderengine::RenderEngine::ContextPriority::REALTIME
                                           : renderengine::RenderEngine::ContextPriority::MEDIUM);
    if (auto type = chooseRenderEngineTypeViaSysProp()) {
        builder.setRenderEngineType(type.value());
    }
    mRenderEngine = renderengine::RenderEngine::create(builder.build());
    mCompositionEngine->setRenderEngine(mRenderEngine.get());
    mMaxRenderTargetSize =
            std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());

    // Set SF main policy after initializing RenderEngine which has its own policy.
    if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
        ALOGW("Failed to set main task profile");
    }

    mCompositionEngine->setTimeStats(mTimeStats);
    mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
    mCompositionEngine->getHwComposer().setCallback(*this);
    ClientCache::getInstance().setRenderEngine(&getRenderEngine());

    enableLatchUnsignaledConfig = getLatchUnsignaledConfig();

    if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
        enableHalVirtualDisplays(true);
    }

    // Process hotplug for displays connected at boot.
    LOG_ALWAYS_FATAL_IF(!configureLocked(),
                        "Initial display configuration failed: HWC did not hotplug");

    // Commit primary display.
    sp<const DisplayDevice> display;
    if (const auto indexOpt = mCurrentState.getDisplayIndex(getPrimaryDisplayIdLocked())) {
        const auto& displays = mCurrentState.displays;

        const auto& token = displays.keyAt(*indexOpt);
        const auto& state = displays.valueAt(*indexOpt);

        processDisplayAdded(token, state);
        mDrawingState.displays.add(token, state);

        display = getDefaultDisplayDeviceLocked();
    }

    LOG_ALWAYS_FATAL_IF(!display, "Failed to configure the primary display");
    LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(display->getPhysicalId()),
                        "Primary display is disconnected");

    // TODO(b/241285876): The Scheduler needlessly depends on creating the CompositionEngine part of
    // the DisplayDevice, hence the above commit of the primary display. Remove that special case by
    // initializing the Scheduler after configureLocked, once decoupled from DisplayDevice.
    initScheduler(display);
    dispatchDisplayHotplugEvent(display->getPhysicalId(), true);

    // Commit secondary display(s).
    processDisplayChangesLocked();

    // initialize our drawing state
    mDrawingState = mCurrentState;

    onActiveDisplayChangedLocked(nullptr, *display);

    static_cast<void>(mScheduler->schedule(
            [this]() FTL_FAKE_GUARD(kMainThreadContext) { initializeDisplays(); }));

    mPowerAdvisor->init();

    char primeShaderCache[PROPERTY_VALUE_MAX];
    property_get("service.sf.prime_shader_cache", primeShaderCache, "1");
    if (atoi(primeShaderCache)) {
        if (setSchedFifo(false) != NO_ERROR) {
            ALOGW("Can't set SCHED_OTHER for primeCache");
        }

        mRenderEnginePrimeCacheFuture = getRenderEngine().primeCache();

        if (setSchedFifo(true) != NO_ERROR) {
            ALOGW("Can't set SCHED_OTHER for primeCache");
        }
    }

    // Inform native graphics APIs whether the present timestamp is supported:

    const bool presentFenceReliable =
            !getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
    mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);

    if (mStartPropertySetThread->Start() != NO_ERROR) {
        ALOGE("Run StartPropertySetThread failed!");
    }

    ALOGV("Done initializing");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

在 init 函数中,使用到了一个 mCompositionEngine 成员,它在 SurfaceFlinger 的构造函数中初始化:

// /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
      : mFactory(factory),
        // ......
        mCompositionEngine(mFactory.createCompositionEngine()), // 这里
        // ......
        mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()) {
    ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
}
1
2
3
4
5
6
7
8
9

CompositionEngine 的定义如下:

// /frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
class CompositionEngine : public compositionengine::CompositionEngine {
public:
    
    // ......

private:
    std::unique_ptr<HWComposer> mHwComposer;
    renderengine::RenderEngine* mRenderEngine;
    std::shared_ptr<TimeStats> mTimeStats;
    bool mNeedsAnotherUpdate = false;
    nsecs_t mRefreshStartTime = 0;
};
1
2
3
4
5
6
7
8
9
10
11
12
13

CompositionEngine 持有了 HWComposer 和 RenderEngine 两个重要成员,类图如下所示:

20240630161856

HWComposer 一方面向 SurfaceFlinger 提供硬件 Vsync 信号,另一方面用于 Device 合成 Layer 图层,也就是硬件合成。

RenderEngine 主要用于 Client 合成 Layer 图层,也就是软件合成。

CompositionEngine 主要充当了 SurfaceFlinger 与 RenderEngine & HWComposer 之间的桥梁。

接着我们回到 init 函数中:

RenderEngine::create 构建了一个 RenderEngine 对象。

getFactory().createHWComposer(mHwcServiceName) 构建一个 HWComposer 对象,并通过 mCompositionEngine->getHwComposer().setCallback(*this); 将当前 SurfaceFlinger 对象设置为 HWComposer 的回调。

主要关注以下三个回调函数:

struct ComposerCallback {
    // 热插拔
    virtual void onComposerHalHotplug(hal::HWDisplayId, hal::Connection) = 0;
    // 刷新
    virtual void onComposerHalRefresh(hal::HWDisplayId) = 0;
    // 硬件 Vysnc 信号
    virtual void onComposerHalVsync(hal::HWDisplayId, nsecs_t timestamp,
                                    std::optional<hal::VsyncPeriodNanos>) = 0;
    //......
}
1
2
3
4
5
6
7
8
9
10

initScheduler 主要是进行 Vysnc 处理相关类的初始化,这个会在 Vysnc 章节来做分析。

# 1.4 关注点4,注册 Binder 服务

    // .....
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
    
    // ......
    // publish gui::ISurfaceComposer, the new AIDL interface
    sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger);
    // 注册了一个叫 SurfaceFlingerAIDL 的 binder 服务
    sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO); 
    
    // ......
1
2
3
4
5
6
7
8
9
10
11
12
13

关注点 4 处在主函数中注册了 SurfaceFlinger 和 SurfaceComposerAIDL 两个 Binder 服务。

20240528223713

SurfaceFlinger Binder 服务相关类的关系如下图所示:

20240528223801

SurfaceFlinger Binder 服务对应的接口类是 ISurfaceComposer:

class ISurfaceComposer: public IInterface {
public:
    DECLARE_META_INTERFACE(SurfaceComposer)

    // flags for setTransactionState()
    enum {
        eAnimation = 0x02,

        // Explicit indication that this transaction and others to follow will likely result in a
        // lot of layers being composed, and thus, SurfaceFlinger should wake-up earlier to avoid
        // missing frame deadlines. In this case SurfaceFlinger will wake up at
        // (sf vsync offset - debug.sf.early_phase_offset_ns). SurfaceFlinger will continue to be
        // in the early configuration until it receives eEarlyWakeupEnd. These flags are
        // expected to be used by WindowManager only and are guarded by
        // android.permission.WAKEUP_SURFACE_FLINGER
        eEarlyWakeupStart = 0x08,
        eEarlyWakeupEnd = 0x10,
        eOneWay = 0x20
    };

    /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
    virtual status_t setTransactionState(
            const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state,
            const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
            InputWindowCommands inputWindowCommands, int64_t desiredPresentTime,
            bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffer,
            bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
            uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) = 0;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

这里只有一个函数 setTransactionState,应该不是 SurfaceFlinger 对外提供服务的主战场。

我们接着看 SurfaceComposerAIDL Binder 服务,其相关类关系如下图所示:

20240528223944

从名字就可以看出,SurfaceComposerAIDL 是通过 aidl 辅助实现的 binder 服务。

对应的 aidl 文件是:

// /frameworks/native/libs/gui/aidl/android/gui/ISurfaceComposer.aidl

package android.gui;

// ......

/** @hide */
interface ISurfaceComposer {

    enum VsyncSource {
        eVsyncSourceApp = 0,
        eVsyncSourceSurfaceFlinger = 1
    }

    enum EventRegistration {
        modeChanged = 1 << 0,
        frameRateOverride = 1 << 1,
    }

    void bootFinished();

    @nullable IDisplayEventConnection createDisplayEventConnection(VsyncSource vsyncSource,
            EventRegistration eventRegistration, @nullable IBinder layerHandle);

    @nullable ISurfaceComposerClient createConnection();

    @nullable IBinder createDisplay(@utf8InCpp String displayName, boolean secure,
            float requestedRefreshRate);

    void destroyDisplay(IBinder display);

    long[] getPhysicalDisplayIds();

    @nullable IBinder getPhysicalDisplayToken(long displayId);

    FrameEvent[] getSupportedFrameTimestamps();

    void setPowerMode(IBinder display, int mode);

    DisplayStatInfo getDisplayStats(@nullable IBinder display);

    //......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

aidl 文件中定义了大量的函数,这里只贴出了部分。

ISurfaceComposer.aidl 文件主要生成了以下的类:

  • gui::ISurfaceComposer:描述 binder 服务的接口
  • gui::BnSurfaceComposer:binder 服务端对象
  • gui::BpSurfaceComposer:binder 代理端对象

该服务提供了大量的函数供客户端调用。

# 1.5 关注点5,启动显示服务

startDisplayService();
1

对应的实现是:

static void startDisplayService() {
    using android::frameworks::displayservice::V1_0::implementation::DisplayService;
    using android::frameworks::displayservice::V1_0::IDisplayService;

    sp<IDisplayService> displayservice = sp<DisplayService>::make();
    status_t err = displayservice->registerAsService();

    // b/141930622
    if (err != OK) {
        ALOGE("Did not register (deprecated) IDisplayService service.");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

这里会注册一个显示服务,Framework 层很少会接触到 DisplayService,DisplayService 实际是一个 hidl hal,定义在 frameworks/native/services/displayservice 目录下,其主要作用是向其他 Vendor 模块提供显示器的 hotplug 事件 和 Vsync 信号。

我们可以从 hal 文件从看一下 DisplayService 对外提供的接口:

package android.frameworks.displayservice@1.0;

import IEventCallback;

interface IDisplayEventReceiver {
    /**
     * 添加callback,开始接收Events事件,热插拔是默认打开的,Vysnc需要通过setVsyncRate打开
     */
    init(IEventCallback callback) generates (Status status);

    /**
     * 开始或停止发送callback
     */
    setVsyncRate(int32_t count) generates (Status status);

    /**
     * 请求一个Vsync,如果setVsyncRate是0,这不起作用
     */
    requestNextVsync() generates (Status status);

    /**
     * Server端丢弃所以的callback,停止发送
     */
    close() generates (Status status);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

调用 init 的时候会传入一个 IEventCallback callback 回调:

package android.frameworks.displayservice@1.0;

interface IEventCallback {
    /**
     * Vsync事件
     */
    oneway onVsync(uint64_t timestamp, uint32_t count);

    /**
     * hotplug事件
     */
    oneway onHotplug(uint64_t timestamp, bool connected);
};
1
2
3
4
5
6
7
8
9
10
11
12
13

当有显示器热插拔事件的时候就会回调 onHotplug 函数

调用 requestNextVsync 函数后,下一个 Vysnc 信号到来的时候就会回调到 onVsync 函数。

# 1.6 关注点6,进入无限循环

flinger->run()
1

run 函数的实现如下:

std::unique_ptr<scheduler::Scheduler> mScheduler;

void SurfaceFlinger::run() {
    mScheduler->run();
}
1
2
3
4
5
// /frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h
class Scheduler : android::impl::MessageQueue {
    //.......
}

// /frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
void Scheduler::run() {
    while (true) {
        waitMessage();
    }
}

// /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
void MessageQueue::waitMessage() {
    do {
        IPCThreadState::self()->flushCommands();
        int32_t ret = mLooper->pollOnce(-1);
        switch (ret) {
            case Looper::POLL_WAKE:
            case Looper::POLL_CALLBACK:
                continue;
            case Looper::POLL_ERROR:
                ALOGE("Looper::POLL_ERROR");
                continue;
            case Looper::POLL_TIMEOUT:
                // timeout (should not happen)
                continue;
            default:
                // should not happen
                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
                continue;
        }
    } while (true);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

这里的 MessageQueue 对 Looper 进行了简单的包装,实际这里就是一个 Native Looper。

# 2. App 与 SurfaceFlinger 之间的 Binder 通信通道建立

在了解了 SurfaceFlinger 后,我们就可以开始分析上一节的示例代码了。

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

    // ......
}
1
2
3
4
5
6
7
8
9
10

我们 new 一个 SurfaceComposerClient 对象,SurfaceComposerClient 是 App 与 SurfaceFlinger 通信的辅助类,其构造函数如下:

// frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT) {}
1
2

构造函数,除了给 mStatus 成员初始化一个值,就没了。

SurfaceComposerClient 中还定义了 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
2
3
4
5
6
7
8
9
10
11

onFirstRef 函数会先调用到 ComposerServiceAIDL::getComposerService():

// frameworks/native/libs/gui/include/private/gui/ComposerServiceAIDL.h  
class ComposerServiceAIDL : public Singleton<ComposerServiceAIDL> {

    sp<gui::ISurfaceComposer> mComposerService;
    sp<IBinder::DeathRecipient> mDeathObserver;
    mutable std::mutex mMutex;

    ComposerServiceAIDL();
    bool connectLocked();
    void composerServiceDied();
    friend class Singleton<ComposerServiceAIDL>;

public:
    // Get a connection to the Composer Service.  This will block until
    // a connection is established. Returns null if permission is denied.
    static sp<gui::ISurfaceComposer> getComposerService();
};

// /frameworks/native/libs/gui/SurfaceComposerClient.cpp

/*static*/ sp<gui::ISurfaceComposer> ComposerServiceAIDL::getComposerService() {
    // 获取单例对象
    ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
    std::scoped_lock lock(instance.mMutex);
    if (instance.mComposerService == nullptr) {
        // 调用 connectLocked 获取 binder 服务
        if (ComposerServiceAIDL::getInstance().connectLocked()) {
            ALOGD("ComposerServiceAIDL reconnected");
            WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
        }
    }
    return instance.mComposerService;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

getComposerService 函数中会去获取到 ComposerServiceAIDL 单例对象,然后调用 ComposerServiceAIDL 单例对象的 connectLocked 方法去获取 SurfaceFlingerAIDL binder 服务:

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

    // Create the death listener.
    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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

connectLocked 获取到名为 SurfaceFlingerAIDL 的 binder 服务代理端 sp<gui::ISurfaceComposer> mComposerService,这个和上一节的分析相吻合。

接着通过这个代理端对象远程调用 createConnection 函数,获取到 sp<ISurfaceComposerClient> conn 匿名 Binder 服务。

找到 SurfaceFlingerAIDL 服务端 createConnection 函数的实现:

// /frameworks/native/services/surfaceflinger/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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

new 一个 Client 然后通过参数返回

那这个 Client 又是啥呢?找到 Client 的实现:

// /frameworks/native/services/surfaceflinger/Client.h

class Client : public gui::BnSurfaceComposerClient {
public:
    explicit Client(const sp<SurfaceFlinger>& flinger);
    ~Client() = default;

    status_t initCheck() const;

private:
    // ISurfaceComposerClient interface

    binder::Status createSurface(const std::string& name, int32_t flags, const sp<IBinder>& parent,
                                 const gui::LayerMetadata& metadata,
                                 gui::CreateSurfaceResult* outResult) override;

    binder::Status clearLayerFrameStats(const sp<IBinder>& handle) override;

    binder::Status getLayerFrameStats(const sp<IBinder>& handle,
                                      gui::FrameStats* outStats) override;

    binder::Status mirrorSurface(const sp<IBinder>& mirrorFromHandle,
                                 gui::CreateSurfaceResult* outResult) override;

    binder::Status mirrorDisplay(int64_t displayId, gui::CreateSurfaceResult* outResult) override;

    // constant
    sp<SurfaceFlinger> mFlinger;

    // thread-safe
    mutable Mutex mLock;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Client 是一个 binder 服务端类,内部持有一个 SurfaceFlinger 的指针,指针的值通过构造函数传入。

该匿名 Binder 服务相关类的关系如图所示:

20240609172340

可以看出,Client 实际就是一个匿名 Binder 服务。

每个 App 都会有一个匿名 Binder 代理端对象,SF 中有对应的 Client Binder 服务端类与之对应:

20240701160320

# 总结

  • SurfaceFlinger 进程中提供了 SurfaceFlinger Binder 服务,SurfaceFlingerAIDL Binder 服务和一个名为 Client 的匿名 Binder 服务

20240528230736

整个 binder 通信通道的建立过程:

  • App 向 ServiceManager 查询 SurfaceFlingerAIDL 服务,获取到服务的代理端对象
  • 接着远程调用 SurfaceFlingerAIDL 服务的 createConnection 函数,获取到 Client 匿名服务的代理端对象
  • App 想要调用 SurfaceFlinger 相关的功能,可以远程调用 Client 服务,Client 服务中具体的功能再委托给 SurfaceFlinger 来实现。

# 参考资料