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/utils/Flattenable.h b/include/utils/Flattenable.h
index 852be3b..e40d289 100644
--- a/include/utils/Flattenable.h
+++ b/include/utils/Flattenable.h
@@ -24,6 +24,11 @@
 
 namespace android {
 
+/*
+ * The Flattenable interface allows an object to serialize itself out
+ * to a byte-buffer and an array of file descriptors.
+ */
+
 class Flattenable
 {
 public:
@@ -56,6 +61,73 @@
 
 };
 
+/*
+ * LightFlattenable is a protocol allowing object to serialize themselves out
+ * to a byte-buffer.
+ *
+ * LightFlattenable objects must implement this protocol.
+ *
+ * LightFlattenable doesn't require the object to be virtual.
+ */
+template <typename T>
+class LightFlattenable {
+public:
+    // returns whether this object always flatten into the same size.
+    // for efficiency, this should always be inline.
+    inline bool isFixedSize() const;
+
+    // returns size in bytes of the flattened object. must be a constant.
+    inline size_t getSize() const;
+
+    // flattens the object into buffer.
+    inline status_t flatten(void* buffer) const;
+
+    // unflattens the object from buffer of given size.
+    inline status_t unflatten(void const* buffer, size_t size);
+};
+
+template <typename T>
+inline bool LightFlattenable<T>::isFixedSize() const {
+    return static_cast<T const*>(this)->T::isFixedSize();
+}
+template <typename T>
+inline size_t LightFlattenable<T>::getSize() const {
+    return static_cast<T const*>(this)->T::getSize();
+}
+template <typename T>
+inline status_t LightFlattenable<T>::flatten(void* buffer) const {
+    return static_cast<T const*>(this)->T::flatten(buffer);
+}
+template <typename T>
+inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) {
+    return static_cast<T*>(this)->T::unflatten(buffer, size);
+}
+
+/*
+ * LightFlattenablePod is an implementation of the LightFlattenable protocol
+ * for POD (plain-old-data) objects.
+ */
+template <typename T>
+class LightFlattenablePod : public LightFlattenable<T> {
+public:
+    inline bool isFixedSize() const {
+        return true;
+    }
+
+    inline size_t getSize() const {
+        return sizeof(T);
+    }
+    inline status_t flatten(void* buffer) const {
+        *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
+        return NO_ERROR;
+    }
+    inline status_t unflatten(void const* buffer, size_t) {
+        *static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer);
+        return NO_ERROR;
+    }
+};
+
+
 }; // namespace android