背景
图层泄露的复现步骤和前置知识,请看这里:
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图层泄露问题进行了修复。

1093

被折叠的 条评论
为什么被折叠?



