GUI: Move Surface.aidl here and implement for native

- Move android/view/Surface.aidl parcelable definition from frameworks/base
- Implement matching native behavior to android.view.Surface parceling,
  to enable use of android.view.Surface in generated native AIDL interfaces

Bug: 25091611
Change-Id: I87ffbb9a19c27a99ce0749d0ca1f17aaa6b3fe74
diff --git a/aidl/gui/android/view/Surface.aidl b/aidl/gui/android/view/Surface.aidl
new file mode 100644
index 0000000..674c163
--- /dev/null
+++ b/aidl/gui/android/view/Surface.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/Surface.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.view;
+
+parcelable Surface cpp_header "gui/Surface.h";
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 3afdaae..9f51cdd 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -23,6 +23,8 @@
 #include <ui/ANativeObjectBase.h>
 #include <ui/Region.h>
 
+#include <binder/Parcelable.h>
+
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
@@ -348,6 +350,43 @@
     bool mSharedBufferHasBeenQueued;
 };
 
+namespace view {
+
+/**
+ * A simple holder for an IGraphicBufferProducer, to match the managed-side
+ * android.view.Surface parcelable behavior.
+ *
+ * This implements android/view/Surface.aidl
+ *
+ * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly
+ * used in managed Binder calls.
+ */
+class Surface : public Parcelable {
+  public:
+
+    String16 name;
+    sp<IGraphicBufferProducer> graphicBufferProducer;
+
+    virtual status_t writeToParcel(Parcel* parcel) const override;
+    virtual status_t readFromParcel(const Parcel* parcel) override;
+
+    // nameAlreadyWritten set to true by Surface.java, because it splits
+    // Parceling itself between managed and native code, so it only wants a part
+    // of the full parceling to happen on its native side.
+    status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;
+
+    // nameAlreadyRead set to true by Surface.java, because it splits
+    // Parceling itself between managed and native code, so it only wants a part
+    // of the full parceling to happen on its native side.
+    status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);
+
+  private:
+
+    static String16 readMaybeEmptyString16(const Parcel* parcel);
+};
+
+} // namespace view
+
 }; // namespace android
 
 #endif  // ANDROID_GUI_SURFACE_H
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index c295684..8025ca5 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1259,4 +1259,57 @@
     return err;
 }
 
+namespace view {
+
+status_t Surface::writeToParcel(Parcel* parcel) const {
+    return writeToParcel(parcel, false);
+}
+
+status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
+    if (parcel == nullptr) return BAD_VALUE;
+
+    status_t res = OK;
+
+    if (!nameAlreadyWritten) res = parcel->writeString16(name);
+
+    if (res == OK) {
+        res = parcel->writeStrongBinder(
+                IGraphicBufferProducer::asBinder(graphicBufferProducer));
+    }
+    return res;
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel) {
+    return readFromParcel(parcel, false);
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
+    if (parcel == nullptr) return BAD_VALUE;
+
+    if (!nameAlreadyRead) {
+        name = readMaybeEmptyString16(parcel);
+    }
+
+    sp<IBinder> binder;
+
+    status_t res = parcel->readStrongBinder(&binder);
+    if (res != OK) return res;
+
+    graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
+
+    return OK;
+}
+
+String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
+    size_t len;
+    const char16_t* str = parcel->readString16Inplace(&len);
+    if (str != nullptr) {
+        return String16(str, len);
+    } else {
+        return String16();
+    }
+}
+
+} // namespace view
+
 }; // namespace android