SurfaceFlinger02-surfaceflinger跨进程交互

1,277 阅读6分钟

前言

surfaceflinger既是一个独立进程,也是一个公共服务,它可以跟system_server交互,也可以直接和应用进程交互,还能跟底层HW Composer交互。这些操作都是通过Binder实现IPC(跟HWC是通过Aidl HAL)。

在surfaceflinger进程内部,提供了两个IPC服务来支撑和system_server/APP进程的交互。

整个交互架构上,提供了统一的接口层——SurfaceComposerClient,从而避免应用进程直接获取服务接口和交互实现。

本篇文章中,将对surfaceflinger进程进行跨进程通信(IPC)的接口服务、以及跨进程交互组件进行说明总结。

一、surfaceflinger进程IPC接口服务

1.1、IPC接口定义和注册

在surfaceflinger启动时,创建并注册了两个Binder 服务,用于和其他进程间进行交互:

// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {
    // 注册ISurfaceComposer到servicemanager
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
    
    // 注册gui::ISurfaceComposer到servicemanager
    sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger);
    sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    return 0;
}

1.1.1、ISurfaceComposer接口

SurfaceFlinger类继承于BnSurfaceComposer,而BnSurfaceComposer是ISurfaceComposer接口的实现:

// frameworks/native/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger : public BnSurfaceComposer { ...... }

// frameworks/native/libs/gui/include/gui/ISurfaceComposer.h
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> { ...... }

因此,SurfaceFlinger类在完成向ServiceManager的注册后便具有IPC能力。

1.1.2、gui::ISurfaceComposer接口

gui::ISurfaceComposer是Android T上通过AIDL的方式生成的服务接口,aidl文件位于如下位置中:

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

interface ISurfaceComposer {
    .......
}

surfaceflinger进程中,让SurfaceComposerAIDL继承了gui::BnSurfaceComposer:

// frameworks/native/services/surfaceflinger/SurfaceFlinger.h

class SurfaceComposerAIDL : public gui::BnSurfaceComposer { ... }

如果需要在SurfaceComposerAIDL中新增接口,就必须要修改ISurfaceComposer.aidl文件。

通过SurfaceComposerAIDL,可以分担一部分SurfaceFlinger的跨进程压力。

SurfaceFlinger和SurfaceComposerAIDL的类关系如下图所示:

1.2、IPC服务获取方式

在完成向ServiceManager的注册后,就可以直接获取对应的IPC服务句柄了,Java层通过如下方式可获取SurfaceFlinger(ISurfaceComposer)服务:

// 获取ISurfaceComposer服务

IBinder sf = ServiceManager.getService("SurfaceFlinger");
if (sf != null) {
    reply = Parcel.obtain();
    data = Parcel.obtain();
    data.writeInterfaceToken("android.ui.ISurfaceComposer");
    sf.transact(/* LAYER_TRACE_STATUS_CODE */ 1026, data, reply, 0 /* flags */);
    return reply.readBoolean();
}

C++层通过如下方式获取SurfaceFlinger(ISurfaceComposer)服务和SurfaceComposerAIDL(gui::ISurfaceComposer)服务:

// 获取SurfaceFlinger服务
const String16 name("SurfaceFlinger");
sp<ISurfaceComposer> mComposerService = waitForService<ISurfaceComposer>(name);

// 获取SurfaceComposerAIDL服务
const String16 name("SurfaceFlingerAIDL");
sp<gui::ISurfaceComposer> mComposerService = waitForService<gui::ISurfaceComposer>(name);

不过,应用进程跟surfaceflinger进程的通信,更多地是通过一个“中间层”SurfaceComposerClient来进行,SurfaceComposerClient中通过以上方法获取surfaceflinger进程IPC服务,并将应用进程参数传递给surfaceflinger。

1.3、surfaceflinger服务端的响应

当客户端直接通过IPC服务的方式或通过SurfaceComposerClient发起跟surfaceflinger的交互后,surfaceflinger作为服务端进行响应,执行各自的onTransact()方法。

1.3.1、ISurfaceComposer::onTransact()

如果是ISurfaceComposer服务调用,会执行ISurfaceComposer::onTransact()方法:

// frameworks/native/libs/gui/ISurfaceComposer.cpp

status_t BnSurfaceComposer::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case SET_TRANSACTION_STATE: {
        ......
        }
    }
    ......
}

SurfaceFlinger类重写了该方法,因此,在收到来自其他进程的调用后,会优先执行父类方法,当父类方法没法满足时,执行子类中的逻辑:

// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                    uint32_t flags) {
    if (const status_t error = CheckTransactCodeCredentials(code); error != OK) {
        return error;
    }
    // 优先执行父类方法
    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
        .....
        int n;
        switch (code) {
            case 1000: // Unused.
            ......
        }
    }
}

1.3.2、gui::ISurfaceComposer::onTransact()

