SurfaceFlinger中有Layer泄漏一直增长超过4096问题如何排查-实战问题分析排查

背景:

有学员在vip群里反馈一个SurfaceFlinger相关的报错
在这里插入图片描述
群里讨论也非常激烈。
问题如下:
在这里插入图片描述sf的报错信息大概可以看出这个是创建的Layer数量已经大于4096个,sf端有保护机制,为了让内存不会永久持续增大,只能报错异常,不然在创建新的。

对应的代码如下:
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
在这里插入图片描述
那么出现这种问题一般是什么原因呢?正常的系统要展示窗口时候创建layer,不展示时候肯定就会销毁layer,这样layer肯定不会只增不减,所以4096在长期经验来说已经足够大了,一旦会超过4096这个数量,那一般就是有泄露。

那么这种问题如何排查呢?这个相关优秀学员也回答很详细,在这里给大家做一个记录,方便大家以后遇到同样问题可以参考这篇文章。
在这里插入图片描述在这里插入图片描述

【Android 13】SurfaceFlinger - Layer的创建与销毁

SurfaceControl的创建

SurfaceControl的创建流程(app端创建SurfaceControl,sf端创建Layer)
在这里插入图片描述

Java层

ViewRootImpl创建SurfaceSession和SurfaceControl

ViewRootImpl的SurfaceSession在初始化的时候就构造完成:

代码位于:frameworks/base/core/java/android/view/ViewRootImpl.java
private final SurfaceSession mSurfaceSession = new SurfaceSession();
代码位于:frameworks/base/core/java/android/view/SurfaceSession.java
public SurfaceSession() {
    mNativeClient = nativeCreate();
}

ViewRootImpl通过setView()可以通过Session在system_server端构建一个WindowToken和WindowState。WindowToken和WindowState这类窗口容器的SurfaceControl在1.1.2中提到创建过程。

ViewRootImpl在初始化的时候,就构造了一个空的SurfaceControl:

代码位于frameworks/base/core/java/android/view/ViewRootImpl.java

private final SurfaceControl mSurfaceControl = new SurfaceControl();

在ViewRootImpl需要绘制的时候,通过session.relayout()会在system_server端为这个ViewRootImpl创建一个SurfaceControl,挂到WindowState下面去:

代码位于frameworks/base/core/java/android/view/ViewRootImpl.java

 private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
            //...
    relayoutResult = mWindowSession.relayout(mWindow, params,
                    requestedWidth, requestedHeight, viewVisibility,
                    insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
                    mTmpFrames, mPendingMergedConfiguration, mSurfaceControl /* 注意到这里把SurfaceControl作参数传入 */, mTempInsets,
                    mTempControls, mRelayoutBundle);
}

来到WMS,在relayout的过程中会为其构建真正的SurfaceControl (implements Parcelable),并将创建好的SurfaceControl回传给应用端的ViewRootImpl:

代码位于frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags,
            ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Bundle outSyncIdBundle) {
    // ...
    // Create surfaceControl before surface placement otherwise layout will be skipped
    // (because WS.isGoneForLayout() is true when there is no surface.
    if (shouldRelayout) {
        try {
            result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
        } catch (Exception e) {
            displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
            Binder.restoreCallingIdentity(origId);
            return 0;
        }
    }   
}

private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
        WindowState win, WindowStateAnimator winAnimator) {
    WindowSurfaceController surfaceController;
    // 在system_server端为ViewRootImpl构建一个SurfaceControl
    // winAnimator是WindowState的一个成员变量,这个WindowState是ViewRootImpl在system_server侧的挂载父亲
    surfaceController = winAnimator.createSurfaceLocked();
    if (surfaceController != null) {
        // 将创建好的SurfaceControl回传给ViewRootImpl
        surfaceController.getSurfaceControl(outSurfaceControl);
    } else {
        ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
        outSurfaceControl.release();
    }
    return result;
}

WindowStateAnimator中会构建一个mSurfaceController,其中维护了mSurfaceControl:

代码位于frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java

