Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8683fca3 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

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
parent e57f2925
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -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 @@ public:
    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 @@ public:
    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 @@ public:

// ---------------------------------------------------------------------------

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);
+7 −9
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ class Parcel;

// ----------------------------------------------------------------------------

class Sensor : public ASensor, public Flattenable
class Sensor : public ASensor, public LightFlattenable<Sensor>
{
public:
    enum {
@@ -54,7 +54,7 @@ public:

            Sensor();
            Sensor(struct sensor_t const* hwSensor);
    virtual ~Sensor();
            ~Sensor();

    const String8& getName() const;
    const String8& getVendor() const;
@@ -68,13 +68,11 @@ public:
    nsecs_t getMinDelayNs() const;
    int32_t getVersion() const;

    // Flattenable interface
    virtual size_t getFlattenedSize() const;
    virtual size_t getFdCount() const;
    virtual status_t flatten(void* buffer, size_t size,
            int fds[], size_t count) const;
    virtual status_t unflatten(void const* buffer, size_t size,
            int fds[], size_t count);
    // LightFlattenable protocol
    inline bool isFixedSize() const { return false; }
    size_t getSize() const;
    status_t flatten(void* buffer) const;
    status_t unflatten(void const* buffer, size_t size);

private:
    String8 mName;
+2 −1
Original line number Diff line number Diff line
@@ -17,11 +17,12 @@
#ifndef ANDROID_UI_POINT
#define ANDROID_UI_POINT

#include <utils/Flattenable.h>
#include <utils/TypeHelpers.h>

namespace android {

class Point
class Point : public LightFlattenablePod<Point>
{
public:
    int x;
+2 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef ANDROID_UI_RECT
#define ANDROID_UI_RECT

#include <utils/Flattenable.h>
#include <utils/TypeHelpers.h>
#include <ui/Point.h>

@@ -24,7 +25,7 @@

namespace android {

class Rect : public ARect
class Rect : public ARect, public LightFlattenablePod<Rect>
{
public:
    typedef ARect::value_type value_type;
+6 −8
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <utils/Vector.h>

#include <ui/Rect.h>
#include <utils/Flattenable.h>

namespace android {
// ---------------------------------------------------------------------------
@@ -30,13 +31,12 @@ namespace android {
class String8;

// ---------------------------------------------------------------------------
class Region
class Region : public LightFlattenable<Region>
{
public:
                        Region();
                        Region(const Region& rhs);
    explicit            Region(const Rect& rhs);
    explicit            Region(const void* buffer);
                        ~Region();
                        
        Region& operator = (const Region& rhs);
@@ -122,12 +122,10 @@ public:
            // be sorted in Y and X and must not make the region invalid.
            void        addRectUnchecked(int l, int t, int r, int b);

            // flatten/unflatten a region to/from a raw buffer
            ssize_t     write(void* buffer, size_t size) const;
    static  ssize_t     writeEmpty(void* buffer, size_t size);

            ssize_t     read(const void* buffer);
    static  bool        isEmpty(void* buffer);
    inline  bool        isFixedSize() const { return false; }
            size_t      getSize() const;
            status_t    flatten(void* buffer) const;
            status_t    unflatten(void const* buffer, size_t size);

    void        dump(String8& out, const char* what, uint32_t flags=0) const;
    void        dump(const char* what, uint32_t flags=0) const;
Loading