Merge "Prevent reallocation of Surface object in copyFrom"
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 7fcb2af..d0194f9 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -57,7 +57,8 @@
             throws OutOfResourcesException;
 
     private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
-    private static native long nativeGetFromSurfaceControl(long surfaceControlNativeObject);
+    private static native long nativeGetFromSurfaceControl(long surfaceObject,
+            long surfaceControlNativeObject);
 
     private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
             throws OutOfResourcesException;
@@ -519,9 +520,12 @@
             throw new NullPointerException(
                     "null SurfaceControl native object. Are you using a released SurfaceControl?");
         }
-        long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);
+        long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
 
         synchronized (mLock) {
+            if (newNativeObject == mNativeObject) {
+                return;
+            }
             if (mNativeObject != 0) {
                 nativeRelease(mNativeObject);
             }
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index f9407f4..67a56ae 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -415,18 +415,23 @@
 }
 
 static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
+        jlong nativeObject,
         jlong surfaceControlNativeObj) {
-    /*
-     * This is used by the WindowManagerService just after constructing
-     * a Surface and is necessary for returning the Surface reference to
-     * the caller. At this point, we should only have a SurfaceControl.
-     */
-
+    Surface* self(reinterpret_cast<Surface *>(nativeObject));
     sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
+
+    // If the underlying IGBP's are the same, we don't need to do anything.
+    if (self != nullptr &&
+            IInterface::asBinder(self->getIGraphicBufferProducer()) ==
+            IInterface::asBinder(ctrl->getIGraphicBufferProducer())) {
+        return nativeObject;
+    }
+
     sp<Surface> surface(ctrl->getSurface());
     if (surface != NULL) {
         surface->incStrong(&sRefBaseOwner);
     }
+
     return reinterpret_cast<jlong>(surface.get());
 }
 
@@ -614,7 +619,7 @@
             (void*)nativeAllocateBuffers },
     {"nativeCreateFromSurfaceControl", "(J)J",
             (void*)nativeCreateFromSurfaceControl },
-    {"nativeGetFromSurfaceControl", "(J)J",
+    {"nativeGetFromSurfaceControl", "(JJ)J",
             (void*)nativeGetFromSurfaceControl },
     {"nativeReadFromParcel", "(JLandroid/os/Parcel;)J",
             (void*)nativeReadFromParcel },