improve [un]marshalling of non-binder objects

this change introduces a new class LightFlattenable<> which is
a protocol to flatten simple objects that don't require
binders or file descriptors; the benefit of this protocol is that
it doesn't require the objects to have a virtual table and give us
a consitant way of doing this.

we also introduce an implementation of this protocol for
POD structures, LightFlattenablePod<>.

Parcel has been update to handle this protocol automatically.

Sensor, Rect, Point and Region now use this new protocol.

Change-Id: Icb3ce7fa1d785249eb666f39c2129f2fc143ea4a
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 33b2f00..877b17c 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -22,10 +22,12 @@
 #include <utils/RefBase.h>
 #include <utils/String16.h>
 #include <utils/Vector.h>
+#include <utils/Flattenable.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
 
+template <typename T> class LightFlattenable;
 class Flattenable;
 class IBinder;
 class IPCThreadState;
@@ -102,6 +104,10 @@
     status_t            writeWeakBinder(const wp<IBinder>& val);
     status_t            write(const Flattenable& val);
 
+    template<typename T>
+    status_t            write(const LightFlattenable<T>& val);
+
+
     // Place a native_handle into the parcel (the native_handle's file-
     // descriptors are dup'ed, so it is safe to delete the native_handle
     // when this function returns). 
@@ -153,6 +159,9 @@
     wp<IBinder>         readWeakBinder() const;
     status_t            read(Flattenable& val) const;
 
+    template<typename T>
+    status_t            read(LightFlattenable<T>& val) const;
+
     // Like Parcel.java's readExceptionCode().  Reads the first int32
     // off of a Parcel's header, returning 0 or the negative error
     // code on exceptions, but also deals with skipping over rich
@@ -267,6 +276,40 @@
 
 // ---------------------------------------------------------------------------
 
+template<typename T>
+status_t Parcel::write(const LightFlattenable<T>& val) {
+    size_t size(val.getSize());
+    if (!val.isFixedSize()) {
+        status_t err = writeInt32(size);
+        if (err != NO_ERROR) {
+            return err;
+        }
+    }
+    void* buffer = writeInplace(size);
+    return buffer == NULL ? NO_MEMORY :
+        val.flatten(buffer);
+}
+
+template<typename T>
+status_t Parcel::read(LightFlattenable<T>& val) const {
+    size_t size;
+    if (val.isFixedSize()) {
+        size = val.getSize();
+    } else {
+        int32_t s;
+        status_t err = readInt32(&s);
+        if (err != NO_ERROR) {
+            return err;
+        }
+        size = s;
+    }
+    void const* buffer = readInplace(size);
+    return buffer == NULL ? NO_MEMORY :
+        val.unflatten(buffer, size);
+}
+
+// ---------------------------------------------------------------------------
+
 inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
 {
     parcel.print(to);