mirror of
				https://github.com/mer-hybris/libgbinder
				synced 2025-11-04 14:46:00 +08:00 
			
		
		
		
	Merge pull request #144 from mer-hybris/jb61406
Add support for writing AIDL FMQs
This commit is contained in:
		@@ -236,7 +236,7 @@ void
 | 
			
		||||
gbinder_writer_append_fds(
 | 
			
		||||
    GBinderWriter* writer,
 | 
			
		||||
    const GBinderFds* fds,
 | 
			
		||||
    const GBinderParent* parent); /* Since 1.1.14 */
 | 
			
		||||
    const GBinderParent* parent); /* Since 1.1.43 */
 | 
			
		||||
 | 
			
		||||
guint
 | 
			
		||||
gbinder_writer_append_buffer_object_with_parent(
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2025 Jolla Mobile Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
@@ -30,13 +31,16 @@
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "gbinder_fmq_p.h"
 | 
			
		||||
#include "gbinder_rpc_protocol.h"
 | 
			
		||||
#include "gbinder_reader.h"
 | 
			
		||||
#include "gbinder_writer.h"
 | 
			
		||||
#include "gbinder_writer_p.h"
 | 
			
		||||
#include "gbinder_config.h"
 | 
			
		||||
#include "gbinder_log.h"
 | 
			
		||||
#include "gbinder_local_object_p.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_misc.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
 | 
			
		||||
@@ -78,6 +82,61 @@ static const GBinderRpcProtocol DEFAULT_PROTOCOL;
 | 
			
		||||
static const GBinderRpcProtocol* gbinder_rpc_protocol_default =
 | 
			
		||||
    &DEFAULT_PROTOCOL;
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Common AIDL protocol
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_rpc_protocol_aidl_write_fmq_descriptor(
 | 
			
		||||
    GBinderWriter* writer, const GBinderFmq* queue)
 | 
			
		||||
{
 | 
			
		||||
    GBinderMQDescriptor* desc = gbinder_fmq_get_descriptor(queue);
 | 
			
		||||
 | 
			
		||||
    gssize size_offset;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    gssize fmq_size_offset = gbinder_writer_append_parcelable_start(writer,
 | 
			
		||||
        queue != NULL);
 | 
			
		||||
 | 
			
		||||
    /* Write the grantors */
 | 
			
		||||
    GBinderFmqGrantorDescriptor *grantors =
 | 
			
		||||
        (GBinderFmqGrantorDescriptor *)desc->grantors.data.ptr;
 | 
			
		||||
 | 
			
		||||
    gbinder_writer_append_int32(writer, desc->grantors.count);
 | 
			
		||||
    for (i = 0; i < desc->grantors.count; i++) {
 | 
			
		||||
        gssize grantors_size_offset =
 | 
			
		||||
            gbinder_writer_append_parcelable_start(writer, TRUE);
 | 
			
		||||
        gbinder_writer_append_int32(writer, grantors[i].fd_index);
 | 
			
		||||
        gbinder_writer_append_int32(writer, grantors[i].offset);
 | 
			
		||||
        gbinder_writer_append_int64(writer, grantors[i].extent);
 | 
			
		||||
        gbinder_writer_append_parcelable_finish(writer, grantors_size_offset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Write the native handle */
 | 
			
		||||
    size_offset = gbinder_writer_append_parcelable_start(writer, TRUE);
 | 
			
		||||
 | 
			
		||||
    gbinder_writer_append_int32(writer, desc->data.fds->num_fds);
 | 
			
		||||
    for (i = 0; i < desc->data.fds->num_fds; i++) {
 | 
			
		||||
        gbinder_writer_append_int32(writer, 1);
 | 
			
		||||
        gbinder_writer_append_int32(writer, 0);
 | 
			
		||||
        gbinder_writer_append_fd(writer, gbinder_fds_get_fd(desc->data.fds, i));
 | 
			
		||||
    }
 | 
			
		||||
    gbinder_writer_append_int32(writer, desc->data.fds->num_ints);
 | 
			
		||||
    for (i = 0; i < desc->data.fds->num_ints; i++) {
 | 
			
		||||
        gbinder_writer_append_int32(writer, gbinder_fds_get_fd(desc->data.fds, desc->data.fds->num_fds + i));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gbinder_writer_append_parcelable_finish(writer, size_offset);
 | 
			
		||||
 | 
			
		||||
    /* Write the quantum */
 | 
			
		||||
    gbinder_writer_append_int32(writer, desc->quantum);
 | 
			
		||||
 | 
			
		||||
    /* Write the flags */
 | 
			
		||||
    gbinder_writer_append_int32(writer, desc->flags);
 | 
			
		||||
 | 
			
		||||
    gbinder_writer_append_parcelable_finish(writer, fmq_size_offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * The original AIDL protocol.
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
@@ -128,7 +187,8 @@ static const GBinderRpcProtocol gbinder_rpc_protocol_aidl = {
 | 
			
		||||
    .ping_tx = GBINDER_PING_TRANSACTION,
 | 
			
		||||
    .write_ping = gbinder_rpc_protocol_aidl_write_ping,
 | 
			
		||||
    .write_rpc_header = gbinder_rpc_protocol_aidl_write_rpc_header,
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_aidl_read_rpc_header
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_aidl_read_rpc_header,
 | 
			
		||||
    .write_fmq_descriptor = gbinder_rpc_protocol_aidl_write_fmq_descriptor,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -176,7 +236,8 @@ static const GBinderRpcProtocol gbinder_rpc_protocol_aidl2 = {
 | 
			
		||||
    .ping_tx = GBINDER_PING_TRANSACTION,
 | 
			
		||||
    .write_ping = gbinder_rpc_protocol_aidl_write_ping, /* no payload */
 | 
			
		||||
    .write_rpc_header = gbinder_rpc_protocol_aidl2_write_rpc_header,
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_aidl2_read_rpc_header
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_aidl2_read_rpc_header,
 | 
			
		||||
    .write_fmq_descriptor = gbinder_rpc_protocol_aidl_write_fmq_descriptor,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -235,7 +296,8 @@ static const GBinderRpcProtocol gbinder_rpc_protocol_aidl3 = {
 | 
			
		||||
    .write_rpc_header = gbinder_rpc_protocol_aidl3_write_rpc_header,
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_aidl3_read_rpc_header,
 | 
			
		||||
    .flat_binder_object_extra = 4,
 | 
			
		||||
    .finish_flatten_binder = gbinder_rpc_protocol_aidl3_finish_flatten_binder
 | 
			
		||||
    .finish_flatten_binder = gbinder_rpc_protocol_aidl3_finish_flatten_binder,
 | 
			
		||||
    .write_fmq_descriptor = gbinder_rpc_protocol_aidl_write_fmq_descriptor,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -273,7 +335,8 @@ static const GBinderRpcProtocol gbinder_rpc_protocol_aidl4 = {
 | 
			
		||||
    .write_rpc_header = gbinder_rpc_protocol_aidl3_write_rpc_header,
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_aidl3_read_rpc_header,
 | 
			
		||||
    .flat_binder_object_extra = 4,
 | 
			
		||||
    .finish_flatten_binder = gbinder_rpc_protocol_aidl4_finish_flatten_binder
 | 
			
		||||
    .finish_flatten_binder = gbinder_rpc_protocol_aidl4_finish_flatten_binder,
 | 
			
		||||
    .write_fmq_descriptor = gbinder_rpc_protocol_aidl_write_fmq_descriptor,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -312,12 +375,56 @@ gbinder_rpc_protocol_hidl_read_rpc_header(
 | 
			
		||||
    return gbinder_reader_read_string8(reader);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_rpc_protocol_hidl_write_fmq_descriptor(
 | 
			
		||||
    GBinderWriter* writer, const GBinderFmq* queue)
 | 
			
		||||
{
 | 
			
		||||
    GBinderParent parent;
 | 
			
		||||
    GBinderMQDescriptor* desc = gbinder_fmq_get_descriptor(queue);
 | 
			
		||||
    GBinderMQDescriptor* mqdesc = gutil_memdup(desc,
 | 
			
		||||
        sizeof(GBinderMQDescriptor));
 | 
			
		||||
 | 
			
		||||
    const gsize vec_total =
 | 
			
		||||
        desc->grantors.count * sizeof(GBinderFmqGrantorDescriptor);
 | 
			
		||||
    void* vec_buf = gutil_memdup(desc->grantors.data.ptr, vec_total);
 | 
			
		||||
 | 
			
		||||
    const gsize fds_total = sizeof(GBinderFds) +
 | 
			
		||||
        sizeof(int) * (desc->data.fds->num_fds + desc->data.fds->num_ints);
 | 
			
		||||
    GBinderFds* fds = gutil_memdup(desc->data.fds, fds_total);
 | 
			
		||||
 | 
			
		||||
    mqdesc->data.fds = fds;
 | 
			
		||||
    gbinder_writer_add_cleanup(writer, g_free, fds);
 | 
			
		||||
 | 
			
		||||
    /* Fill in the grantor vector descriptor */
 | 
			
		||||
    if (vec_buf) {
 | 
			
		||||
        mqdesc->grantors.count = desc->grantors.count;
 | 
			
		||||
        mqdesc->grantors.data.ptr = vec_buf;
 | 
			
		||||
        mqdesc->grantors.owns_buffer = TRUE;
 | 
			
		||||
        gbinder_writer_add_cleanup(writer, g_free, vec_buf);
 | 
			
		||||
    }
 | 
			
		||||
    gbinder_writer_add_cleanup(writer, g_free, mqdesc);
 | 
			
		||||
 | 
			
		||||
    /* Write the FMQ descriptor object */
 | 
			
		||||
    parent.index = gbinder_writer_append_buffer_object(writer,
 | 
			
		||||
        mqdesc, sizeof(*mqdesc));
 | 
			
		||||
 | 
			
		||||
    /* Write the vector data buffer */
 | 
			
		||||
    parent.offset = GBINDER_MQ_DESCRIPTOR_GRANTORS_OFFSET;
 | 
			
		||||
    gbinder_writer_append_buffer_object_with_parent(writer, vec_buf, vec_total,
 | 
			
		||||
        &parent);
 | 
			
		||||
 | 
			
		||||
    /* Write the fds */
 | 
			
		||||
    parent.offset = GBINDER_MQ_DESCRIPTOR_FDS_OFFSET;
 | 
			
		||||
    gbinder_writer_append_fds(writer, mqdesc->data.fds, &parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const GBinderRpcProtocol gbinder_rpc_protocol_hidl = {
 | 
			
		||||
    .name = "hidl",
 | 
			
		||||
    .ping_tx = HIDL_PING_TRANSACTION,
 | 
			
		||||
    .write_ping = gbinder_rpc_protocol_hidl_write_ping,
 | 
			
		||||
    .write_rpc_header = gbinder_rpc_protocol_hidl_write_rpc_header,
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_hidl_read_rpc_header
 | 
			
		||||
    .read_rpc_header = gbinder_rpc_protocol_hidl_read_rpc_header,
 | 
			
		||||
    .write_fmq_descriptor = gbinder_rpc_protocol_hidl_write_fmq_descriptor,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2025 Jolla Mobile Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
@@ -58,6 +59,7 @@ struct gbinder_rpc_protocol {
 | 
			
		||||
    gsize flat_binder_object_extra;
 | 
			
		||||
    void (*finish_flatten_binder)(void* out, GBinderLocalObject* obj);
 | 
			
		||||
    void (*finish_unflatten_binder)(const void* in, GBinderRemoteObject* obj);
 | 
			
		||||
    void (*write_fmq_descriptor)(GBinderWriter* writer, const GBinderFmq* queue);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const GBinderRpcProtocol*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2024 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2025 Jolla Mobile Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
@@ -35,6 +36,7 @@
 | 
			
		||||
#include "gbinder_fmq_p.h"
 | 
			
		||||
#include "gbinder_local_object.h"
 | 
			
		||||
#include "gbinder_object_converter.h"
 | 
			
		||||
#include "gbinder_rpc_protocol.h"
 | 
			
		||||
#include "gbinder_io.h"
 | 
			
		||||
#include "gbinder_log.h"
 | 
			
		||||
 | 
			
		||||
@@ -732,6 +734,19 @@ gbinder_writer_data_append_fds(
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_append_fds(
 | 
			
		||||
    GBinderWriter* self,
 | 
			
		||||
    const GBinderFds *fds,
 | 
			
		||||
    const GBinderParent* parent) /* Since 1.0.43 */
 | 
			
		||||
{
 | 
			
		||||
    GBinderWriterData* data = gbinder_writer_data(self);
 | 
			
		||||
 | 
			
		||||
    if (G_LIKELY(data)) {
 | 
			
		||||
        gbinder_writer_data_append_fds(data, fds, parent);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
guint
 | 
			
		||||
gbinder_writer_append_buffer_object_with_parent(
 | 
			
		||||
    GBinderWriter* self,
 | 
			
		||||
@@ -960,6 +975,61 @@ gbinder_writer_data_append_parcelable(
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This is compatible with aidl parcelables, and is not guaranteed to work
 | 
			
		||||
 * with any other kind of parcelable.
 | 
			
		||||
 * Returns offset needed for overwriting size of parcelable or -1
 | 
			
		||||
 * if no data is to be written for the parcel.
 | 
			
		||||
 */
 | 
			
		||||
gssize
 | 
			
		||||
gbinder_writer_append_parcelable_start(
 | 
			
		||||
    GBinderWriter* self,
 | 
			
		||||
    gboolean has_data)
 | 
			
		||||
{
 | 
			
		||||
    GBinderWriterData* data = gbinder_writer_data(self);
 | 
			
		||||
 | 
			
		||||
    if (G_LIKELY(data)) {
 | 
			
		||||
        gssize size_offset = -1;
 | 
			
		||||
 | 
			
		||||
        if (has_data) {
 | 
			
		||||
            /* Non-null */
 | 
			
		||||
            gbinder_writer_data_append_int32(data, 1);
 | 
			
		||||
 | 
			
		||||
            size_offset = data->bytes->len;
 | 
			
		||||
            /*
 | 
			
		||||
             * Write the dummy parcelable size which is later fixed using
 | 
			
		||||
             * gbinder_writer_data_append_parcelable_finish.
 | 
			
		||||
             */
 | 
			
		||||
            gbinder_writer_data_append_int32(data, 0);
 | 
			
		||||
        } else {
 | 
			
		||||
            /* Null */
 | 
			
		||||
            gbinder_writer_data_append_int32(data, 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return size_offset;
 | 
			
		||||
        }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This is compatible with aidl parcelables, and is not guaranteed to work
 | 
			
		||||
 * with any other kind of parcelable.
 | 
			
		||||
 * Fixes size of parcelable using offset obtained from
 | 
			
		||||
 * gbinder_writer_append_parcelable_start. Do nothing if no data was written
 | 
			
		||||
 * to parceable, i.e. offset is -1.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_append_parcelable_finish(
 | 
			
		||||
    GBinderWriter* self,
 | 
			
		||||
    gssize offset)
 | 
			
		||||
{
 | 
			
		||||
    if (offset >= 0) {
 | 
			
		||||
        /* Replace parcelable size with real value */
 | 
			
		||||
        gbinder_writer_overwrite_int32(self, offset,
 | 
			
		||||
            gbinder_writer_bytes_written(self) - offset);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_append_hidl_string(
 | 
			
		||||
    GBinderWriter* self,
 | 
			
		||||
@@ -1237,51 +1307,6 @@ gbinder_writer_append_byte_array(
 | 
			
		||||
 | 
			
		||||
#if GBINDER_FMQ_SUPPORTED
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_data_append_fmq_descriptor(
 | 
			
		||||
    GBinderWriterData* data,
 | 
			
		||||
    const GBinderFmq* queue)
 | 
			
		||||
{
 | 
			
		||||
    GBinderParent parent;
 | 
			
		||||
    GBinderMQDescriptor* desc = gbinder_fmq_get_descriptor(queue);
 | 
			
		||||
    GBinderMQDescriptor* mqdesc = gutil_memdup(desc,
 | 
			
		||||
        sizeof(GBinderMQDescriptor));
 | 
			
		||||
 | 
			
		||||
    const gsize vec_total =
 | 
			
		||||
        desc->grantors.count * sizeof(GBinderFmqGrantorDescriptor);
 | 
			
		||||
    void* vec_buf = gutil_memdup(desc->grantors.data.ptr, vec_total);
 | 
			
		||||
 | 
			
		||||
    const gsize fds_total = sizeof(GBinderFds) +
 | 
			
		||||
        sizeof(int) * (desc->data.fds->num_fds + desc->data.fds->num_ints);
 | 
			
		||||
    GBinderFds* fds = gutil_memdup(desc->data.fds, fds_total);
 | 
			
		||||
 | 
			
		||||
    mqdesc->data.fds = fds;
 | 
			
		||||
    data->cleanup = gbinder_cleanup_add(data->cleanup, g_free, fds);
 | 
			
		||||
 | 
			
		||||
    /* Fill in the grantor vector descriptor */
 | 
			
		||||
    if (vec_buf) {
 | 
			
		||||
        mqdesc->grantors.count = desc->grantors.count;
 | 
			
		||||
        mqdesc->grantors.data.ptr = vec_buf;
 | 
			
		||||
        mqdesc->grantors.owns_buffer = TRUE;
 | 
			
		||||
        data->cleanup = gbinder_cleanup_add(data->cleanup, g_free, vec_buf);
 | 
			
		||||
    }
 | 
			
		||||
    data->cleanup = gbinder_cleanup_add(data->cleanup, g_free, mqdesc);
 | 
			
		||||
 | 
			
		||||
    /* Write the FMQ descriptor object */
 | 
			
		||||
    parent.index = gbinder_writer_data_append_buffer_object(data,
 | 
			
		||||
        mqdesc, sizeof(*mqdesc), NULL);
 | 
			
		||||
 | 
			
		||||
    /* Write the vector data buffer */
 | 
			
		||||
    parent.offset = GBINDER_MQ_DESCRIPTOR_GRANTORS_OFFSET;
 | 
			
		||||
    gbinder_writer_data_append_buffer_object(data, vec_buf, vec_total,
 | 
			
		||||
        &parent);
 | 
			
		||||
 | 
			
		||||
    /* Write the fds */
 | 
			
		||||
    parent.offset = GBINDER_MQ_DESCRIPTOR_FDS_OFFSET;
 | 
			
		||||
    gbinder_writer_data_append_fds(data, mqdesc->data.fds, &parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_append_fmq_descriptor(
 | 
			
		||||
    GBinderWriter* self,
 | 
			
		||||
@@ -1290,7 +1315,7 @@ gbinder_writer_append_fmq_descriptor(
 | 
			
		||||
    GBinderWriterData* data = gbinder_writer_data(self);
 | 
			
		||||
 | 
			
		||||
    if (G_LIKELY(data) && G_LIKELY(queue)) {
 | 
			
		||||
        gbinder_writer_data_append_fmq_descriptor(data, queue);
 | 
			
		||||
        data->protocol->write_fmq_descriptor(self, queue);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2025 Jolla Mobile Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
@@ -177,6 +178,16 @@ gbinder_writer_data_append_fd(
 | 
			
		||||
    int fd)
 | 
			
		||||
    GBINDER_INTERNAL;
 | 
			
		||||
 | 
			
		||||
gssize
 | 
			
		||||
gbinder_writer_append_parcelable_start(
 | 
			
		||||
    GBinderWriter* writer,
 | 
			
		||||
    gboolean has_data);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_writer_append_parcelable_finish(
 | 
			
		||||
    GBinderWriter* writer,
 | 
			
		||||
    gssize offset);
 | 
			
		||||
 | 
			
		||||
#endif /* GBINDER_WRITER_PRIVATE_H */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2025 Jolla Mobile Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -55,13 +56,22 @@
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-writer-XXXXXX";
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
GBinderLocalRequest*
 | 
			
		||||
test_local_request_new_with_io_dev(
 | 
			
		||||
    const GBinderIo* io,
 | 
			
		||||
    const char *dev)
 | 
			
		||||
{
 | 
			
		||||
    return gbinder_local_request_new(io,
 | 
			
		||||
      gbinder_rpc_protocol_for_device(dev), NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
GBinderLocalRequest*
 | 
			
		||||
test_local_request_new_with_io(
 | 
			
		||||
    const GBinderIo* io)
 | 
			
		||||
{
 | 
			
		||||
    return gbinder_local_request_new(io,
 | 
			
		||||
      gbinder_rpc_protocol_for_device(GBINDER_DEFAULT_BINDER), NULL);
 | 
			
		||||
    return test_local_request_new_with_io_dev(io, GBINDER_DEFAULT_BINDER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
@@ -78,6 +88,13 @@ test_local_request_new_64()
 | 
			
		||||
    return test_local_request_new_with_io(&gbinder_io_64);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
GBinderLocalRequest*
 | 
			
		||||
test_local_request_new_64_hidl()
 | 
			
		||||
{
 | 
			
		||||
    return test_local_request_new_with_io_dev(&gbinder_io_64, GBINDER_DEFAULT_HWBINDER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Test context
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
@@ -1466,7 +1483,7 @@ test_fmq_descriptor(
 | 
			
		||||
        GBINDER_FMQ_FLAG_CONFIGURE_EVENT_FLAG, -1, 0);
 | 
			
		||||
 | 
			
		||||
    g_assert(fmq);
 | 
			
		||||
    req = test_local_request_new_64();
 | 
			
		||||
    req = test_local_request_new_64_hidl();
 | 
			
		||||
    gbinder_local_request_init_writer(req, &writer);
 | 
			
		||||
    gbinder_writer_append_fmq_descriptor(&writer, fmq);
 | 
			
		||||
    data = gbinder_local_request_data(req);
 | 
			
		||||
@@ -1482,6 +1499,36 @@ test_fmq_descriptor(
 | 
			
		||||
    gbinder_fmq_unref(fmq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_fmq_descriptor_aidl(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    GBinderLocalRequest* req;
 | 
			
		||||
    GBinderOutputData* data;
 | 
			
		||||
    GBinderWriter writer;
 | 
			
		||||
    const gint32 len = 2 * sizeof(gint32) /* FMQ decriptor parcelable header */
 | 
			
		||||
        + sizeof(gint32) + 4 * (4 * sizeof(gint32) + sizeof(gint64)) /* grantors + parcelable headers */
 | 
			
		||||
        + 2 * sizeof(gint32) /* Native handle parcelable header */
 | 
			
		||||
        + sizeof(gint32) + 2 * sizeof(gint32) + 3 * sizeof(gint64) /* fds (1 fd array) */
 | 
			
		||||
        + sizeof(gint32) /* ints (0 int array) */
 | 
			
		||||
        + sizeof(gint32) /* quantum */
 | 
			
		||||
        + sizeof(gint32); /* flags */
 | 
			
		||||
 | 
			
		||||
    GBinderFmq* fmq = gbinder_fmq_new(sizeof(guint32), 5,
 | 
			
		||||
        GBINDER_FMQ_TYPE_SYNC_READ_WRITE,
 | 
			
		||||
        GBINDER_FMQ_FLAG_CONFIGURE_EVENT_FLAG, -1, 0);
 | 
			
		||||
 | 
			
		||||
    g_assert(fmq);
 | 
			
		||||
    req = test_local_request_new_64();
 | 
			
		||||
    gbinder_local_request_init_writer(req, &writer);
 | 
			
		||||
    gbinder_writer_append_fmq_descriptor(&writer, fmq);
 | 
			
		||||
    data = gbinder_local_request_data(req);
 | 
			
		||||
    g_assert_cmpuint(data->bytes->len, == ,len);
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
    gbinder_fmq_unref(fmq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* GBINDER_FMQ_SUPPORTED */
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -1610,6 +1657,7 @@ int main(int argc, char* argv[])
 | 
			
		||||
        } else {
 | 
			
		||||
            close(test_fd);
 | 
			
		||||
            g_test_add_func(TEST_("fmq_descriptor"), test_fmq_descriptor);
 | 
			
		||||
            g_test_add_func(TEST_("fmq_descriptor_aidl"), test_fmq_descriptor_aidl);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* GBINDER_FMQ_SUPPORTED */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user