WindowSurfaceController createSurfaceLocked() {
    final WindowState w = mWin;
    if (mSurfaceController != null) {
        return mSurfaceController;
    }
    // ...
    mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,
        flags, this, attrs.type);
    // ...
    return mSurfaceController;
}

实例化WindowSurfaceController的时候,构造了mSurfaceControl,可以通过其getSurfaceControl()方法,将其拷贝出去:

  • 需要注意的是,这里为ViewRootImpl创建的SurfaceControl的父亲,就是其需要挂载的WindowState的SurfaceControl

代码位于frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java

WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,
            int windowType) {
    mAnimator = animator;

    title = name;

    mService = animator.mService;
    final WindowState win = animator.mWin;
    mWindowType = windowType;
    mWindowSession = win.mSession;

    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
    final SurfaceControl.Builder b = win.makeSurface()
            .setParent(win.getSurfaceControl()) /* 需要注意的是,ViewRootImpl创建的SurfaceControl挂载的父亲就是WindowState */
            .setName(name)
            .setFormat(format)
            .setFlags(flags)
            .setMetadata(METADATA_WINDOW_TYPE, windowType)
            .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
            .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
            .setCallsite("WindowSurfaceController");

    final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
            & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);

    if (useBLAST) {
        b.setBLASTLayer();
    }

    mSurfaceControl = b.build();

    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}

WindowContainer创建SurfaceSession和SurfaceControl

WindowContainer的SurfaceSession在DisplayContent初始化的时候就构造完成,其孩子使用session时,可以从父亲这里取得Session:

代码位于:frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

 private final SurfaceSession mSession = new SurfaceSession();

当WindowContainer挂载到窗口结构树上时,会为其初始化一个SurfaceControl与该窗口容器一一对应:

代码位于frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent,
            PreAssignChildLayersCallback callback) {
    //...
    if (mSurfaceControl == null) {
        createSurfaceControl(false /*force*/);
    } else {
        reparentSurfaceControl(getSyncTransaction(), mParent.mSurfaceControl);
    }
}

使用SurfaceControl.Builder进行构造:

代码位于frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

void createSurfaceControl(boolean force) {
    setInitialSurfaceControlProperties(makeSurface());
}

SurfaceControl.Builder makeSurface() {
    final WindowContainer p = getParent();
    return p.makeChildSurface(this);
}

void setInitialSurfaceControlProperties(SurfaceControl.Builder b) {
    setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build());
    if (showSurfaceOnCreation()) {
        getSyncTransaction().show(mSurfaceControl);
    }
    onSurfaceShown(getSyncTransaction());
    updateSurfacePositionNonOrganized();
}

如果窗口容器是Task.java,还会为SurfaceControl打上EffectLayer标签

代码位于frameworks/base/services/core/java/com/android/server/wm/Task.java

@Override
void setInitialSurfaceControlProperties(SurfaceControl.Builder b) {
    b.setEffectLayer().setMetadata(METADATA_TASK_ID, mTaskId);
    super.setInitialSurfaceControlProperties(b);
}

jni的发起

最终都会通过SurfaceController.Build()的方式,进行SurfaceControl的构造。SurfaceControl.java只是一个壳,真正的对象在native层:

代码位于frameworks/base/core/java/android/view/SurfaceControl.java

 private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
            SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
            String callsite) throws OutOfResourcesException, IllegalArgumentException {
    if (name == null) {
        throw new IllegalArgumentException("name must not be null");
    }

    mName = name;
    mWidth = w;
    mHeight = h;
    mLocalOwnerView = localOwnerView;
    Parcel metaParcel = Parcel.obtain();
    try {
        if (metadata != null && metadata.size() > 0) {
            metaParcel.writeInt(metadata.size());
            for (int i = 0; i < metadata.size(); ++i) {
                metaParcel.writeInt(metadata.keyAt(i));
                metaParcel.writeByteArray(
                        ByteBuffer.allocate(4).order(ByteOrder.nativeOrder())
                                .putInt(metadata.valueAt(i)).array());
            }
            metaParcel.setDataPosition(0);
        }
        // 发起构建
        mNativeObject = nativeCreate(session, name, w, h, format, flags,
                parent != null ? parent.mNativeObject : 0, metaParcel);
    } finally {
        metaParcel.recycle();
    }
    if (mNativeObject == 0) {
        throw new OutOfResourcesException(
                "Couldn't allocate SurfaceControl native object");
    }
    mNativeHandle = nativeGetHandle(mNativeObject);
    mCloseGuard.openWithCallSite("release", callsite);
}

