Reland "Prevent dismissing starting window when reopening app"

If we are changing the visibility while the app is shortly before
drawing it's first frame, we cleared out the draw state, leading
to a hang. We also had this issue with starting windows, but that
was a fix only for starting windows, but cascaded the underlying
issue.

Now, we only clear out the draw state if is has fully drawn - this
covers the Chrome case but doesn't clear out draw state if it's
just about to show.

Furthermore, we also add the window to mResizingWindows such that
the client is expected to call back to us with reportDrawn, in all
the edge cases.

Test: go/wm-smoke
Test: Open TTS settings, go back, open again
Test: All the use cases from the linked bug
Bug: 135706138
Bug: 135661232
Bug: 135976008
Bug: 135921478
Bug: 135780312
Bug: 135084202
Fixes: 134561008
Change-Id: I69f893a19d6426710bb0b8b0e18f3d2664cb6412
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 03cae42..eab5e0d 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -79,6 +79,7 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.logWithStack;
 import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
+import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
 
@@ -540,6 +541,18 @@
                 // If the app was already visible, don't reset the waitingToShow state.
                 if (isHidden()) {
                     waitingToShow = true;
+
+                    // Let's reset the draw state in order to prevent the starting window to be
+                    // immediately dismissed when the app still has the surface.
+                    forAllWindows(w -> {
+                        if (w.mWinAnimator.mDrawState == HAS_DRAWN) {
+                            w.mWinAnimator.resetDrawState();
+
+                            // Force add to mResizingWindows, so that we are guaranteed to get
+                            // another reportDrawn callback.
+                            w.resetLastContentInsets();
+                        }
+                    },  true /* traverseTopToBottom */);
                 }
             }