Detach children when stopping app.

Prior to the implementation of detachChildren we handled this
case via the "mWindowStopped" codepath in SurfaceView.java which this
CL deletes. That codepath however causes confusion due to it's failure
to set null the SurfaceControl, meaning we may not necessarily
recreate it when resuming if we didn't hit any other code-path
to do such as happens in linked bug 78588930. Anyway it seems clearest
to handle all these preserve-child-surfaces-on-tear-down cases via
one mechanism (detachChildren).

Bug: 78588930
Test: Manual.
Change-Id: Iac7c0bc0c6b4da0d405bdc2b57d13d5c881611b0
This commit is contained in:
Robert Carr
2018-04-27 11:56:48 -07:00
parent 2897fd315d
commit 29daa92be9
4 changed files with 24 additions and 11 deletions

View File

@@ -700,15 +700,9 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
mIsCreating = false;
if (mSurfaceControl != null && !mSurfaceCreated) {
mSurface.release();
// If we are not in the stopped state, then the destruction of the Surface
// represents a visual change we need to display, and we should go ahead
// and destroy the SurfaceControl. However if we are in the stopped state,
// we can just leave the Surface around so it can be a part of animations,
// and we let the life-time be tied to the parent surface.
if (!mWindowStopped) {
mSurfaceControl.destroy();
mSurfaceControl = null;
}
mSurfaceControl.destroy();
mSurfaceControl = null;
}
}
} catch (Exception ex) {

View File

@@ -1626,6 +1626,10 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
if (parent != null) {
parent.onActivityStateChanged(this, state, reason);
}
if (state == STOPPING) {
mWindowContainerController.notifyAppStopping();
}
}
ActivityState getState() {

View File

@@ -671,6 +671,17 @@ public class AppWindowContainerController
}
}
public void notifyAppStopping() {
synchronized(mWindowMap) {
if (mContainer == null) {
Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
+ mToken);
return;
}
mContainer.detachChildren();
}
}
public void notifyAppStopped() {
synchronized(mWindowMap) {
if (mContainer == null) {

View File

@@ -913,12 +913,16 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
// try and clean up it's child surfaces. We need to prevent this from
// happening, so we sever the children, transfering their ownership
// from the client it-self to the parent surface (owned by us).
detachChildren();
mPendingRelaunchCount++;
}
void detachChildren() {
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState w = mChildren.get(i);
w.mWinAnimator.detachChildren();
}
mPendingRelaunchCount++;
}
void finishRelaunching() {