Merge "Prepare to replace windows across recreate()." into nyc-dev
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4f00f91..cf2ef45 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4168,7 +4168,7 @@
                 }
                 IBinder wtoken = v.getWindowToken();
                 if (r.activity.mWindowAdded) {
-                    if (r.onlyLocalRequest || r.mPreserveWindow) {
+                    if (r.mPreserveWindow) {
                         // Hold off on removing this until the new activity's
                         // window is being added.
                         r.mPendingRemoveWindow = r.window;
@@ -4403,15 +4403,20 @@
         // be replaced and defer requests to destroy or hide them. This way we can achieve
         // visual continuity. It's important that we do this here prior to pause and destroy
         // as that is when we may hide or remove the child views.
+        //
+        // There is another scenario, if we have decided locally to relaunch the app from a
+        // call to recreate, then none of the windows will be prepared for replacement or
+        // preserved by the server, so we want to notify it that we are preparing to replace
+        // everything
         try {
-            if (r.mPreserveWindow) {
-                WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token);
+            if (r.mPreserveWindow || r.onlyLocalRequest) {
+                WindowManagerGlobal.getWindowSession().prepareToReplaceWindows(
+                        r.token, !r.onlyLocalRequest);
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
 
-
         // Need to ensure state is saved.
         if (!r.paused) {
             performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity");
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 8e1609c..1facc10 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -125,11 +125,13 @@
 
     /*
      * Notify the window manager that an application is relaunching and
-     * child windows should be prepared for replacement.
+     * windows should be prepared for replacement.
      *
      * @param appToken The application
+     * @param childrenOnly Whether to only prepare child windows for replacement
+     * (for example when main windows are being reused via preservation).
      */
-    void prepareToReplaceChildren(IBinder appToken);
+    void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly);
 
     /**
      * If a call to relayout() asked to have the surface destroy deferred,
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index daeb860..08c0a4b 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -201,8 +201,8 @@
     }
 
     @Override
-    public void prepareToReplaceChildren(IBinder appToken) {
-        mService.setReplacingChildren(appToken);
+    public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
+        mService.setReplacingWindows(appToken, childrenOnly);
     }
 
     public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5a5f10c..4762cbf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -10700,12 +10700,16 @@
     }
 
     /**
-     * Hint to a token that its children will be replaced across activity relaunch.
-     * The children would otherwise be removed  shortly following this as the
+     * Hint to a token that its windows will be replaced across activity relaunch.
+     * The windows would otherwise be removed  shortly following this as the
      * activity is torn down.
      * @param token Application token for which the activity will be relaunched.
+     * @param childrenOnly Whether to mark only child windows for replacement
+     *                     (for the case where main windows are being preserved/
+     *                     reused rather than replaced).
+     *
      */
-    public void setReplacingChildren(IBinder token) {
+    public void setReplacingWindows(IBinder token, boolean childrenOnly) {
         AppWindowToken appWindowToken = null;
         synchronized (mWindowMap) {
             appWindowToken = findAppWindowToken(token);
@@ -10715,7 +10719,12 @@
                 return;
             }
 
-            appWindowToken.setReplacingChildren();
+            if (childrenOnly) {
+                appWindowToken.setReplacingChildren();
+            } else {
+                appWindowToken.setReplacingWindows(false /* animate */);
+            }
+
             scheduleClearReplacingWindowIfNeeded(token, true /* replacing */);
         }
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 5a6a00f..7582fda 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -233,7 +233,7 @@
     }
 
     @Override
-    public void prepareToReplaceChildren(IBinder appToken) {
+    public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
         // pass for now.
     }