private static native long nativeCreate(SurfaceSession session, String name,
        int w, int h, int format, int flags, long parentObject, Parcel metadata)
        throws OutOfResourcesException;

native层

代码位于:frameworks/base/core/jni/android_view_SurfaceControl.cpp

  1. 获取一个SurfaceComposerClient的引用

    1. 这是客户端对象,将用于和SurfaceFlinger服务端通信
  2. sp parentHandle 指向传入的需要挂载的SurfaceControl父亲

    1. 在native层,通过handle来指向SurfaceControl,在SurfaceFlinger端,handle->owner指向Layer
  3. 通过SurfaceComposerClient创建SurfaceControl,同时将向sf发起构建Layer的请求

static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
        jobject metadataParcel) {
    ScopedUtfChars name(env, nameStr);
    sp<SurfaceComposerClient> client;
    if (sessionObj != NULL) {
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
        client = SurfaceComposerClient::getDefault();
    }
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
    sp<SurfaceControl> surface;
    LayerMetadata metadata;
    Parcel* parcel = parcelForJavaObject(env, metadataParcel);
    if (parcel && !parcel->objectsCount()) {
        status_t err = metadata.readFromParcel(parcel);
        if (err != NO_ERROR) {
          jniThrowException(env, "java/lang/IllegalArgumentException",
                            "Metadata parcel has wrong format");
        }
    }

    sp<IBinder> parentHandle;
    if (parent != nullptr) {
        parentHandle = parent->getHandle();
    }

    status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
                                                flags, parentHandle, std::move(metadata));
    if (err == NAME_NOT_FOUND) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return 0;
    } else if (err != NO_ERROR) {
        jniThrowException(env, OutOfResourcesException, NULL);
        return 0;
    }

    surface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(surface.get());
}

SurfaceComposerClient发起Layer(surfaceflinger服务端)和SurfaceControl(client端)构建:

  • 可以看到SurfaceControl对象也是存在于客户端的,其中维护了handle,这可以用来指向sf端的Layer
  • 这里的mClient则是位于sf端的Client.cpp对象的BpBinder,它的构建在下一小节解释

代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;

    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;

        uint32_t transformHint = 0;
        int32_t id = -1;
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &id, &transformHint);

        if (outTransformHint) {
            *outTransformHint = transformHint;
        }
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
    return err;
}

实例化SurfaceControl

将sf端构造好的Layer的句柄handle (BpBinder)进行维护,以便后续deconstructor()调用时,可以远程调用进行资源释放

代码位于:frameworks/native/libs/gui/SurfaceControl.cpp

SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
                               const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
                               uint32_t w, uint32_t h, PixelFormat format, uint32_t transform,
                               uint32_t flags)
      : mClient(client),
        mHandle(handle),
        mGraphicBufferProducer(gbp),
        mLayerId(layerId),
        mTransformHint(transform),
        mWidth(w),
        mHeight(h),
        mFormat(format),
        mCreateFlags(flags) {}

SurfaceComposerClient与SurfaceFlinger建联

SurfaceComposerClient获取SurfaceFlinger服务远程代理对象

当SurfaceComposerClient首次构建的时候,会尝试与SurfaceFlinger进程建立联系:

代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp

代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        conn = sf->createConnection();
        if (conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

这里会获取一个sf对象,这是sf服务在客户端的BpBinder,通过ComposerService::getComposerService()获取:

代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp

/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    // ComposerService继承了Singleton这是个单例
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == nullptr) {
        if (ComposerService::getInstance().connectLocked()) {
            ALOGD("ComposerService reconnected");
            WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
        }
    }
    return instance.mComposerService;
}

在构造ComposerService的时候,通过ServiceManager获取SurfaceFlinger服务的BpBinder

代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp

ComposerService::ComposerService()
: Singleton<ComposerService>() {
    Mutex::Autolock _l(mLock);
    connectLocked();
}

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) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

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

