SurfaceView: Fix Surface leak when changing format.

We simply weren't destroying the old Surface (though the finalizer
would have eventually caught it). As we destroy it we need to use
a Window preservation scheme similar to what the WindowManager
provided.

Bug: 36447956
Test: Manual
Change-Id: I8b4210eb76cec364522cc0a40014517e42ebbe68
(cherry picked from commit 3bc95b5b712c44c687ef04156b63c70c930f69f2)
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index f559d42..e590739 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -114,6 +114,9 @@
     SurfaceSession mSurfaceSession;
 
     SurfaceControl mSurfaceControl;
+    // In the case of format changes we switch out the surface in-place
+    // we need to preserve the old one until the new one has drawn.
+    SurfaceControl mDeferredDestroySurfaceControl;
     final Rect mTmpRect = new Rect();
     final Configuration mConfiguration = new Configuration();
 
@@ -475,6 +478,7 @@
 
                 if (creating) {
                     mSurfaceSession = new SurfaceSession(viewRoot.mSurface);
+                    mDeferredDestroySurfaceControl = mSurfaceControl;
                     mSurfaceControl = new SurfaceControl(mSurfaceSession,
                             "SurfaceView - " + viewRoot.getTitle().toString(),
                             mSurfaceWidth, mSurfaceHeight, mFormat,
@@ -676,6 +680,12 @@
             Log.i(TAG, System.identityHashCode(this) + " "
                     + "finishedDrawing");
         }
+
+        if (mDeferredDestroySurfaceControl != null) {
+            mDeferredDestroySurfaceControl.destroy();
+            mDeferredDestroySurfaceControl = null;
+        }
+
         mHandler.sendEmptyMessage(DRAW_FINISHED_MSG);
     }