Make SurfaceControl parcelable (1/2)

Bug: 69145041
Test: Send SurfaceControl over binder
Change-Id: Ia3780fcb8dc2716f416eaad151aff79ea3f977a9
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 3d01ec2..2e0ad1b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -23,6 +23,8 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.Process;
 import android.os.UserHandle;
 import android.util.Log;
@@ -36,12 +38,14 @@
  * SurfaceControl
  *  @hide
  */
-public class SurfaceControl {
+public class SurfaceControl implements Parcelable {
     private static final String TAG = "SurfaceControl";
 
     private static native long nativeCreate(SurfaceSession session, String name,
             int w, int h, int format, int flags, long parentObject, int windowType, int ownerUid)
             throws OutOfResourcesException;
+    private static native long nativeReadFromParcel(Parcel in);
+    private static native void nativeWriteToParcel(long nativeObject, Parcel out);
     private static native void nativeRelease(long nativeObject);
     private static native void nativeDestroy(long nativeObject);
     private static native void nativeDisconnect(long nativeObject);
@@ -576,6 +580,37 @@
         mCloseGuard.open("release");
     }
 
+    private SurfaceControl(Parcel in) {
+        mName = in.readString();
+        mNativeObject = nativeReadFromParcel(in);
+        if (mNativeObject == 0) {
+            throw new IllegalArgumentException("Couldn't read SurfaceControl from parcel=" + in);
+        }
+        mCloseGuard.open("release");
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mName);
+        nativeWriteToParcel(mNativeObject, dest);
+    }
+
+    public static final Creator<SurfaceControl> CREATOR
+            = new Creator<SurfaceControl>() {
+        public SurfaceControl createFromParcel(Parcel in) {
+            return new SurfaceControl(in);
+        }
+
+        public SurfaceControl[] newArray(int size) {
+            return new SurfaceControl[size];
+        }
+    };
+
     @Override
     protected void finalize() throws Throwable {
         try {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f77e6c4..5e8eece 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -904,11 +904,40 @@
             capabilities.getDesiredMaxAverageLuminance(), capabilities.getDesiredMinLuminance());
 }
 
+static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel == NULL) {
+        doThrowNPE(env);
+        return 0;
+    }
+    sp<SurfaceControl> surface = SurfaceControl::readFromParcel(parcel);
+    if (surface == nullptr) {
+        return 0;
+    }
+    surface->incStrong((void *)nativeCreate);
+    return reinterpret_cast<jlong>(surface.get());
+}
+
+static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
+        jlong nativeObject, jobject parcelObj) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel == NULL) {
+        doThrowNPE(env);
+        return;
+    }
+    SurfaceControl* const self = reinterpret_cast<SurfaceControl *>(nativeObject);
+    self->writeToParcel(parcel);
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod sSurfaceControlMethods[] = {
     {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJII)J",
             (void*)nativeCreate },
+    {"nativeReadFromParcel", "(Landroid/os/Parcel;)J",
+            (void*)nativeReadFromParcel },
+    {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
+            (void*)nativeWriteToParcel },
     {"nativeRelease", "(J)V",
             (void*)nativeRelease },
     {"nativeDestroy", "(J)V",