SurfaceComposerClient通过sf的BpBinder远程调用,创建Client的BpBinder,用于后续通信

回到SurfaceComposerClient构建的时机,获取到sf的BpBinder后,调用了其createConnection()方法,这会在SurfaceFlinger服务端构建一个Client.cpp的实体对象,它的BpBinder交给客户端,后续SurfaceComposerClient向sf服务发起请求,都通过client的BpBinder,而不总通过SurfaceFlinger的BpBinder

代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        conn = sf->createConnection();
        if (conn != nullptr) {
            // 获取到Client的BpBinder
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

来到surfaceflinger进程,SurfaceFlinger.cpp响应createConnection()远程调用,构造一个Client,并将其BpBinder交给客户端:

代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    const sp<Client> client = new Client(this);
    return client->initCheck() == NO_ERROR ? client : nullptr;
}

SurfaceComposerClient通过Client发起Layer创建

SurfaceControl与Layer的对应关系:

回到SurfaceComposerClient创建SurfaceControl,在客户端创建SurfaceControl之前,会通过Client的BpBinder在sf端建立Layer,并将其引用句柄handle回传,由即将创建的SurfaceControl维护:

代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    // ...
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &id, &transformHint);
        if (err == NO_ERROR) {
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
    return err;
}

来到surfaceflinger进程,Client.cpp响应该远程调用:

代码位于:frameworks/native/services/surfaceflinger/Client.cpp

status_t Client::createSurface(const String8& name, uint32_t /* w */, uint32_t /* h */,
                               PixelFormat /* format */, uint32_t flags,
                               const sp<IBinder>& parentHandle, LayerMetadata metadata,
                               sp<IBinder>* outHandle, sp<IGraphicBufferProducer>* /* gbp */,
                               int32_t* outLayerId, uint32_t* outTransformHint) {
    // We rely on createLayer to check permissions.
    LayerCreationArgs args(mFlinger.get(), this, name.c_str(), flags, std::move(metadata));
    return mFlinger->createLayer(args, outHandle, parentHandle, outLayerId, nullptr,
                                 outTransformHint);
}

转发给SurfaceFlinger.cpp来进行Layer的创建:

  • 根据不同的Layer类型进行创建,类型有:EffectLayer(例如Task的Layer),ContainerLayer(例如ActivityRecord的Layer), BufferStateLayer(有实在内容的Layer)
  • 将构建好的Layer进行记录,addClientLayer()
  • 为Layer带上sequence,这是递增的数值,用来维护其唯一性

代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHandle,
                                     const sp<IBinder>& parentHandle, int32_t* outLayerId,
                                     const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
    status_t result = NO_ERROR;
    sp<Layer> layer;
    switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
        case ISurfaceComposerClient::eFXSurfaceBufferState: {
            result = createBufferStateLayer(args, outHandle, &layer);
        } break;
        case ISurfaceComposerClient::eFXSurfaceEffect:
            result = createEffectLayer(args, outHandle, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceContainer:
            result = createContainerLayer(args, outHandle, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }
    //...
    result = addClientLayer(args.client, *outHandle, layer, parent, addToRoot, outTransformHint);
    *outLayerId = layer->sequence;
    return result;
}

重点关注1: 构造Layer的时候,会同时构建一个指向该Layer的Handle, 以createEffectLayer为例:

代码位于frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* handle,
                                           sp<Layer>* outLayer) {
    *outLayer = getFactory().createEffectLayer(args);
    *handle = (*outLayer)->getHandle();
    return NO_ERROR;
}

代码位于:frameworks/native/services/surfaceflinger/Layer.cpp

sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);
    if (mGetHandleCalled) {
        ALOGE("Get handle called twice" );
        return nullptr;
    }
    mGetHandleCalled = true;
    return new Handle(mFlinger, this);
}

重点关注到Handle:

  • 作为Layer的句柄,是BBinder类型,在sf端,可以通过owner找到对应的Layer,在客户端可以通过handle远程对应到Layer
  • 可以控制Layer的销毁,当Layer被销毁的时候,句柄也会销毁,会走到mFlinger->onHandleDestroyed(),从相关集合中移除,如mOffscreenLayers集合
