Call preserveSurfaces when detaching children.
When WM calls detachChildren, it means the app is exiting and we temporarily want to keep the children around so they aren't removed during the animation. If the app is quickly relaunched, the children will remain detached and will not be removed. Therefore, add a call to preserveSurfaces when detachChildren is called so it can keep the children around. When the app relaunches, it will tear down the preserved surface. We also need to ensure the children aren't reparented to the new surface so we make sure the children weren't detached previously before reparented them to the new surface. Test: Quickly close and open app with SV. SV will not leak Bug: 157439199 Fixes: 155694905 Change-Id: Iea8ed86a9c4a7674804152aa44df7ef3d6341768
This commit is contained in:
@@ -418,25 +418,25 @@ class WindowStateAnimator {
|
||||
if (!mDestroyPreservedSurfaceUponRedraw) {
|
||||
return;
|
||||
}
|
||||
if (mSurfaceController != null) {
|
||||
if (mPendingDestroySurface != null) {
|
||||
// If we are preserving a surface but we aren't relaunching that means
|
||||
// we are just doing an in-place switch. In that case any SurfaceFlinger side
|
||||
// child layers need to be reparented to the new surface to make this
|
||||
// transparent to the app.
|
||||
if (mWin.mActivityRecord == null || mWin.mActivityRecord.isRelaunching() == false) {
|
||||
mPostDrawTransaction.reparentChildren(
|
||||
mPendingDestroySurface.getClientViewRootSurface(),
|
||||
mSurfaceController.mSurfaceControl).apply();
|
||||
}
|
||||
}
|
||||
|
||||
// If we are preserving a surface but we aren't relaunching that means
|
||||
// we are just doing an in-place switch. In that case any SurfaceFlinger side
|
||||
// child layers need to be reparented to the new surface to make this
|
||||
// transparent to the app.
|
||||
// If the children are detached, we don't want to reparent them to the new surface.
|
||||
// Instead let the children get removed when the old surface is deleted.
|
||||
if (mSurfaceController != null && mPendingDestroySurface != null && !mChildrenDetached
|
||||
&& (mWin.mActivityRecord == null || !mWin.mActivityRecord.isRelaunching())) {
|
||||
mPostDrawTransaction.reparentChildren(
|
||||
mPendingDestroySurface.getClientViewRootSurface(),
|
||||
mSurfaceController.mSurfaceControl).apply();
|
||||
}
|
||||
|
||||
destroyDeferredSurfaceLocked();
|
||||
mDestroyPreservedSurfaceUponRedraw = false;
|
||||
}
|
||||
|
||||
void markPreservedSurfaceForDestroy() {
|
||||
private void markPreservedSurfaceForDestroy() {
|
||||
if (mDestroyPreservedSurfaceUponRedraw
|
||||
&& !mService.mDestroyPreservedSurface.contains(mWin)) {
|
||||
mService.mDestroyPreservedSurface.add(mWin);
|
||||
@@ -1363,9 +1363,13 @@ class WindowStateAnimator {
|
||||
if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
|
||||
final SurfaceControl pendingSurfaceControl = mPendingDestroySurface.mSurfaceControl;
|
||||
mPostDrawTransaction.reparent(pendingSurfaceControl, null);
|
||||
mPostDrawTransaction.reparentChildren(
|
||||
mPendingDestroySurface.getClientViewRootSurface(),
|
||||
mSurfaceController.mSurfaceControl);
|
||||
// If the children are detached, we don't want to reparent them to the new surface.
|
||||
// Instead let the children get removed when the old surface is deleted.
|
||||
if (!mChildrenDetached) {
|
||||
mPostDrawTransaction.reparentChildren(
|
||||
mPendingDestroySurface.getClientViewRootSurface(),
|
||||
mSurfaceController.mSurfaceControl);
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceControl.mergeToGlobalTransaction(mPostDrawTransaction);
|
||||
@@ -1593,6 +1597,12 @@ class WindowStateAnimator {
|
||||
mSurfaceController.detachChildren();
|
||||
}
|
||||
mChildrenDetached = true;
|
||||
// If the children are detached, it means the app is exiting. We don't want to tear the
|
||||
// content down too early, otherwise we could end up with a flicker. By preserving the
|
||||
// current surface, we ensure the content remains on screen until the window is completely
|
||||
// removed. It also ensures that the old surface is cleaned up when started again since it
|
||||
// forces mSurfaceController to be set to null.
|
||||
preserveSurfaceLocked();
|
||||
}
|
||||
|
||||
void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) {
|
||||
|
||||
Reference in New Issue
Block a user