Make Flattenable not virtual

Fallout from the Flattenable change, update all its uses.

Additionnaly, fix/tighten size checks when (un)flatten()ing
things.

Removed the assumption by some flattenables (e.g.: Fence)
that the size passed to them would be exact (it can
and will be larger in some cases)

The code in Parcel is a bit complicated so that we don't
have to expose the full implementation (and also to
keep the code smallish).

Change-Id: I0bf1c8aca2a3128491b4f45510bc46667e566dde
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index 464ee86..93ec0ce 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -127,37 +127,49 @@
 }
 
 size_t Fence::getFlattenedSize() const {
-    return 0;
+    return 1;
 }
 
 size_t Fence::getFdCount() const {
     return isValid() ? 1 : 0;
 }
 
-status_t Fence::flatten(void* buffer, size_t size, int fds[],
-        size_t count) const {
-    if (size != getFlattenedSize() || count != getFdCount()) {
-        return BAD_VALUE;
+status_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
+    if (size < getFlattenedSize() || count < getFdCount()) {
+        return NO_MEMORY;
     }
-
+    FlattenableUtils::write(buffer, size, getFdCount());
     if (isValid()) {
-        fds[0] = mFenceFd;
+        *fds++ = mFenceFd;
+        count--;
     }
     return NO_ERROR;
 }
 
-status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
-        size_t count) {
-    if (size != 0 || (count != 0 && count != 1)) {
-        return BAD_VALUE;
-    }
+status_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) {
     if (mFenceFd != -1) {
         // Don't unflatten if we already have a valid fd.
         return INVALID_OPERATION;
     }
 
-    if (count == 1) {
-        mFenceFd = fds[0];
+    if (size < 1) {
+        return NO_MEMORY;
+    }
+
+    size_t numFds;
+    FlattenableUtils::read(buffer, size, numFds);
+
+    if (numFds > 1) {
+        return BAD_VALUE;
+    }
+
+    if (count < numFds) {
+        return NO_MEMORY;
+    }
+
+    if (numFds) {
+        mFenceFd = *fds++;
+        count--;
     }
 
     return NO_ERROR;
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 580788d..1f273e2 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -209,9 +209,7 @@
     return handle ? handle->numFds : 0;
 }
 
-status_t GraphicBuffer::flatten(void* buffer, size_t size,
-        int fds[], size_t count) const
-{
+status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
     size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
     if (size < sizeNeeded) return NO_MEMORY;
 
@@ -236,12 +234,16 @@
         memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
     }
 
+    buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded);
+    size -= sizeNeeded;
+    fds += handle->numFds;
+    count -= handle->numFds;
+
     return NO_ERROR;
 }
 
-status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
-        int fds[], size_t count)
-{
+status_t GraphicBuffer::unflatten(
+        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
     if (size < 8*sizeof(int)) return NO_MEMORY;
 
     int const* buf = static_cast<int const*>(buffer);
@@ -287,6 +289,11 @@
         }
     }
 
+    buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded);
+    size -= sizeNeeded;
+    fds += numFds;
+    count -= numFds;
+
     return NO_ERROR;
 }
 
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 623f8ed..e5abcf5 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -715,14 +715,17 @@
 
 // ----------------------------------------------------------------------------
 
-size_t Region::getSize() const {
+size_t Region::getFlattenedSize() const {
     return mStorage.size() * sizeof(Rect);
 }
 
-status_t Region::flatten(void* buffer) const {
+status_t Region::flatten(void* buffer, size_t size) const {
 #if VALIDATE_REGIONS
     validate(*this, "Region::flatten");
 #endif
+    if (size < mStorage.size() * sizeof(Rect)) {
+        return NO_MEMORY;
+    }
     Rect* rects = reinterpret_cast<Rect*>(buffer);
     memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
     return NO_ERROR;