/*
 * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer)
 * is called.
 */
class LayerCleaner {
    sp<SurfaceFlinger> mFlinger;
    sp<Layer> mLayer;
    BBinder* mHandle;

protected:
    ~LayerCleaner() {
        // destroy client resources
        mFlinger->onHandleDestroyed(mHandle, mLayer);
    }

public:
    LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer, BBinder* handle)
          : mFlinger(flinger), mLayer(layer), mHandle(handle) {}
};

/*
 * The layer handle is just a BBinder object passed to the client
 * (remote process) -- we don't keep any reference on our side such that
 * the dtor is called when the remote side let go of its reference.
 *
 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
 * this layer when the handle is destroyed.
 */
class Handle : public BBinder, public LayerCleaner {
public:
    Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
          : LayerCleaner(flinger, layer, this), owner(layer) {}
    const String16& getInterfaceDescriptor() const override { return kDescriptor; }

    static const String16 kDescriptor;
    wp<Layer> owner;
};

**重点关注2:**addClientLayer(),将创建好的Layer进行添加:

  • 记录到mCreatedLayers集合中
  • 将其与Client绑定

代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                                        const sp<Layer>& layer, const wp<Layer>& parent,
                                        bool addToRoot, uint32_t* outTransformHint) {
    if (mNumLayers >= ISurfaceComposer::MAX_LAYERS /* 4096 */) {
        // 报错
        return NO_MEMORY;
    }
    
    {
        std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
        mCreatedLayers.emplace_back(layer, parent, addToRoot);
    }
    
    // attach this layer to the client
    if (client != nullptr) {
        client->attachLayer(handle, layer);
    }
}

Client.cpp中维护Layer

  • 关系是, 一个SurfaceComposerClient持有一个Client的BpBinder,一个Client下可能维护有多个Layer,场景是 client->mirrorSurface() \ 再次client->createSurface()

SurfaceControl的销毁与Layer的释放

SurfaceControl的销毁

java层销毁SurfaceControl

java层,通过SurfaceControl.Transaction的remove()方法,可以进行SurfaceControl的销毁:

  • reparent到父亲为null
  • release释放引用关系

这使得Layer成为游离态,将会在sf端的mOffscreenLayers集合中存在,并在Layer所有引用消失的时候,调用析构函数,从mOffscreenLayers中移除,真正销毁Layer。

代码位于:frameworks/base/core/java/android/view/SurfaceControl.java

// SurfaceControl.Transaction
public Transaction remove(@NonNull SurfaceControl sc) {
    reparent(sc, null);
    sc.release();
    return this;
}

public Transaction reparent(@NonNull SurfaceControl sc,
        @Nullable SurfaceControl newParent) {
    checkPreconditions(sc);
    long otherObject = 0;
    if (newParent != null) {
        newParent.checkNotReleased();
        otherObject = newParent.mNativeObject;
    }
    nativeReparent(mNativeObject, sc.mNativeObject, otherObject);
    mReparentedSurfaces.put(sc, newParent);
    return this;
}
// SurfaceControl
public void release() {
    if(LOG_SURFACE_CONTROL) {
        Log.d(TAG, "release, mNativeObject:" + mNativeObject, new Throwable());
    }

    if (mNativeObject != 0) {
        nativeRelease(mNativeObject);
        mNativeObject = 0;
        mNativeHandle = 0;
        mCloseGuard.close();
    }
}

native层销毁SurfaceControl

SurfaceControl.cpp继承于RefBase.cpp,它的析构函数会在强引用关系消失的时候调用

代码位于:frameworks/base/core/jni/android_view_SurfaceControl.cpp

static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
    // 强引用数 -1
    ctrl->decStrong((void *)nativeCreate);
}

当其强引用关系消失的时候,调用deconstructor:

代码位于:system/core/libutils/RefBase.cpp

