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.
}