[gbinder] Close descriptors associated with transactions. Fixes JB#44099
Those are coming as objects of type BINDER_TYPE_FD and the receiving side has to close them.
This commit is contained in:
		@@ -36,54 +36,62 @@
 | 
			
		||||
 | 
			
		||||
#include <gutil_macros.h>
 | 
			
		||||
 | 
			
		||||
struct gbinder_buffer_memory {
 | 
			
		||||
struct gbinder_buffer_contents {
 | 
			
		||||
    gint refcount;
 | 
			
		||||
    void* buffer;
 | 
			
		||||
    gsize size;
 | 
			
		||||
    void** objects;
 | 
			
		||||
    GBinderDriver* driver;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct gbinder_buffer_priv {
 | 
			
		||||
    GBinderBuffer pub;
 | 
			
		||||
    GBinderBufferMemory* memory;
 | 
			
		||||
    GBinderBufferContents* contents;
 | 
			
		||||
} GBinderBufferPriv;
 | 
			
		||||
 | 
			
		||||
static inline GBinderBufferPriv* gbinder_buffer_cast(GBinderBuffer* buf)
 | 
			
		||||
    { return G_CAST(buf, GBinderBufferPriv, pub); }
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * GBinderBufferMemory
 | 
			
		||||
 * GBinderBufferContents
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
GBinderBufferMemory*
 | 
			
		||||
gbinder_buffer_memory_new(
 | 
			
		||||
GBinderBufferContents*
 | 
			
		||||
gbinder_buffer_contents_new(
 | 
			
		||||
    GBinderDriver* driver,
 | 
			
		||||
    void* buffer,
 | 
			
		||||
    gsize size)
 | 
			
		||||
    gsize size,
 | 
			
		||||
    void** objects)
 | 
			