如果是来自gui::ISurfaceComposer服务的调用,由于它是通过aidl生成,因此直接会执行到对应方法,这些方法基本都被SurfaceComposerAIDL类进行了重写,如设置亮度接口:

// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

binder::Status SurfaceComposerAIDL::setDisplayBrightness(const sp<IBinder>& displayToken,
                                                         const gui::DisplayBrightness& brightness) {
    status_t status = checkControlDisplayBrightnessPermission();
    if (status == OK) {
        status = mFlinger->setDisplayBrightness(displayToken, brightness);
    }
    return binderStatusFromStatusT(status);
}

二、IPC相关组件

这里对应用进程和surfaceflinger进程在View内容更新过程中进行IPC时,涉及到的三个类进行下介绍:SurfaceComposerClient、SurfaceControl、SurfaceControl.Transaction。

2.1、SurfaceComposerClient

应用进程与surfaceflinger交互过程中,除特殊场景外,并不会直接获取服务接口进行通信,也不推荐这种方式。系统提供了统一的接口层——SurfaceComposerClient,作为surfaceflinger进程和应用进程间的“中间件”,进行IPC交互。此外,从SurfaceComposerClient命名看,就是SurfaceComposer的客户端,相对应的服务端正是SurfaceFlinger。

流程图1.jpg

SurfaceComposerClient中,获取SurfaceComposerAIDL服务实例如下:

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

// 获取SurfaceComposerAIDL服务实例
/*static*/ sp<gui::ISurfaceComposer> ComposerServiceAIDL::getComposerService() {
    ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
    std::scoped_lock lock(instance.mMutex);
    if (instance.mComposerService == nullptr) {
        if (ComposerServiceAIDL::getInstance().connectLocked()) {
            WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
        }
    }
    return instance.mComposerService;
}

bool ComposerServiceAIDL::connectLocked() {
    const String16 name("SurfaceFlingerAIDL");
    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) {
            mComposerService.composerServiceDied();
        }

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

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

获取SurfaceFlinger服务实例如下:

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

// 获取SurfaceFlinger服务实例
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == nullptr) {
        if (ComposerService::getInstance().connectLocked()) {
            ALOGD("ComposerService reconnected");
        }
    }
    return instance.mComposerService;
}

bool ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    mComposerService = waitForService<ISurfaceComposer>(name);
    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<IBinder>& who) {
            mComposerService.composerServiceDied();
        }
     public:
        explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

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

2.2、SurfaceControl

SurfaceControl是暴露给外部进程用于操作surfaceflinger进程中Layer的句柄,它定义了图形缓冲数据、元数据、大小等多个属性,来描述如何显示一个Layer。当实例化一个SurfaceControl时,便会创建一个对应的Layer,并且将持有这个Layer的句柄(LayerHandle),通过LayerHandle管理Layer的保留和销毁。

应用进程的View在绘制过程中,就是将各类图形属性设置给SurfaceControl,并最终同步给surfaceflinger进行合成。

关于SurfaceControl的创建及更多细节,见《[SurfaceFlinger-07-Layer创建流程]) 》。

2.3、SurfaceControl.Transaction

SurfaceControl.Transaction是SurfaceControl中的静态内部类(以下简称Transaction),它作为一个“事务”,负责将设置给SurfaceControl的属性在同一帧内提交给surfaceflinger进行操作。

当应用进程进行View内容更新时,大致步骤如下:

  1. 第一步:应用进程将图形数据设置给SurfaceControl:
// frameworks/base/core/java/com/android/internal/policy/TransitionAnimation.java

public static void configureScreenshotLayer(SurfaceControl.Transaction t, SurfaceControl layer,
        ScreenCapture.ScreenshotHardwareBuffer buffer) {
    // 为SurfaceControl对象设置一个Buffer
    t.setBuffer(layer, buffer.getHardwareBuffer());
    // 设置DataSpace
    t.setDataSpace(layer, buffer.getColorSpace().getDataSpace());
    // Avoid showing dimming effect for HDR content when running animation.
    if (buffer.containsHdrLayers()) {
        t.setDimmingEnabled(layer, false);
    }
    t.show(mAnimLeash);
    // 设置mSurfaceControl的区域
    t.setCrop(mSurfaceControl, new Rect(0, 0, mEndWidth, mEndHeight));
}

2. 第二步:完成设置后,通过Transaction.apply()一次性将数据传递给SurfaceComposerClient:


Transaction t = new Transaction();
......
// 开始提交
t.apply();
  1. 第三步:收到apply()后,SurfaceComposerClient中向SurfaceFlinger发起调用:
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {

    ......
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
                            mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
                            mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId,
                            mMergedTransactionIds);

    return NO_ERROR;
}

除View的绘制和刷新之外,system_server和surfaceflinger之间屏幕状态的更新也是通过Transaction进行设置,这部分具体细节,见《SurfaceFlinger03-Transaction基础 》。