summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author chaviw <chaviw@google.com> 2020-06-02 18:45:20 -0700
committer chaviw <chaviw@google.com> 2020-06-04 08:57:08 -0700
commit9118c9b573a743a1526beb7a0de48174ee561af2 (patch)
tree07175b2542bda472bf2f59dbef151d88e12473c7
parent28fdf609dcce30f9825006d60f6a45b4cc4d88dd (diff)
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
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java42
1 files changed, 26 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 42c21930bdf7..c0252363a159 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -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) {