干货分享:sf中Layer泄露问题分析修复实战方法--直播总结

背景

图层泄露的复现步骤和前置知识,请看这里:
https://mp.weixin.qq.com/s/yiQH4iPJKTH153Pn40Xu0A

昨天晚上也对壁纸的泄露问题进行详细的直播讲解,今天把这部分进行相关的直播过程总结,方便各位学员们进行后续查看阅读。
直播讲解壁纸ImageWallpaper图层泄露问题,主要就以下几个点来进行:

1、遇到这种layer泄漏的问题,请问你是如何排查的,说出你的流程

2、为啥会有ImageWallpaper的layer泄漏呢?请剖析出原因

3、请问为啥就ImageWallpaper有泄漏,其他正常的窗口没泄漏呢?

4、给出相关的优化修复方案,并进行验证

在这里插入图片描述

排查壁纸图层OffScreen泄露问题流程

具体流程如下:

在这里插入图片描述1、通过dumpsys SurfaceFlinger 查看OffScreen数据,看是否存在某些layer只增不减情况,如果有这个Layer就很可能泄漏,需要根据Layer名字推测出SurfaceControl名字,寻找到相关SurfaceControl创建代码位置

2、寻找到了SurfaceControl,然后要分析业务,注意排查看看是否在窗口业务结束后进行了正常的release

3、如果发现没有release,则可以考虑加上进行复现看看是否还有

4、上面3步对于一个Layer只有一个SurfaceControl持有都一般可以解决,但是有可能一个Layer有多个SC的情况,这种就要多个地方加入日志排查。(相关案例后续考虑给vip学员们再分享)

在这里插入图片描述
定位ImageWallpaper的泄漏原因:
创建ImageWallpaper对于的SurfaceControl

   void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
       //省略
       //可以看到这里调用wms的relayout会对mSurfaceControl进行赋值
                        relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
                                View.VISIBLE, 0, mWinFrames, mMergedConfiguration,
                                mSurfaceControl, mInsetsState, mTempControls, mSyncSeqIdBundle);
                    }

正常要释放的方法detach没有看到mSurfaceControl.release()


        void detach() {
           //省略
           //在detach代码没有对mSurfaceControl.release()进行调用
                mSurfaceHolder.mSurface.release();
                if (mBlastBufferQueue != null) {
                    mBlastBufferQueue.destroy();
                    mBlastBufferQueue = null;
                }
                if (mBbqSurfaceControl != null) {
                     new SurfaceControl.Transaction().remove(mBbqSurfaceControl).apply();
                    mBbqSurfaceControl = null;
                }
                mCreated = false;
            }
        }

所以修改方案就是在detach方法中加入mSurfaceControl.release()既可以。

对比查看为啥就ImageWallpaper泄漏

这里主要对比2个场景

1、同样aosp13版本Wallpaper壁纸窗口有泄漏,为啥普通窗口没有泄漏?

这里就只需要检测普通的窗口创建相关的SurfaceControl是在ViewRootImpl中进行的,可以看看ViewRootImpl中对SurfaceControl看看是否有进行release
relayout中会对mSurfaceControl进行赋值

frameworks/base/core/java/android/view/ViewRootImpl.java

 private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
    //省略
    //这里和Wallpaper一样都是relayout进行的操作,赋值mSurfaceControl
            relayoutResult = mWindowSession.relayout(mWindow, params,
                    requestedWidth, requestedHeight, viewVisibility,
                    insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
                    mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
                    mTempControls, mRelayoutBundle);
  
            }

但是在壁纸WallpaperService中是没有看到有release调用,ViewRootImpl中是有对这里的mSurfaceControl进行release。

frameworks/base/core/java/android/view/ViewRootImpl.java



    private void destroySurface() {
        if (mBoundsLayer != null) {
            mBoundsLayer.release();
            mBoundsLayer = null;
        }
        mSurface.release();
        mSurfaceControl.release();//明显ViewRootImpl在这里有对SurfaceControl进行了release

        if (mBlastBufferQueue != null) {
            mBlastBufferQueue.destroy();
            mBlastBufferQueue = null;
        }

        if (mAttachInfo.mThreadedRenderer != null) {
            mAttachInfo.mThreadedRenderer.setSurfaceControl(null);
            mAttachInfo.mThreadedRenderer.setBlastBufferQueue(null);
        }
    }

所以这里源码就解答为啥正常窗口没有泄漏,只有WallpaperService有,就因为正常窗口ViewRootImpl是有调用这release。

对比aosp15壁纸为啥又没有泄露呢?

同样的壁纸切换操作在aosp15上操作若干次都没有看到有任何ImageWallpaper图层放入到OffScreen中

test@test:~$ adb shell dumpsys SurfaceFlinger | grep Offscreen -A 20 | grep ImageWallpaper

那么为啥aosp15没有呢?
需要回答这个问题,就需要查看官方对于WallpaperService这块的修改。
在这里插入图片描述在aosp15的代码中可以看到实际上是有调用SurfaceControl的release方法。

官方修复相关git log

上面问题分析清楚后,那么为啥新版本没有
aosp官方修复方法:

test@test:~/aosp15/frameworks/base$ git show 9c1d6b45920a4
commit 9c1d6b45920a402d35f18057151e78cad1ccf0b4
Author: Robin Lee <rgl@google.com>
Date:   Thu Feb 9 14:41:37 2023 +0100

    Release WallpaperService SurfaceControl directly
    
    The SurfaceControl is created with the engine and filled in later after
    the first time attachging. It can be released as soon as the engine is detached, since wallpaper engines are never reused after detaching.
    
    Test: atest WallpaperManagerTest # after which, check dumpsys surfaceflinger for leftover offscreen wallpaper layers
    Test: adb shell su root kill -10 `adb shell pidof system_server` # and then take a heap dump to ensure the IWindow is also gone.
    Bug: 261358202
    Change-Id: I86f0a3ee9b8272d61bbc8f9c5f80ee3f0ddac96f

diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 12cd5236017c..f53abce1d1ea 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -2198,6 +2198,11 @@ public abstract class WallpaperService extends Service {
                 }
                 mCreated = false;
             }
+
+            if (mSurfaceControl != null) {
+                mSurfaceControl.release();
+                mSurfaceControl = null;
+            }
         }
 
         private final DisplayListener mDisplayListener = new DisplayListener() {

看可以从官方链接看出已经针对这个ImageWallpaper图层泄露问题进行了修复。

原文参考:
https://mp.weixin.qq.com/s/PgAmwjeGYLaQbfuVWUXeWg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

千里马学框架

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

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

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

打赏作者

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

抵扣说明:

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

余额充值