summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java33
2 files changed, 37 insertions, 2 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1da21b0dc5e7..0764ff41efaf 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3474,6 +3474,12 @@ public final class ActivityThread {
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
+ // Normally the ViewRoot sets up callbacks with the Activity
+ // in addView->ViewRootImpl#setView. If we are instead reusing
+ // the decor view we have to notify the view root that the
+ // callbacks may have changed.
+ ViewRootImpl impl = decor.getViewRootImpl();
+ impl.notifyChildRebuilt();
}
if (a.mVisibleFromClient && !a.mWindowAdded) {
a.mWindowAdded = true;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9e4f26fe0aec..a0384f2601d3 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -514,6 +514,34 @@ public final class ViewRootImpl implements ViewParent,
}
/**
+ * Notifies us that our child has been rebuilt, following
+ * a window preservation operation. In these cases we
+ * keep the same DecorView, but the activity controlling it
+ * is a different instance, and we need to update our
+ * callbacks.
+ *
+ * @hide
+ */
+ public void notifyChildRebuilt() {
+ if (mView instanceof RootViewSurfaceTaker) {
+ mSurfaceHolderCallback =
+ ((RootViewSurfaceTaker)mView).willYouTakeTheSurface();
+ if (mSurfaceHolderCallback != null) {
+ mSurfaceHolder = new TakenSurfaceHolder();
+ mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
+ } else {
+ mSurfaceHolder = null;
+ }
+
+ mInputQueueCallback =
+ ((RootViewSurfaceTaker)mView).willYouTakeTheInputQueue();
+ if (mInputQueueCallback != null) {
+ mInputQueueCallback.onInputQueueCreated(mInputQueue);
+ }
+ }
+ }
+
+ /**
* We have one child
*/
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
@@ -1645,6 +1673,8 @@ public final class ViewRootImpl implements ViewParent,
boolean insetsPending = false;
int relayoutResult = 0;
+ final int surfaceGenerationId = mSurface.getGenerationId();
+
final boolean isViewVisible = viewVisibility == View.VISIBLE;
if (mFirst || windowShouldResize || insetsChanged ||
viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
@@ -1689,7 +1719,6 @@ public final class ViewRootImpl implements ViewParent,
}
mChoreographer.mFrameInfo.addFlags(FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED);
}
- final int surfaceGenerationId = mSurface.getGenerationId();
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
if (DEBUG_LAYOUT) Log.v(mTag, "relayout: frame=" + frame.toShortString()
@@ -1883,7 +1912,7 @@ public final class ViewRootImpl implements ViewParent,
mSurfaceHolder.setSurfaceFrameSize(mWidth, mHeight);
mSurfaceHolder.mSurfaceLock.unlock();
if (mSurface.isValid()) {
- if (!hadSurface) {
+ if (!hadSurface || surfaceGenerationId != mSurface.getGenerationId()) {
mSurfaceHolder.ungetCallbacks();
mIsCreating = true;