void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->removeStrongRef(id);
    const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);
    LOG_ALWAYS_FATAL_IF(BAD_STRONG(c), "decStrong() called on %p too many times",
            refs);
    if (c == 1) {
        std::atomic_thread_fence(std::memory_order_acquire);
        refs->mBase->onLastStrongRef(id);
        int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            delete this;
            // The destructor does not delete refs in this case.
        }
    }
    refs->decWeak(id);
}

Layer的销毁

Layer也继承自RefBase.cpp当其引用关系清空时,将会触发析构函数,进行Layer的销毁释放。Layer被handle持有,在SurfaceControl.cpp对象释放的时候,将会触发handle的释放:

SurfaceControl的析构

代码位于:frameworks/native/libs/gui/SurfaceControl.cpp

SurfaceControl::~SurfaceControl()
{
    // Trigger an IPC now, to make sure things
    // happen without delay, since these resources are quite heavy.
    mClient.clear();
    mHandle.clear();
    mBbq.clear();
    IPCThreadState::self()->flushCommands();
}

这里将Handle的引用进行了释放,来到sf端:

Handle触发析构,继承自LayerCleaner:

代码位于:frameworks/native/services/surfaceflinger/Layer.h

class LayerCleaner {
    sp<SurfaceFlinger> mFlinger;
    sp<Layer> mLayer;
    BBinder* mHandle;

protected:
    ~LayerCleaner() {
        // destroy client resources
        mFlinger->onHandleDestroyed(mHandle, mLayer);
    }

Layer引用清空

来到SurfaceFlinger.cpp,进行Handle销毁的回调,将Layer进行引用清空:

代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer) {
    Mutex::Autolock lock(mStateLock);
    markLayerPendingRemovalLocked(layer);
    mBufferCountTracker.remove(handle);
    layer.clear();
    if (mTransactionTracing) {
        mTransactionTracing->onHandleRemoved(handle);
    }
}

Layer引用清空后,Layer触发析构:

Layer::~Layer() {
    sp<Client> c(mClientRef.promote());
    if (c != 0) {
        c->detachLayer(this);
    }

    mFlinger->onLayerDestroyed(this);
    
    if (mHadClonedChild) {
        mFlinger->mNumClones--;
    }
}

在SurfaceFlinger.cpp中清空该Layer的记录:

  • 从mOffscreenLayers集合中移除
  • mNumLayers总Layer数记录-1
void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
    mNumLayers--;
    removeHierarchyFromOffscreenLayers(layer);
    if (!layer->isRemovedFromCurrentState()) {
        mScheduler->deregisterLayer(layer);
    }
    if (mTransactionTracing) {
        mTransactionTracing->onLayerRemoved(layer->getSequence());
    }
}

至此完成Layer的销毁,和资源的释放。

TODO:

多个SurfaceControl(nativeCopy) 都指向一个Layer,只有所有SurfaceControl都销毁,才会将Layer的引用清空,触发析构。跟踪该流程。

实际案例

BugFix:
在这里插入图片描述

问题原因:进入过分屏的Task,其Layer都无法触发析构,当mOffscreenLayers数量过高,总Layer数超过4096后将会创建SurfaceControl失败。

跟踪发现,SystemUI会通过nativeCopy构造一个SurfaceControl,其中的handle就指向Task的Layer。

进入分屏后,该SurfaceControl会被StageTaskListener中的StageTaskUnfoldController持有,当该Task销毁vanished()时,StageTaskUnfoldController并没有将其引用释放。发生内存泄漏:

代码位置:frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java

public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
        // 这里条件不符合,直接return,导致没有触发后续的remove
        if (!taskInfo.hasParentTask()) return;

        AnimationContext context = mAnimationContextByTaskId.get(taskInfo.taskId);
        if (context != null) {
            final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
            resetSurface(transaction, context);
            transaction.apply();
            mTransactionPool.release(transaction);
        }
        mAnimationContextByTaskId.remove(taskInfo.taskId);
    }

解决:

  • 方案1:取消折叠屏特性,不触发StageTaskUnfoldController的onTaskAppeared和onTaskVanished
  • 方案2: 调整逻辑,使得remove逻辑正常
  • 方案3: ShellTaskOrganizer中收到onTaskVanished最后,主动对SurfaceControl调用release()

更多framework实战干货,请关注下面“千里马学框架”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值