		||||
{
 | 
			
		||||
    GBinderBufferMemory* self = g_slice_new0(GBinderBufferMemory);
 | 
			
		||||
    GBinderBufferContents* self = g_slice_new0(GBinderBufferContents);
 | 
			
		||||
 | 
			
		||||
    g_atomic_int_set(&self->refcount, 1);
 | 
			
		||||
    self->buffer = buffer;
 | 
			
		||||
    self->size = size;
 | 
			
		||||
    self->objects = objects;
 | 
			
		||||
    self->driver = gbinder_driver_ref(driver);
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
gbinder_buffer_memory_free(
 | 
			
		||||
    GBinderBufferMemory* self)
 | 
			
		||||
gbinder_buffer_contents_free(
 | 
			
		||||
    GBinderBufferContents* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self->objects) {
 | 
			
		||||
        gbinder_driver_close_fds(self->driver, self->objects,
 | 
			
		||||
            ((guint8*)self->buffer) + self->size);
 | 
			
		||||
        g_free(self->objects);
 | 
			
		||||
    }
 | 
			
		||||
    gbinder_driver_free_buffer(self->driver, self->buffer);
 | 
			
		||||
    gbinder_driver_unref(self->driver);
 | 
			
		||||
    g_slice_free(GBinderBufferMemory, self);
 | 
			
		||||
    g_slice_free(GBinderBufferContents, self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderBufferMemory*
 | 
			
		||||
gbinder_buffer_memory_ref(
 | 
			
		||||
    GBinderBufferMemory* self)
 | 
			
		||||
GBinderBufferContents*
 | 
			
		||||
gbinder_buffer_contents_ref(
 | 
			
		||||
    GBinderBufferContents* self)
 | 
			
		||||
{
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GASSERT(self->refcount > 0);
 | 
			
		||||
@@ -93,13 +101,13 @@ gbinder_buffer_memory_ref(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_buffer_memory_unref(
 | 
			
		||||
    GBinderBufferMemory* self)
 | 
			
		||||
gbinder_buffer_contents_unref(
 | 
			
		||||
    GBinderBufferContents* self)
 | 
			
		||||
{
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GASSERT(self->refcount > 0);
 | 
			
		||||
        if (g_atomic_int_dec_and_test(&self->refcount)) {
 | 
			
		||||
            gbinder_buffer_memory_free(self);
 | 
			
		||||
            gbinder_buffer_contents_free(self);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -111,14 +119,14 @@ gbinder_buffer_memory_unref(
 | 
			
		||||
static
 | 
			
		||||
GBinderBuffer*
 | 
			
		||||
gbinder_buffer_alloc(
 | 
			
		||||
    GBinderBufferMemory* memory,
 | 
			
		||||
    GBinderBufferContents* contents,
 | 
			
		||||
    void* data,
 | 
			
		||||
    gsize size)
 | 
			
		||||
{
 | 
			
		||||
    GBinderBufferPriv* priv = g_slice_new0(GBinderBufferPriv);
 | 
			
		||||
    GBinderBuffer* self = &priv->pub;
 | 
			
		||||
 | 
			
		||||
    priv->memory = memory;
 | 
			
		||||
    priv->contents = contents;
 | 
			
		||||
    self->data = data;
 | 
			
		||||
    self->size = size;
 | 
			
		||||
    return self;
 | 
			
		||||
@@ -131,7 +139,7 @@ gbinder_buffer_free(
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GBinderBufferPriv* priv = gbinder_buffer_cast(self);
 | 
			
		||||
 | 
			
		||||
        gbinder_buffer_memory_unref(priv->memory);
 | 
			
		||||
        gbinder_buffer_contents_unref(priv->contents);
 | 
			
		||||
        g_slice_free(GBinderBufferPriv, priv);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -140,10 +148,12 @@ GBinderBuffer*
 | 
			
		||||
gbinder_buffer_new(
 | 
			
		||||
    GBinderDriver* driver,
 | 
			
		||||
    void* data,
 | 
			
		||||
    gsize size)
 | 
			
		||||
    gsize size,
 | 
			
		||||
    void** objects)
 | 
			
		||||
{
 | 
			
		||||
    return gbinder_buffer_alloc((driver && data) ?
 | 
			
		||||
        gbinder_buffer_memory_new(driver, data, size) : NULL, data, size);
 | 
			
		||||
        gbinder_buffer_contents_new(driver, data, size, objects) : NULL,
 | 
			
		||||
        data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderBuffer*
 | 
			
		||||
@@ -153,7 +163,7 @@ gbinder_buffer_new_with_parent(
 | 
			
		||||
    gsize size)
 | 
			
		||||
{
 | 
			
		||||
    return gbinder_buffer_alloc(parent ?
 | 
			
		||||
        gbinder_buffer_memory_ref(gbinder_buffer_memory(parent)) : NULL,
 | 
			
		||||
        gbinder_buffer_contents_ref(gbinder_buffer_contents(parent)) : NULL,
 | 
			
		||||
        data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -162,13 +172,13 @@ gbinder_buffer_data(
 | 
			
		||||
    GBinderBuffer* self,
 | 
			
		||||
    gsize* size)
 | 
			
		||||
{
 | 
			
		||||
    GBinderBufferMemory* memory = gbinder_buffer_memory(self);
 | 
			
		||||
    GBinderBufferContents* contents = gbinder_buffer_contents(self);
 | 
			
		||||
 | 
			
		||||
    if (G_LIKELY(memory)) {
 | 
			
		||||
    if (G_LIKELY(contents)) {
 | 
			
		||||
        if (size) {
 | 
			
		||||
            *size = memory->size;
 | 
			
		||||
            *size = contents->size;
 | 
			
		||||
        }
 | 
			
		||||
        return memory->buffer;
 | 
			
		||||
        return contents->buffer;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (size) {
 | 
			
		||||
            *size = 0;
 | 
			
		||||
@@ -184,8 +194,8 @@ gbinder_buffer_driver(
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GBinderBufferPriv* priv = gbinder_buffer_cast(self);
 | 
			
		||||
 | 
			
		||||
        if (priv->memory) {
 | 
			
		||||
            return priv->memory->driver;
 | 
			
		||||
        if (priv->contents) {
 | 
			
		||||
            return priv->contents->driver;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
@@ -200,11 +210,25 @@ gbinder_buffer_io(
 | 
			
		||||
    return driver ? gbinder_driver_io(driver) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderBufferMemory*
 | 
			
		||||
gbinder_buffer_memory(
 | 
			
		||||
void**
 | 
			
		||||
gbinder_buffer_objects(
 | 
			
		||||
    GBinderBuffer* self)
 | 
			
		||||
{
 | 
			
		||||
    return G_LIKELY(self) ? gbinder_buffer_cast(self)->memory : NULL;
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GBinderBufferPriv* priv = gbinder_buffer_cast(self);
 | 
			
		||||
 | 
			
		||||
        if (priv->contents) {
 | 
			
		||||
            return priv->contents->objects;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderBufferContents*
 | 
			
		||||
gbinder_buffer_contents(
 | 
			
		||||
    GBinderBuffer* self)
 | 
			
		||||
{
 | 
			
		||||
    return G_LIKELY(self) ? gbinder_buffer_cast(self)->contents : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,8 @@ GBinderBuffer*
 | 
			
		||||
gbinder_buffer_new(
 | 
			
		||||
    GBinderDriver* driver,
 | 
			
		||||
    void* data,
 | 
			
		||||
    gsize size);
 | 
			
		||||
    gsize size,
 | 
			
		||||
    void** objects);
 | 
			
		||||
 | 
			
		||||
GBinderBuffer*
 | 
			
		||||
gbinder_buffer_new_with_parent(
 | 
			
		||||
@@ -53,8 +54,8 @@ GBinderDriver*
 | 
			
		||||
gbinder_buffer_driver(
 | 
			
		||||
    GBinderBuffer* buf);
 | 
			
		||||
 | 
			
		||||
GBinderBufferMemory*
 | 
			
		||||
gbinder_buffer_memory(
 | 
			
		||||
GBinderBufferContents*
 | 
			
		||||
gbinder_buffer_contents(
 | 
			
		||||
    GBinderBuffer* buf);
 | 
			
		||||
 | 
			
		||||
gconstpointer
 | 
			
		||||
@@ -66,13 +67,17 @@ const GBinderIo*
 | 
			
		||||
gbinder_buffer_io(
 | 
			
		||||
    GBinderBuffer* buf);
 | 
			
		||||
 | 
			
		||||
GBinderBufferMemory*
 | 
			
		||||
gbinder_buffer_memory_ref(
 | 
			
		||||
    GBinderBufferMemory* mem);
 | 
			
		||||
void**
 | 
			
		||||
gbinder_buffer_objects(
 | 
			
		||||
    GBinderBuffer* buffer);
 | 
			
		||||
 | 
			
		||||
GBinderBufferContents*
 | 
			
		||||
gbinder_buffer_contents_ref(
 | 
			
		||||
    GBinderBufferContents* contents);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_buffer_memory_unref(
 | 
			
		||||
    GBinderBufferMemory* mem);
 | 
			
		||||
gbinder_buffer_contents_unref(
 | 
			
		||||
    GBinderBufferContents* contents);
 | 
			
		||||
 | 
			
		||||
#endif /* GBINDER_BUFFER_PRIVATE_H */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -439,11 +439,10 @@ gbinder_driver_handle_transaction(
 | 
			
		||||
    /* Transfer data ownership to the request */
 | 
			
		||||
    if (tx.data && tx.size) {
 | 
			
		||||
        gbinder_driver_verbose_dump(' ', (uintptr_t)tx.data, tx.size);
 | 
			
		||||
        gbinder_remote_request_set_data(req,
 | 
			
		||||
            gbinder_buffer_new(self, tx.data, tx.size),
 | 
			
		||||
            tx.objects);
 | 
			
		||||
        gbinder_remote_request_set_data(req, tx.code,
 | 
			
		||||
            gbinder_buffer_new(self, tx.data, tx.size, tx.objects));
 | 
			
		||||
    } else {
 | 
			
		||||
        g_free(tx.objects);
 | 
			
		||||
        GASSERT(!tx.objects);
 | 
			
		||||
        gbinder_driver_free_buffer(self, tx.data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -637,10 +636,9 @@ gbinder_driver_txstatus(
 | 
			
		||||
            if (tx.data && tx.size) {
 | 
			
		||||
                gbinder_driver_verbose_dump(' ', (uintptr_t)tx.data, tx.size);
 | 
			
		||||
                gbinder_remote_reply_set_data(reply,
 | 
			
		||||
                    gbinder_buffer_new(self, tx.data, tx.size),
 | 
			
		||||
                    tx.objects);
 | 
			
		||||
                    gbinder_buffer_new(self, tx.data, tx.size, tx.objects));
 | 
			
		||||
            } else {
 | 
			
		||||
                g_free(tx.objects);
 | 
			
		||||
                GASSERT(!tx.objects);
 | 
			
		||||
                gbinder_driver_free_buffer(self, tx.data);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -863,6 +861,32 @@ gbinder_driver_release(
 | 
			
		||||
    return gbinder_driver_cmd_int32(self, self->io->bc.release, handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_driver_close_fds(
 | 
			
		||||
    GBinderDriver* self,
 | 
			
		||||
    void** objects,
 | 
			
		||||
    const void* end)
 | 
			
		||||
{
 | 
			
		||||
    const GBinderIo* io = self->io;
 | 
			
		||||
    void** ptr;
 | 
			
		||||
 | 
			
		||||
    /* Caller checks objects for NULL */
 | 
			
		||||
    for (ptr = objects; *ptr; ptr++) {
 | 
			
		||||
        void* obj = *ptr;
 | 
			
		||||
 | 
			
		||||
        GASSERT(obj < end);
 | 
			
		||||
        if (obj < end) {
 | 
			
		||||
            int fd;
 | 
			
		||||
 | 
			
		||||
            if (io->decode_fd_object(obj, (guint8*)end - (guint8*)obj, &fd)) {
 | 
			
		||||
                if (close(fd) < 0) {
 | 
			
		||||
                    GWARN("Error closing fd %d: %s", fd, strerror(errno));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_driver_free_buffer(
 | 
			
		||||
    GBinderDriver* self,
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,12 @@ gbinder_driver_release(
 | 
			
		||||
    GBinderDriver* driver,
 | 
			
		||||
    guint32 handle);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_driver_close_fds(
 | 
			
		||||
    GBinderDriver* self,
 | 
			
		||||
    void** objects,
 | 
			
		||||
    const void* end);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_driver_free_buffer(
 | 
			
		||||
    GBinderDriver* driver,
 | 
			
		||||
 
 | 
			
		||||
@@ -411,6 +411,28 @@ GBINDER_IO_FN(decode_buffer_object)(
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
guint
 | 
			
		||||
GBINDER_IO_FN(decode_fd_object)(
 | 
			
		||||
    const void* data,
 | 
			
		||||
    gsize size,
 | 
			
		||||
    int* fd)
 | 
			
		||||
{
 | 
			
		||||
    const struct flat_binder_object* obj = data;
 | 
			
		||||
 | 
			
		||||
    if (size >= sizeof(*obj)) {
 | 
			
		||||
        switch (obj->hdr.type) {
 | 
			
		||||
        case BINDER_TYPE_FD:
 | 
			
		||||
            if (fd) *fd = obj->handle;
 | 
			
		||||
            return sizeof(*obj);
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (fd) *fd = -1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const GBinderIo GBINDER_IO_PREFIX = {
 | 
			
		||||
    .version = BINDER_CURRENT_PROTOCOL_VERSION,
 | 
			
		||||
    .pointer_size = GBINDER_POINTER_SIZE,
 | 
			
		||||
@@ -478,6 +500,7 @@ const GBinderIo GBINDER_IO_PREFIX = {
 | 
			
		||||
    .decode_binder_ptr_cookie = GBINDER_IO_FN(decode_binder_ptr_cookie),
 | 
			
		||||
    .decode_binder_object = GBINDER_IO_FN(decode_binder_object),
 | 
			
		||||
    .decode_buffer_object = GBINDER_IO_FN(decode_buffer_object),
 | 
			
		||||
    .decode_fd_object = GBINDER_IO_FN(decode_fd_object),
 | 
			
		||||
 | 
			
		||||
    /* ioctl wrappers */
 | 
			
		||||
    .write_read = GBINDER_IO_FN(write_read)
 | 
			
		||||
 
 | 
			
		||||
@@ -167,6 +167,7 @@ struct gbinder_io {
 | 
			
		||||
       GBinderObjectRegistry* reg, GBinderRemoteObject** obj);
 | 
			
		||||
    guint (*decode_buffer_object)(GBinderBuffer* buf, gsize offset,
 | 
			
		||||
        GBinderBuffer** out);
 | 
			
		||||
    guint (*decode_fd_object)(const void* data, gsize size, int* fd);
 | 
			
		||||
 | 
			
		||||
    /* ioctl wrappers */
 | 
			
		||||
    int (*write_read)(int fd, GBinderIoBuf* write, GBinderIoBuf* read);
 | 
			
		||||
 
 | 
			
		||||
@@ -95,14 +95,13 @@ gbinder_local_reply_new(
 | 
			
		||||
 | 
			
		||||
GBinderLocalReply*
 | 
			
		||||
gbinder_local_reply_new_from_data(
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects)
 | 
			
		||||
    GBinderBuffer* buffer)
 | 
			
		||||
{
 | 
			
		||||
    const GBinderIo* io = gbinder_buffer_io(buffer);
 | 
			
		||||
    GBinderLocalReply* self = gbinder_local_reply_new(io);
 | 
			
		||||
 | 
			
		||||
    if (self) {
 | 
			
		||||
        gbinder_writer_data_set_contents(&self->data, buffer, objects);
 | 
			
		||||
        gbinder_writer_data_set_contents(&self->data, buffer);
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -47,8 +47,7 @@ gbinder_local_reply_data(
 | 
			
		||||
 | 
			
		||||
GBinderLocalReply*
 | 
			
		||||
gbinder_local_reply_new_from_data(
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects);
 | 
			
		||||
    GBinderBuffer* buffer);
 | 
			
		||||
 | 
			
		||||
#endif /* GBINDER_LOCAL_REPLY_PRIVATE_H */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -105,14 +105,13 @@ gbinder_local_request_new(
 | 
			
		||||
 | 
			
		||||
GBinderLocalRequest*
 | 
			
		||||
gbinder_local_request_new_from_data(
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects)
 | 
			
		||||
    GBinderBuffer* buffer)
 | 
			
		||||
{
 | 
			
		||||
    GBinderLocalRequest* self = gbinder_local_request_new
 | 
			
		||||
        (gbinder_buffer_io(buffer), NULL);
 | 
			
		||||
 | 
			
		||||
    if (self) {
 | 
			
		||||
        gbinder_writer_data_set_contents(&self->data, buffer, objects);
 | 
			
		||||
        gbinder_writer_data_set_contents(&self->data, buffer);
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -48,8 +48,7 @@ gbinder_local_request_data(
 | 
			
		||||
 | 
			
		||||
GBinderLocalRequest*
 | 
			
		||||
gbinder_local_request_new_from_data(
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects);
 | 
			
		||||
    GBinderBuffer* buffer);
 | 
			
		||||
 | 
			
		||||
#endif /* GBINDER_LOCAL_REQUEST_PRIVATE_H */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
#include "gbinder_local_reply_p.h"
 | 
			
		||||
#include "gbinder_reader_p.h"
 | 
			
		||||
#include "gbinder_object_registry.h"
 | 
			
		||||
#include "gbinder_buffer.h"
 | 
			
		||||
#include "gbinder_buffer_p.h"
 | 
			
		||||
#include "gbinder_log.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_macros.h>
 | 
			
		||||
@@ -65,26 +65,22 @@ gbinder_remote_reply_free(
 | 
			
		||||
 | 
			
		||||
    gbinder_object_registry_unref(data->reg);
 | 
			
		||||
    gbinder_buffer_free(data->buffer);
 | 
			
		||||
    g_free(data->objects);
 | 
			
		||||
    g_slice_free(GBinderRemoteReply, self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_reply_set_data(
 | 
			
		||||
    GBinderRemoteReply* self,
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects)
 | 
			
		||||
    GBinderBuffer* buffer)
 | 
			
		||||
{
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GBinderReaderData* data = &self->data;
 | 
			
		||||
 | 
			
		||||
        g_free(data->objects);
 | 
			
		||||
        gbinder_buffer_free(data->buffer);
 | 
			
		||||
        data->buffer = buffer;
 | 
			
		||||
        data->objects = objects;
 | 
			
		||||
        data->objects = gbinder_buffer_objects(buffer);
 | 
			
		||||
    } else {
 | 
			
		||||
        gbinder_buffer_free(buffer);
 | 
			
		||||
        g_free(objects);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -125,7 +121,7 @@ gbinder_remote_reply_copy_to_local(
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GBinderReaderData* d = &self->data;
 | 
			
		||||
 | 
			
		||||
        return gbinder_local_reply_new_from_data(d->buffer, d->objects);
 | 
			
		||||
        return gbinder_local_reply_new_from_data(d->buffer);
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,9 @@
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the name of Jolla Ltd nor the names of its contributors may
 | 
			
		||||
 *      be used to endorse or promote products derived from this software
 | 
			
		||||
 *      without specific prior written permission.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
@@ -44,8 +44,7 @@ gbinder_remote_reply_new(
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_reply_set_data(
 | 
			
		||||
    GBinderRemoteReply* reply,
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects);
 | 
			
		||||
    GBinderBuffer* buffer);
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
gbinder_remote_reply_is_empty(
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
#include "gbinder_rpc_protocol.h"
 | 
			
		||||
#include "gbinder_local_request_p.h"
 | 
			
		||||
#include "gbinder_object_registry.h"
 | 
			
		||||
#include "gbinder_buffer.h"
 | 
			
		||||
#include "gbinder_buffer_p.h"
 | 
			
		||||
#include "gbinder_log.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_macros.h>
 | 
			
		||||
@@ -76,7 +76,7 @@ gbinder_remote_request_copy_to_local(
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GBinderReaderData* d = &self->data;
 | 
			
		||||
 | 
			
		||||
        return gbinder_local_request_new_from_data(d->buffer, d->objects);
 | 
			
		||||
        return gbinder_local_request_new_from_data(d->buffer);
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -90,7 +90,6 @@ gbinder_remote_request_free(
 | 
			
		||||
 | 
			
		||||
    gbinder_object_registry_unref(data->reg);
 | 
			
		||||
    gbinder_buffer_free(data->buffer);
 | 
			
		||||
    g_free(data->objects);
 | 
			
		||||
    g_free(self->iface2);
 | 
			
		||||
    g_slice_free(GBinderRemoteRequest, self);
 | 
			
		||||
}
 | 
			
		||||
@@ -117,27 +116,30 @@ gbinder_remote_request_init_reader2(
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_request_set_data(
 | 
			
		||||
    GBinderRemoteRequest* self,
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects)
 | 
			
		||||
    guint32 txcode,
 | 
			
		||||
    GBinderBuffer* buffer)
 | 
			
		||||
{
 | 
			
		||||
    if (G_LIKELY(self)) {
 | 
			
		||||
        GBinderReaderData* data = &self->data;
 | 
			
		||||
        GBinderReader reader;
 | 
			
		||||
 | 
			
		||||
        g_free(self->iface2);
 | 
			
		||||
        g_free(data->objects);
 | 
			
		||||
        gbinder_buffer_free(data->buffer);
 | 
			
		||||
        data->buffer = buffer;
 | 
			
		||||
        data->objects = objects;
 | 
			
		||||
        data->objects = gbinder_buffer_objects(buffer);
 | 
			
		||||
 | 
			
		||||
        /* Parse RPC header */
 | 
			
		||||
        self->header_size = 0;
 | 
			
		||||
        gbinder_remote_request_init_reader2(self, &reader);
 | 
			
		||||
        self->iface = self->protocol->read_rpc_header(&reader, &self->iface2);
 | 
			
		||||
        self->header_size = gbinder_reader_bytes_read(&reader);
 | 
			
		||||
        self->iface = self->protocol->read_rpc_header(&reader, txcode,
 | 
			
		||||
            &self->iface2);
 | 
			
		||||
        if (self->iface) {
 | 
			
		||||
            self->header_size = gbinder_reader_bytes_read(&reader);
 | 
			
		||||
        } else {
 | 
			
		||||
            /* No RPC header */
 | 
			
		||||
            self->header_size = 0;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        gbinder_buffer_free(buffer);
 | 
			
		||||
        g_free(objects);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,9 @@
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the name of Jolla Ltd nor the names of its contributors may
 | 
			
		||||
 *      be used to endorse or promote products derived from this software
 | 
			
		||||
 *      without specific prior written permission.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
@@ -47,8 +47,8 @@ gbinder_remote_request_new(
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_request_set_data(
 | 
			
		||||
    GBinderRemoteRequest* request,
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects);
 | 
			
		||||
    guint txcode,
 | 
			
		||||
    GBinderBuffer* buffer);
 | 
			
		||||
 | 
			
		||||
#endif /* GBINDER_REMOTE_REQUEST_PRIVATE_H */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -69,9 +69,13 @@ static
 | 
			
		||||
const char*
 | 
			
		||||
gbinder_rpc_protocol_binder_read_rpc_header(
 | 
			
		||||
    GBinderReader* reader,
 | 
			
		||||
    guint32 txcode,
 | 
			
		||||
    char** iface)
 | 
			
		||||
{
 | 
			
		||||
    if (gbinder_reader_read_int32(reader, NULL)) {
 | 
			
		||||
    if (txcode > GBINDER_TRANSACTION(0,0,0)) {
 | 
			
		||||
        /* Internal transaction e.g. GBINDER_DUMP_TRANSACTION etc. */
 | 
			
		||||
        *iface = NULL;
 | 
			
		||||
    } else if (gbinder_reader_read_int32(reader, NULL)) {
 | 
			
		||||
        *iface = gbinder_reader_read_string16(reader);
 | 
			
		||||
    } else {
 | 
			
		||||
        *iface = NULL;
 | 
			
		||||
@@ -99,6 +103,7 @@ static
 | 
			
		||||
const char*
 | 
			
		||||
gbinder_rpc_protocol_hwbinder_read_rpc_header(
 | 
			
		||||
    GBinderReader* reader,
 | 
			
		||||
    guint32 txcode,
 | 
			
		||||
    char** iface)
 | 
			
		||||
{
 | 
			
		||||
    *iface = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,8 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct gbinder_rpc_protocol {
 | 
			
		||||
    const char* (*read_rpc_header)(GBinderReader* reader, char** iface);
 | 
			
		||||
    const char* (*read_rpc_header)(GBinderReader* reader, guint32 txcode,
 | 
			
		||||
        char** iface);
 | 
			
		||||
    void (*write_rpc_header)(GBinderWriter* writer, const char* iface);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
 | 
			
		||||
#include <gbinder_types.h>
 | 
			
		||||
 | 
			
		||||
typedef struct gbinder_buffer_memory GBinderBufferMemory;
 | 
			
		||||
typedef struct gbinder_buffer_contents GBinderBufferContents;
 | 
			
		||||
typedef struct gbinder_cleanup GBinderCleanup;
 | 
			
		||||
typedef struct gbinder_driver GBinderDriver;
 | 
			
		||||
typedef struct gbinder_handler GBinderHandler;
 | 
			
		||||
 
 | 
			
		||||
@@ -54,22 +54,21 @@ GBINDER_INLINE_FUNC GBinderWriterData* gbinder_writer_data(GBinderWriter* pub)
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_data_memory_cleanup(
 | 
			
		||||
    gpointer memory)
 | 
			
		||||
gbinder_writer_data_buffer_cleanup(
 | 
			
		||||
    gpointer data)
 | 
			
		||||
{
 | 
			
		||||
    gbinder_buffer_memory_unref(memory);
 | 
			
		||||
    gbinder_buffer_contents_unref((GBinderBufferContents*)data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_data_set_contents(
 | 
			
		||||
    GBinderWriterData* data,
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects)
 | 
			
		||||
    GBinderBuffer* buffer)
 | 
			
		||||
{
 | 
			
		||||
    gsize bufsize;
 | 
			
		||||
    const guint8* bufdata = gbinder_buffer_data(buffer, &bufsize);
 | 
			
		||||
    const GBinderIo* io = gbinder_buffer_io(buffer);
 | 
			
		||||
    GBinderBufferMemory* mem = gbinder_buffer_memory(buffer);
 | 
			
		||||
    GBinderBufferContents* contents = gbinder_buffer_contents(buffer);
 | 
			
		||||
 | 
			
		||||
    GASSERT(data->io == io);
 | 
			
		||||
    g_byte_array_set_size(data->bytes, 0);
 | 
			
		||||
@@ -77,24 +76,26 @@ gbinder_writer_data_set_contents(
 | 
			
		||||
    data->buffers_size = 0;
 | 
			
		||||
 | 
			
		||||
    g_byte_array_append(data->bytes, bufdata, bufsize);
 | 
			
		||||
    if (mem) {
 | 
			
		||||
        data->cleanup = gbinder_cleanup_add(data->cleanup,
 | 
			
		||||
            gbinder_writer_data_memory_cleanup,
 | 
			
		||||
            gbinder_buffer_memory_ref(mem));
 | 
			
		||||
    }
 | 
			
		||||
    if (objects && *objects) {
 | 
			
		||||
        if (!data->offsets) {
 | 
			
		||||
            data->offsets = gutil_int_array_new();
 | 
			
		||||
        }
 | 
			
		||||
        while (*objects) {
 | 
			
		||||
            const guint8* obj = *objects++;
 | 
			
		||||
            gsize offset = obj - bufdata;
 | 
			
		||||
            gsize objsize = io->object_data_size(obj);
 | 
			
		||||
    if (contents) {
 | 
			
		||||
        void** objects = gbinder_buffer_objects(buffer);
 | 
			
		||||
 | 
			
		||||
            GASSERT(offset > 0 && offset < bufsize);
 | 
			
		||||
            gutil_int_array_append(data->offsets, (int)offset);
 | 
			
		||||
            /* Size of each buffer has to be 8-byte aligned */
 | 
			
		||||
            data->buffers_size += G_ALIGN8(objsize);
 | 
			
		||||
        data->cleanup = gbinder_cleanup_add(data->cleanup,
 | 
			
		||||
            gbinder_writer_data_buffer_cleanup,
 | 
			
		||||
            gbinder_buffer_contents_ref(contents));
 | 
			
		||||
        if (objects && *objects) {
 | 
			
		||||
            if (!data->offsets) {
 | 
			
		||||
                data->offsets = gutil_int_array_new();
 | 
			
		||||
            }
 | 
			
		||||
            while (*objects) {
 | 
			
		||||
                const guint8* obj = *objects++;
 | 
			
		||||
                gsize offset = obj - bufdata;
 | 
			
		||||
                gsize objsize = io->object_data_size(obj);
 | 
			
		||||
 | 
			
		||||
                GASSERT(offset > 0 && offset < bufsize);
 | 
			
		||||
                gutil_int_array_append(data->offsets, (int)offset);
 | 
			
		||||
                /* Size of each buffer has to be 8-byte aligned */
 | 
			
		||||
                data->buffers_size += G_ALIGN8(objsize);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -53,8 +53,7 @@ gbinder_writer_init(
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_data_set_contents(
 | 
			
		||||
    GBinderWriterData* data,
 | 
			
		||||
    GBinderBuffer* buffer,
 | 
			
		||||
    void** objects);
 | 
			
		||||
    GBinderBuffer* buffer);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_data_append_bool(
 | 
			
		||||
 
 | 
			
		||||
@@ -47,19 +47,21 @@ test_null(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(NULL, NULL, 0);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(NULL, NULL, 0, NULL);
 | 
			
		||||
    GBinderBuffer* buf2;
 | 
			
		||||
    gsize size = 1;
 | 
			
		||||
 | 
			
		||||
    gbinder_buffer_free(buf);
 | 
			
		||||
 | 
			
		||||
    /* No need to reference the driver if there's no data */
 | 
			
		||||
    buf = gbinder_buffer_new(driver, NULL, 0);
 | 
			
		||||
    buf = gbinder_buffer_new(driver, NULL, 0, NULL);
 | 
			
		||||
    g_assert(!gbinder_buffer_driver(buf));
 | 
			
		||||
    gbinder_buffer_free(buf);
 | 
			
		||||
 | 
			
		||||
    buf = gbinder_buffer_new_with_parent(NULL, NULL, 0);
 | 
			
		||||
    buf2 = gbinder_buffer_new_with_parent(buf, NULL, 0);
 | 
			
		||||
    g_assert(!gbinder_buffer_objects(buf));
 | 
			
		||||
    g_assert(!gbinder_buffer_objects(buf2));
 | 
			
		||||
    g_assert(!gbinder_buffer_driver(buf));
 | 
			
		||||
    g_assert(!gbinder_buffer_driver(buf2));
 | 
			
		||||
    gbinder_buffer_free(buf);
 | 
			
		||||
@@ -67,6 +69,7 @@ test_null(
 | 
			
		||||
 | 
			
		||||
    gbinder_buffer_free(NULL);
 | 
			
		||||
    g_assert(!gbinder_buffer_driver(NULL));
 | 
			
		||||
    g_assert(!gbinder_buffer_objects(NULL));
 | 
			
		||||
    g_assert(!gbinder_buffer_io(NULL));
 | 
			
		||||
    g_assert(!gbinder_buffer_data(NULL, NULL));
 | 
			
		||||
    g_assert(!gbinder_buffer_data(NULL, &size));
 | 
			
		||||
@@ -87,14 +90,14 @@ test_parent(
 | 
			
		||||
    void* ptr = g_memdup(data, sizeof(data));
 | 
			
		||||
    gsize size = 0;
 | 
			
		||||
    GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
 | 
			
		||||
    GBinderBuffer* parent = gbinder_buffer_new(driver, ptr, sizeof(data));
 | 
			
		||||
    GBinderBuffer* parent = gbinder_buffer_new(driver, ptr, sizeof(data), NULL);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new_with_parent
 | 
			
		||||
        (parent, ptr, sizeof(data));
 | 
			
		||||
 | 
			
		||||
    g_assert(gbinder_buffer_driver(buf) == driver);
 | 
			
		||||
    g_assert(gbinder_buffer_io(buf));
 | 
			
		||||
    g_assert(gbinder_buffer_io(buf) == gbinder_driver_io(driver));
 | 
			
		||||
    g_assert(gbinder_buffer_memory(buf));
 | 
			
		||||
    g_assert(gbinder_buffer_contents(buf));
 | 
			
		||||
    g_assert(gbinder_buffer_data(buf, NULL) == ptr);
 | 
			
		||||
    g_assert(gbinder_buffer_data(buf, &size) == ptr);
 | 
			
		||||
    g_assert(size == sizeof(data));
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,8 @@ test_reader_data_init_for_reply(
 | 
			
		||||
    GUtilIntArray* offsets = gbinder_output_data_offsets(out);
 | 
			
		||||
    GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(out->bytes->data, out->bytes->len), out->bytes->len);
 | 
			
		||||
        g_memdup(out->bytes->data, out->bytes->len),
 | 
			
		||||
        out->bytes->len, NULL);
 | 
			
		||||
 | 
			
		||||
    memset(data, 0, sizeof(*data));
 | 
			
		||||
    data->buffer = buf;
 | 
			
		||||
@@ -206,8 +207,9 @@ test_ping(
 | 
			
		||||
        gbinder_ipc_new_local_object(ipc, NULL, NULL, NULL);
 | 
			
		||||
    GBinderLocalReply* reply;
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(req_data, sizeof(req_data)), sizeof(req_data)), NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, HIDL_PING_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(ipc->driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), base_interface));
 | 
			
		||||
    g_assert(gbinder_local_object_can_handle_transaction(obj, base_interface,
 | 
			
		||||
        HIDL_PING_TRANSACTION) == GBINDER_LOCAL_TRANSACTION_LOOPER);
 | 
			
		||||
@@ -248,8 +250,9 @@ test_get_descriptor(
 | 
			
		||||
        gbinder_ipc_new_local_object(ipc, NULL, NULL, NULL);
 | 
			
		||||
    GBinderLocalReply* reply;
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(req_data, sizeof(req_data)), sizeof(req_data)), NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, HIDL_PING_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(ipc->driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), base_interface));
 | 
			
		||||
    g_assert(gbinder_local_object_can_handle_transaction(obj, base_interface,
 | 
			
		||||
        HIDL_GET_DESCRIPTOR_TRANSACTION) == GBINDER_LOCAL_TRANSACTION_LOOPER);
 | 
			
		||||
@@ -303,8 +306,9 @@ test_descriptor_chain(
 | 
			
		||||
        gbinder_ipc_new_local_object(ipc, NULL, NULL, NULL);
 | 
			
		||||
    GBinderLocalReply* reply;
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(req_data, sizeof(req_data)), sizeof(req_data)), NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, HIDL_PING_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(ipc->driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), base_interface));
 | 
			
		||||
    g_assert(gbinder_local_object_can_handle_transaction(obj, base_interface,
 | 
			
		||||
        HIDL_DESCRIPTOR_CHAIN_TRANSACTION) == GBINDER_LOCAL_TRANSACTION_LOOPER);
 | 
			
		||||
@@ -374,8 +378,9 @@ test_custom_iface(
 | 
			
		||||
    char** strv;
 | 
			
		||||
    char* str;
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(req_data, sizeof(req_data)), sizeof(req_data)), NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, HIDL_PING_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(ipc->driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
    g_assert(gbinder_local_object_can_handle_transaction(obj, base_interface,
 | 
			
		||||
        HIDL_DESCRIPTOR_CHAIN_TRANSACTION) == GBINDER_LOCAL_TRANSACTION_LOOPER);
 | 
			
		||||
    g_assert(gbinder_local_object_can_handle_transaction(obj, custom_iface,
 | 
			
		||||
@@ -474,8 +479,9 @@ test_reply_status(
 | 
			
		||||
    GBinderLocalObject* obj = gbinder_ipc_new_local_object(ipc, custom_iface,
 | 
			
		||||
        test_reply_status_handler, &count);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(req_data, sizeof(req_data)), sizeof(req_data)), NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, HIDL_PING_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(ipc->driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
 | 
			
		||||
    /* Execute the custom transaction */
 | 
			
		||||
    g_assert(!gbinder_local_object_handle_transaction(obj, req,
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,7 @@ test_buffer_from_bytes(
 | 
			
		||||
{
 | 
			
		||||
    /* Prevent double free */
 | 
			
		||||
    test_binder_set_destroy(gbinder_driver_fd(driver), bytes->data, NULL);
 | 
			
		||||
    return gbinder_buffer_new(driver, bytes->data, bytes->len);
 | 
			
		||||
    return gbinder_buffer_new(driver, bytes->data, bytes->len, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -88,7 +88,7 @@ test_null(
 | 
			
		||||
    gbinder_local_reply_init_writer(NULL, NULL);
 | 
			
		||||
    gbinder_local_reply_init_writer(NULL, &writer);
 | 
			
		||||
    g_assert(!gbinder_local_reply_data(NULL));
 | 
			
		||||
    g_assert(!gbinder_local_reply_new_from_data(NULL, NULL));
 | 
			
		||||
    g_assert(!gbinder_local_reply_new_from_data(NULL));
 | 
			
		||||
 | 
			
		||||
    gbinder_local_reply_cleanup(NULL, NULL, &count);
 | 
			
		||||
    gbinder_local_reply_cleanup(NULL, test_int_inc, &count);
 | 
			
		||||
@@ -479,7 +479,7 @@ test_remote_reply(
 | 
			
		||||
 | 
			
		||||
    /* Copy flat structures (no binder objects) */
 | 
			
		||||
    buffer = test_buffer_from_bytes(driver, bytes);
 | 
			
		||||
    req2 = gbinder_local_reply_new_from_data(buffer, NULL);
 | 
			
		||||
    req2 = gbinder_local_reply_new_from_data(buffer);
 | 
			
		||||
    gbinder_buffer_free(buffer);
 | 
			
		||||
 | 
			
		||||
    data2 = gbinder_local_reply_data(req2);
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,19 @@ test_buffer_from_bytes(
 | 
			
		||||
{
 | 
			
		||||
    /* Prevent double free */
 | 
			
		||||
    test_binder_set_destroy(gbinder_driver_fd(driver), bytes->data, NULL);
 | 
			
		||||
    return gbinder_buffer_new(driver, bytes->data, bytes->len);
 | 
			
		||||
    return gbinder_buffer_new(driver, bytes->data, bytes->len, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
GBinderBuffer*
 | 
			
		||||
test_buffer_from_bytes_and_objects(
 | 
			
		||||
    GBinderDriver* driver,
 | 
			
		||||
    const GByteArray* bytes,
 | 
			
		||||
    void** objects)
 | 
			
		||||
{
 | 
			
		||||
    /* Prevent double free */
 | 
			
		||||
    test_binder_set_destroy(gbinder_driver_fd(driver), bytes->data, NULL);
 | 
			
		||||
    return gbinder_buffer_new(driver, bytes->data, bytes->len, objects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -82,7 +94,7 @@ test_null(
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_local_request_new(NULL, NULL));
 | 
			
		||||
    g_assert(!gbinder_local_request_ref(NULL));
 | 
			
		||||
    g_assert(!gbinder_local_request_new_from_data(NULL, NULL));
 | 
			
		||||
    g_assert(!gbinder_local_request_new_from_data(NULL));
 | 
			
		||||
    gbinder_local_request_unref(NULL);
 | 
			
		||||
    gbinder_local_request_init_writer(NULL, NULL);
 | 
			
		||||
    gbinder_local_request_init_writer(NULL, &writer);
 | 
			
		||||
@@ -471,14 +483,14 @@ test_remote_request(
 | 
			
		||||
    const GByteArray* bytes;
 | 
			
		||||
    const GByteArray* bytes2;
 | 
			
		||||
    GBinderBuffer* buffer;
 | 
			
		||||
    void* no_obj = NULL;
 | 
			
		||||
    void** no_obj = g_new0(void*, 1);
 | 
			
		||||
 | 
			
		||||
    gbinder_local_request_append_string8(req, input);
 | 
			
		||||
    bytes = gbinder_local_request_data(req)->bytes;
 | 
			
		||||
 | 
			
		||||
    /* Copy flat structures (no binder objects) */
 | 
			
		||||
    buffer = test_buffer_from_bytes(driver, bytes);
 | 
			
		||||
    req2 = gbinder_local_request_new_from_data(buffer, NULL);
 | 
			
		||||
    req2 = gbinder_local_request_new_from_data(buffer);
 | 
			
		||||
    gbinder_buffer_free(buffer);
 | 
			
		||||
 | 
			
		||||
    data2 = gbinder_local_request_data(req2);
 | 
			
		||||
@@ -490,8 +502,8 @@ test_remote_request(
 | 
			
		||||
    gbinder_local_request_unref(req2);
 | 
			
		||||
 | 
			
		||||
    /* Same thing but with non-NULL (albeit empty) array of objects */
 | 
			
		||||
    buffer = test_buffer_from_bytes(driver, bytes);
 | 
			
		||||
    req2 = gbinder_local_request_new_from_data(buffer, &no_obj);
 | 
			
		||||
    buffer = test_buffer_from_bytes_and_objects(driver, bytes, no_obj);
 | 
			
		||||
    req2 = gbinder_local_request_new_from_data(buffer);
 | 
			
		||||
    gbinder_buffer_free(buffer);
 | 
			
		||||
 | 
			
		||||
    data2 = gbinder_local_request_data(req2);
 | 
			
		||||
@@ -559,15 +571,15 @@ test_remote_request_obj(
 | 
			
		||||
        objects[i] = bytes->data + offsets->data[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buffer = test_buffer_from_bytes(driver, data->bytes);
 | 
			
		||||
    req2 = gbinder_local_request_new_from_data(buffer, objects);
 | 
			
		||||
    buffer = test_buffer_from_bytes_and_objects(driver, data->bytes, objects);
 | 
			
		||||
    req2 = gbinder_local_request_new_from_data(buffer);
 | 
			
		||||
    gbinder_buffer_free(buffer);
 | 
			
		||||
    g_free(objects);
 | 
			
		||||
 | 
			
		||||
    test_remote_request_obj_validate_data(gbinder_local_request_data(req2));
 | 
			
		||||
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
    /* req2 has to be freed first because req owns data */
 | 
			
		||||
    gbinder_local_request_unref(req2);
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
    gbinder_driver_unref(driver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -91,22 +91,44 @@ test_device(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * no_header
 | 
			
		||||
 * no_header1
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_no_header(
 | 
			
		||||
test_no_header1(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    GBinderRemoteRequest* req = gbinder_remote_request_new(NULL,
 | 
			
		||||
        gbinder_rpc_protocol_for_device(GBINDER_DEFAULT_BINDER), 0, 0);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, NULL, NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_FIRST_CALL_TRANSACTION, NULL);
 | 
			
		||||
    g_assert(!gbinder_remote_request_interface(req));
 | 
			
		||||
    gbinder_remote_request_unref(req);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * no_header2
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_no_header2(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    const GBinderRpcProtocol* p = &gbinder_rpc_protocol_binder;
 | 
			
		||||
    GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, p);
 | 
			
		||||
    GBinderRemoteRequest* req = gbinder_remote_request_new(NULL, p, 0, 0);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_DUMP_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(TEST_ARRAY_AND_SIZE(test_header_binder)),
 | 
			
		||||
        sizeof(test_header_binder), NULL));
 | 
			
		||||
    g_assert(!gbinder_remote_request_interface(req));
 | 
			
		||||
    gbinder_remote_request_unref(req);
 | 
			
		||||
    gbinder_driver_unref(driver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * write_header
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
@@ -144,38 +166,39 @@ test_read_header(
 | 
			
		||||
    GBinderRemoteRequest* req = gbinder_remote_request_new(NULL,
 | 
			
		||||
        gbinder_rpc_protocol_for_device(test->dev), 0, 0);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(test->header, test->header_size), test->header_size), NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_FIRST_CALL_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(driver, g_memdup(test->header, test->header_size),
 | 
			
		||||
        test->header_size, NULL));
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), test->iface));
 | 
			
		||||
    gbinder_remote_request_unref(req);
 | 
			
		||||
    gbinder_driver_unref(driver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 /*==========================================================================*
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Common
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
#define TEST_PREFIX "/protocol/"
 | 
			
		||||
#define TEST_(t) TEST_PREFIX t
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    guint i;
 | 
			
		||||
 | 
			
		||||
    g_test_init(&argc, &argv, NULL);
 | 
			
		||||
    g_test_add_func(TEST_PREFIX "device", test_device);
 | 
			
		||||
    g_test_add_func(TEST_PREFIX "no_header", test_no_header);
 | 
			
		||||
    g_test_add_func(TEST_("device"), test_device);
 | 
			
		||||
    g_test_add_func(TEST_("no_header1"), test_no_header1);
 | 
			
		||||
    g_test_add_func(TEST_("no_header2"), test_no_header2);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(test_header_tests); i++) {
 | 
			
		||||
        const TestHeaderData* test = test_header_tests + i;
 | 
			
		||||
        char* path = g_strconcat(TEST_PREFIX, "/", test->name,
 | 
			
		||||
            "/read_header", NULL);
 | 
			
		||||
        char* path;
 | 
			
		||||
 | 
			
		||||
        path = g_strconcat(TEST_PREFIX, test->name, "/read_header", NULL);
 | 
			
		||||
        g_test_add_data_func(path, test, test_read_header);
 | 
			
		||||
        g_free(path);
 | 
			
		||||
 | 
			
		||||
        path = g_strconcat(TEST_PREFIX, "/", test->name,
 | 
			
		||||
            "/write_header", NULL);
 | 
			
		||||
 | 
			
		||||
        path = g_strconcat(TEST_PREFIX, test->name, "/write_header", NULL);
 | 
			
		||||
        g_test_add_data_func(path, test, test_write_header);
 | 
			
		||||
        g_free(path);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,7 @@ test_byte(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, g_memdup(&in, sizeof(in)),
 | 
			
		||||
        sizeof(in));
 | 
			
		||||
        sizeof(in), NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, sizeof(in));
 | 
			
		||||
    g_assert(gbinder_reader_read_byte(&reader, &out));
 | 
			
		||||
@@ -155,7 +155,7 @@ test_bool(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(&in_true, sizeof(in_true)), sizeof(in_true));
 | 
			
		||||
        g_memdup(&in_true, sizeof(in_true)), sizeof(in_true), NULL);
 | 
			
		||||
 | 
			
		||||
    /* true */
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, data.buffer->size);
 | 
			
		||||
@@ -170,7 +170,7 @@ test_bool(
 | 
			
		||||
    /* false */
 | 
			
		||||
    gbinder_buffer_free(data.buffer);
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(&in_false, sizeof(in_false)), sizeof(in_false));
 | 
			
		||||
        g_memdup(&in_false, sizeof(in_false)), sizeof(in_false), NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, data.buffer->size);
 | 
			
		||||
    g_assert(gbinder_reader_read_bool(&reader, NULL));
 | 
			
		||||
@@ -204,7 +204,7 @@ test_int32(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, g_memdup(&in, sizeof(in)),
 | 
			
		||||
        sizeof(in));
 | 
			
		||||
        sizeof(in), NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, sizeof(in));
 | 
			
		||||
    g_assert(gbinder_reader_read_uint32(&reader, &out1));
 | 
			
		||||
@@ -243,7 +243,7 @@ test_int64(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, g_memdup(&in, sizeof(in)),
 | 
			
		||||
        sizeof(in));
 | 
			
		||||
        sizeof(in), NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, sizeof(in));
 | 
			
		||||
    g_assert(gbinder_reader_read_uint64(&reader, &out1));
 | 
			
		||||
@@ -282,7 +282,7 @@ test_float(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, g_memdup(&in, sizeof(in)),
 | 
			
		||||
        sizeof(in));
 | 
			
		||||
        sizeof(in), NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, sizeof(in));
 | 
			
		||||
    g_assert(gbinder_reader_read_float(&reader, &out1));
 | 
			
		||||
@@ -321,7 +321,7 @@ test_double(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, g_memdup(&in, sizeof(in)),
 | 
			
		||||
        sizeof(in));
 | 
			
		||||
        sizeof(in), NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, sizeof(in));
 | 
			
		||||
    g_assert(gbinder_reader_read_double(&reader, &out1));
 | 
			
		||||
@@ -386,7 +386,7 @@ test_string8(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, g_memdup(test->in, test->in_size),
 | 
			
		||||
        test->in_size);
 | 
			
		||||
        test->in_size, NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, test->in_size);
 | 
			
		||||
    str = gbinder_reader_read_string8(&reader);
 | 
			
		||||
@@ -454,7 +454,7 @@ test_string16_null(
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(TEST_ARRAY_AND_SIZE(test_string16_in_null)),
 | 
			
		||||
        sizeof(test_string16_in_null));
 | 
			
		||||
        sizeof(test_string16_in_null), NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, sizeof(test_string16_in_null));
 | 
			
		||||
    g_assert(gbinder_reader_read_nullable_string16_utf16(&reader, NULL, NULL));
 | 
			
		||||
@@ -504,7 +504,7 @@ test_string16(
 | 
			
		||||
    g_assert(driver);
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, g_memdup(test->in, test->in_size),
 | 
			
		||||
        test->in_size);
 | 
			
		||||
        test->in_size, NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, test->in_size);
 | 
			
		||||
    g_assert(gbinder_reader_read_nullable_string16_utf16(&reader, NULL,
 | 
			
		||||
@@ -596,7 +596,7 @@ test_hidl_struct(
 | 
			
		||||
    const TestHidlStruct* test = test_data;
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(test->in, test->in_size), test->in_size);
 | 
			
		||||
        g_memdup(test->in, test->in_size), test->in_size, NULL);
 | 
			
		||||
    GBinderReaderData data;
 | 
			
		||||
    GBinderReader reader;
 | 
			
		||||
 | 
			
		||||
@@ -801,7 +801,7 @@ test_hidl_vec(
 | 
			
		||||
    const TestHidlVec* test = test_data;
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(test->in, test->in_size), test->in_size);
 | 
			
		||||
        g_memdup(test->in, test->in_size), test->in_size, NULL);
 | 
			
		||||
    GBinderReaderData data;
 | 
			
		||||
    GBinderReader reader;
 | 
			
		||||
    gsize n = 0, elem = 0;
 | 
			
		||||
@@ -907,7 +907,7 @@ test_hidl_string_err(
 | 
			
		||||
    const TestHidlStringErr* test = test_data;
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(test->in, test->in_size), test->in_size);
 | 
			
		||||
        g_memdup(test->in, test->in_size), test->in_size, NULL);
 | 
			
		||||
    GBinderReaderData data;
 | 
			
		||||
    GBinderReader reader;
 | 
			
		||||
 | 
			
		||||
@@ -949,7 +949,7 @@ test_object(
 | 
			
		||||
    };
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(input, sizeof(input)), sizeof(input));
 | 
			
		||||
        g_memdup(input, sizeof(input)), sizeof(input), NULL);
 | 
			
		||||
    GBinderRemoteObject* obj = NULL;
 | 
			
		||||
    GBinderReaderData data;
 | 
			
		||||
    GBinderReader reader;
 | 
			
		||||
@@ -1007,7 +1007,7 @@ test_object_invalid(
 | 
			
		||||
    };
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
 | 
			
		||||
    GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(input, sizeof(input)), sizeof(input));
 | 
			
		||||
        g_memdup(input, sizeof(input)), sizeof(input), NULL);
 | 
			
		||||
    GBinderRemoteObject* obj = NULL;
 | 
			
		||||
    GBinderReaderData data;
 | 
			
		||||
    GBinderReader reader;
 | 
			
		||||
@@ -1056,7 +1056,7 @@ test_vec(
 | 
			
		||||
    /* This one will fail because the buffer is one byte short */
 | 
			
		||||
    obj.length = sizeof(vec) - 1;
 | 
			
		||||
    data.buffer =  gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(&obj, sizeof(obj)), sizeof(obj));
 | 
			
		||||
        g_memdup(&obj, sizeof(obj)), sizeof(obj), NULL);
 | 
			
		||||
    data.reg = gbinder_ipc_object_registry(ipc);
 | 
			
		||||
    data.objects = g_new(void*, 2);
 | 
			
		||||
    data.objects[0] = data.buffer->data;
 | 
			
		||||
@@ -1068,7 +1068,7 @@ test_vec(
 | 
			
		||||
    obj.length = sizeof(vec);
 | 
			
		||||
    gbinder_buffer_free(data.buffer);
 | 
			
		||||
    data.buffer = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        g_memdup(&obj, sizeof(obj)), sizeof(obj));
 | 
			
		||||
        g_memdup(&obj, sizeof(obj)), sizeof(obj), NULL);
 | 
			
		||||
    data.objects[0] = data.buffer->data;
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, data.buffer->size);
 | 
			
		||||
    out = gbinder_reader_read_hidl_string_vec(&reader);
 | 
			
		||||
@@ -1107,7 +1107,7 @@ test_byte_array(
 | 
			
		||||
    tmp = g_malloc0(1);
 | 
			
		||||
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, 1);
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, 1, NULL);
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, 1);
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_reader_read_byte_array(&reader, &out_len));
 | 
			
		||||
@@ -1123,7 +1123,7 @@ test_byte_array(
 | 
			
		||||
    memcpy(tmp, &in_len, sizeof(in_len));
 | 
			
		||||
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, in_len - 1);
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, in_len - 1, NULL);
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, in_len - 1);
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_reader_read_byte_array(&reader, &out_len));
 | 
			
		||||
@@ -1139,7 +1139,7 @@ test_byte_array(
 | 
			
		||||
    memcpy(tmp, &null_len, sizeof(null_len));
 | 
			
		||||
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, sizeof(null_len));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, sizeof(null_len), NULL);
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, sizeof(null_len));
 | 
			
		||||
 | 
			
		||||
    g_assert((out_data = gbinder_reader_read_byte_array(&reader, &out_len)));
 | 
			
		||||
@@ -1156,7 +1156,7 @@ test_byte_array(
 | 
			
		||||
    memcpy(tmp + sizeof(in_len), in_data, in_len);
 | 
			
		||||
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, tmp_len);
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, tmp_len, NULL);
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, tmp_len);
 | 
			
		||||
 | 
			
		||||
    g_assert((out_data = gbinder_reader_read_byte_array(&reader, &out_len)));
 | 
			
		||||
@@ -1204,7 +1204,7 @@ test_copy(
 | 
			
		||||
    memcpy(ptr, in_data2, in_len2);
 | 
			
		||||
 | 
			
		||||
    memset(&data, 0, sizeof(data));
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, tmp_len);
 | 
			
		||||
    data.buffer = gbinder_buffer_new(driver, tmp, tmp_len, NULL);
 | 
			
		||||
    gbinder_reader_init(&reader, &data, 0, tmp_len);
 | 
			
		||||
 | 
			
		||||
    /* Read the first array */
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ test_null(
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_remote_reply_ref(NULL));
 | 
			
		||||
    gbinder_remote_reply_unref(NULL);
 | 
			
		||||
    gbinder_remote_reply_set_data(NULL, NULL, NULL);
 | 
			
		||||
    gbinder_remote_reply_set_data(NULL, NULL);
 | 
			
		||||
    gbinder_remote_reply_init_reader(NULL, &reader);
 | 
			
		||||
    g_assert(gbinder_reader_at_end(&reader));
 | 
			
		||||
    g_assert(gbinder_remote_reply_is_empty(NULL));
 | 
			
		||||
@@ -85,8 +85,8 @@ test_empty(
 | 
			
		||||
    GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
 | 
			
		||||
    GBinderRemoteReply* reply = gbinder_remote_reply_new(NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_reply_set_data
 | 
			
		||||
        (reply, gbinder_buffer_new(driver, NULL, 0), NULL);
 | 
			
		||||
    gbinder_remote_reply_set_data(reply,
 | 
			
		||||
        gbinder_buffer_new(driver, NULL, 0, NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(gbinder_remote_reply_is_empty(reply));
 | 
			
		||||
    gbinder_remote_reply_unref(reply);
 | 
			
		||||
@@ -132,8 +132,7 @@ test_int32(
 | 
			
		||||
    GBinderRemoteReply* reply = gbinder_remote_reply_new(NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_reply_set_data(reply, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_remote_reply_is_empty(reply));
 | 
			
		||||
    g_assert(gbinder_remote_reply_read_uint32(reply, &out1));
 | 
			
		||||
@@ -163,8 +162,7 @@ test_int64(
 | 
			
		||||
    GBinderRemoteReply* reply = gbinder_remote_reply_new(NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_reply_set_data(reply, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_remote_reply_is_empty(reply));
 | 
			
		||||
    g_assert(gbinder_remote_reply_read_uint64(reply, &out1));
 | 
			
		||||
@@ -192,8 +190,7 @@ test_string8(
 | 
			
		||||
    GBinderRemoteReply* reply = gbinder_remote_reply_new(NULL);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_reply_set_data(reply, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_remote_reply_is_empty(reply));
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_reply_read_string8(reply), "bar"));
 | 
			
		||||
@@ -221,8 +218,7 @@ test_string16(
 | 
			
		||||
    char* str;
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_reply_set_data(reply, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
        g_memdup(reply_data, sizeof(reply_data)), sizeof(reply_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_remote_reply_is_empty(reply));
 | 
			
		||||
    str = gbinder_remote_reply_read_string16(reply);
 | 
			
		||||
@@ -264,7 +260,7 @@ test_to_local(
 | 
			
		||||
    /* Skip the 32-bit integer */
 | 
			
		||||
    objects[0] = req_data + 4;
 | 
			
		||||
    gbinder_remote_reply_set_data(req, gbinder_buffer_new(driver, req_data,
 | 
			
		||||
        sizeof(reply_data)), objects);
 | 
			
		||||
        sizeof(reply_data), objects));
 | 
			
		||||
 | 
			
		||||
    /* Convert to GBinderLocalReply */
 | 
			
		||||
    req2 = gbinder_remote_reply_copy_to_local(req);
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ test_null(
 | 
			
		||||
 | 
			
		||||
    g_assert(!gbinder_remote_request_ref(NULL));
 | 
			
		||||
    gbinder_remote_request_unref(NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(NULL, NULL, NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(NULL, 0, NULL);
 | 
			
		||||
    gbinder_remote_request_init_reader(NULL, &reader);
 | 
			
		||||
    g_assert(gbinder_reader_at_end(&reader));
 | 
			
		||||
    g_assert(!gbinder_remote_request_interface(NULL));
 | 
			
		||||
@@ -118,7 +118,7 @@ void
 | 
			
		||||
test_int32(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    static const guint8 request_data [] = {
 | 
			
		||||
    static const guint8 req_data [] = {
 | 
			
		||||
        TEST_RPC_HEADER,
 | 
			
		||||
        TEST_INT32_BYTES(42)
 | 
			
		||||
    };
 | 
			
		||||
@@ -129,9 +129,9 @@ test_int32(
 | 
			
		||||
    GBinderRemoteRequest* req = gbinder_remote_request_new(NULL,
 | 
			
		||||
        gbinder_rpc_protocol_for_device(dev), 0, 0);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(request_data, sizeof(request_data)), sizeof(request_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_FIRST_CALL_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), TEST_RPC_IFACE));
 | 
			
		||||
    g_assert(gbinder_remote_request_read_uint32(req, &out1));
 | 
			
		||||
@@ -152,7 +152,7 @@ void
 | 
			
		||||
test_int64(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    static const guint8 request_data [] = {
 | 
			
		||||
    static const guint8 req_data [] = {
 | 
			
		||||
        TEST_RPC_HEADER,
 | 
			
		||||
        TEST_INT64_BYTES(42)
 | 
			
		||||
    };
 | 
			
		||||
@@ -163,9 +163,9 @@ test_int64(
 | 
			
		||||
    GBinderRemoteRequest* req = gbinder_remote_request_new(NULL,
 | 
			
		||||
        gbinder_rpc_protocol_for_device(dev), 0, 0);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(request_data, sizeof(request_data)), sizeof(request_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_FIRST_CALL_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), TEST_RPC_IFACE));
 | 
			
		||||
    g_assert(gbinder_remote_request_read_uint64(req, &out1));
 | 
			
		||||
@@ -186,7 +186,7 @@ void
 | 
			
		||||
test_string8(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    static const guint8 request_data [] = {
 | 
			
		||||
    static const guint8 req_data [] = {
 | 
			
		||||
        TEST_RPC_HEADER,
 | 
			
		||||
        'b', 'a', 'r', 0x00
 | 
			
		||||
    };
 | 
			
		||||
@@ -195,9 +195,9 @@ test_string8(
 | 
			
		||||
    GBinderRemoteRequest* req = gbinder_remote_request_new(NULL,
 | 
			
		||||
        gbinder_rpc_protocol_for_device(dev), 0, 0);
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(request_data, sizeof(request_data)), sizeof(request_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_FIRST_CALL_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), TEST_RPC_IFACE));
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_read_string8(req), "bar"));
 | 
			
		||||
@@ -215,7 +215,7 @@ void
 | 
			
		||||
test_string16(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    static const guint8 request_data [] = {
 | 
			
		||||
    static const guint8 req_data [] = {
 | 
			
		||||
        TEST_RPC_HEADER,
 | 
			
		||||
        TEST_INT32_BYTES(3),
 | 
			
		||||
        TEST_INT16_BYTES('b'), TEST_INT16_BYTES('a'),
 | 
			
		||||
@@ -227,9 +227,9 @@ test_string16(
 | 
			
		||||
        gbinder_rpc_protocol_for_device(dev), 0, 0);
 | 
			
		||||
    char* str;
 | 
			
		||||
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(driver,
 | 
			
		||||
        g_memdup(request_data, sizeof(request_data)), sizeof(request_data)),
 | 
			
		||||
        NULL);
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_FIRST_CALL_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(driver, g_memdup(req_data, sizeof(req_data)),
 | 
			
		||||
        sizeof(req_data), NULL));
 | 
			
		||||
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), TEST_RPC_IFACE));
 | 
			
		||||
    str = gbinder_remote_request_read_string16(req);
 | 
			
		||||
@@ -272,8 +272,8 @@ test_to_local(
 | 
			
		||||
 | 
			
		||||
    /* Skip the 32-bit integer */
 | 
			
		||||
    objects[0] = req_data + 4;
 | 
			
		||||
    gbinder_remote_request_set_data(req, gbinder_buffer_new(driver, req_data,
 | 
			
		||||
        sizeof(request_data)), objects);
 | 
			
		||||
    gbinder_remote_request_set_data(req, GBINDER_FIRST_CALL_TRANSACTION,
 | 
			
		||||
        gbinder_buffer_new(driver, req_data, sizeof(request_data), objects));
 | 
			
		||||
 | 
			
		||||
    g_assert(!g_strcmp0(gbinder_remote_request_interface(req), TEST_RPC_IFACE));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user