Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3bc7bb63b | ||
|
|
f525378b18 | ||
|
|
43676db1b9 | ||
|
|
18c4f24fd3 | ||
|
|
4cc22d8256 | ||
|
|
c836a7da81 | ||
|
|
2446d39d4b | ||
|
|
d3233ac89f | ||
|
|
ba9fff8a06 | ||
|
|
311756ae11 | ||
|
|
98459e4053 | ||
|
|
374526be9c | ||
|
|
62dac7e893 | ||
|
|
aa946b4c31 | ||
|
|
b81f35d1ff | ||
|
|
c35d266c77 | ||
|
|
3350f51a21 | ||
|
|
5cfe96b891 | ||
|
|
20774aecac | ||
|
|
624bfa843d | ||
|
|
6d71a0649c | ||
|
|
c31cd7e964 | ||
|
|
c1db86e734 | ||
|
|
bfb95f2bf5 | ||
|
|
6f4c69d58a | ||
|
|
c6b09a10d4 | ||
|
|
545f5bc28d | ||
|
|
78e006f1cf | ||
|
|
3c9cc1711a | ||
|
|
71aa3acc08 | ||
|
|
eee26c5e98 | ||
|
|
736a29aa4c | ||
|
|
0d7105edbe | ||
|
|
4420c7b2ae | ||
|
|
52726a07b0 | ||
|
|
12b9fd49ad | ||
|
|
e75959e389 | ||
|
|
9d35ca22fb | ||
|
|
3e0d0005ce |
5
AUTHORS
5
AUTHORS
@@ -1,4 +1,4 @@
|
||||
Slava Monich <slava.monich@jolla.com>
|
||||
Slava Monich <slava@monich.com>
|
||||
Matti Lehtimäki <matti.lehtimaki@gmail.com>
|
||||
Franz-Josef Haider <franz.haider@jolla.com>
|
||||
Juho Hämäläinen <juho.hamalainen@jolla.com>
|
||||
@@ -9,3 +9,6 @@ Bart Ribbers <bribbers@disroot.org>
|
||||
Gary Wang <gary.wang@canonical.com>
|
||||
Eugenio Paolantonio <me@medesimo.eu>
|
||||
Alessandro Astone <ales.astone@gmail.com>
|
||||
Martin Kampas <martin.kampas@seafarix.com>
|
||||
Nikita Ukhrenkov <nikita.ukhrenkov@seafarix.com>
|
||||
Ratchanan Srirattanamet <ratchanan@ubports.com>
|
||||
|
||||
2
Makefile
2
Makefile
@@ -16,7 +16,7 @@
|
||||
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 1
|
||||
VERSION_RELEASE = 38
|
||||
VERSION_RELEASE = 42
|
||||
|
||||
# Version for pkg-config
|
||||
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
|
||||
|
||||
30
debian/changelog
vendored
30
debian/changelog
vendored
@@ -1,3 +1,33 @@
|
||||
libgbinder (1.1.42) unstable; urgency=low
|
||||
|
||||
* Delete name watches with no handlers
|
||||
* Register for sm notifications asynchronously
|
||||
* Correct stability field wire format on Android 12
|
||||
|
||||
-- Slava Monich <slava@monich.com> Wed, 11 Dec 2024 06:40:00 +0200
|
||||
|
||||
libgbinder (1.1.41) unstable; urgency=low
|
||||
|
||||
* Fix sending NULL binder object
|
||||
* Added gbinder_reader_read_nullable_string8
|
||||
* Check if counted strings are NULL-terminated
|
||||
|
||||
-- Slava Monich <slava@monich.com> Sat, 02 Nov 2024 05:13:22 +0200
|
||||
|
||||
libgbinder (1.1.40) unstable; urgency=low
|
||||
|
||||
* Make stability field of local object configurable
|
||||
* Make more unit tests independent on system config
|
||||
* Use UNDECLARED stability for NULL binders
|
||||
|
||||
-- Slava Monich <slava@monich.com> Thu, 18 Jul 2024 05:14:28 +0300
|
||||
|
||||
libgbinder (1.1.39) unstable; urgency=low
|
||||
|
||||
* Eliminate defects found by Coverity
|
||||
|
||||
-- Slava Monich <slava@monich.com> Sun, 05 May 2024 20:03:44 +0300
|
||||
|
||||
libgbinder (1.1.38) unstable; urgency=low
|
||||
|
||||
* Fixed byte array padding
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 Jolla Ltd.
|
||||
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -61,6 +61,11 @@ GBinderLocalReply*
|
||||
gbinder_local_object_new_reply(
|
||||
GBinderLocalObject* obj);
|
||||
|
||||
void
|
||||
gbinder_local_object_set_stability(
|
||||
GBinderLocalObject* self,
|
||||
GBINDER_STABILITY_LEVEL stability); /* Since 1.1.40 */
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GBINDER_LOCAL_OBJECT_H */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -196,6 +196,15 @@ const char*
|
||||
gbinder_reader_read_string8(
|
||||
GBinderReader* reader);
|
||||
|
||||
gboolean
|
||||
gbinder_reader_read_nullable_string8(
|
||||
GBinderReader* reader,
|
||||
const char** out,
|
||||
gsize* out_len); /* Since 1.1.41 */
|
||||
|
||||
#define gbinder_reader_skip_nullable_string8(reader) \
|
||||
gbinder_reader_read_nullable_string8(reader, NULL, NULL)
|
||||
|
||||
char*
|
||||
gbinder_reader_read_string16(
|
||||
GBinderReader* reader)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -173,6 +173,13 @@ typedef enum gbinder_status {
|
||||
GBINDER_STATUS_DEAD_OBJECT
|
||||
} GBINDER_STATUS;
|
||||
|
||||
typedef enum gbinder_stability_level {
|
||||
GBINDER_STABILITY_UNDECLARED = 0,
|
||||
GBINDER_STABILITY_VENDOR = 0x03,
|
||||
GBINDER_STABILITY_SYSTEM = 0x0c,
|
||||
GBINDER_STABILITY_VINTF = 0x3f
|
||||
} GBINDER_STABILITY_LEVEL; /* Since 1.1.40 */
|
||||
|
||||
#define GBINDER_FOURCC(c1,c2,c3,c4) \
|
||||
(((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4))
|
||||
|
||||
|
||||
8
misc/coverity_model.c
Normal file
8
misc/coverity_model.c
Normal file
@@ -0,0 +1,8 @@
|
||||
typedef struct gbinder_remote_request GBinderRemoteRequest;
|
||||
|
||||
void
|
||||
gbinder_remote_request_unref(
|
||||
GBinderRemoteRequest* req)
|
||||
{
|
||||
__coverity_free__(req);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
Name: libgbinder
|
||||
|
||||
Version: 1.1.38
|
||||
Version: 1.1.42
|
||||
Release: 0
|
||||
Summary: Binder client library
|
||||
License: BSD
|
||||
@@ -20,6 +20,9 @@ BuildRequires: flex
|
||||
BuildRequires: pkgconfig(rpm)
|
||||
%define license_support %(pkg-config --exists 'rpm >= 4.11'; echo $?)
|
||||
|
||||
# make_build macro appeared in rpm 4.12
|
||||
%{!?make_build:%define make_build make %{_smp_mflags}}
|
||||
|
||||
Requires: glib2 >= %{glib_version}
|
||||
Requires: libglibutil >= %{libglibutil_version}
|
||||
Requires(post): /sbin/ldconfig
|
||||
@@ -40,11 +43,11 @@ This package contains the development library for %{name}.
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make %{_smp_mflags} LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig
|
||||
make -C test/binder-bridge KEEP_SYMBOLS=1 release
|
||||
make -C test/binder-list KEEP_SYMBOLS=1 release
|
||||
make -C test/binder-ping KEEP_SYMBOLS=1 release
|
||||
make -C test/binder-call KEEP_SYMBOLS=1 release
|
||||
%make_build LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig
|
||||
%make_build -C test/binder-bridge -j1 KEEP_SYMBOLS=1 release
|
||||
%make_build -C test/binder-list -j1 KEEP_SYMBOLS=1 release
|
||||
%make_build -C test/binder-ping -j1 KEEP_SYMBOLS=1 release
|
||||
%make_build -C test/binder-call -j1 KEEP_SYMBOLS=1 release
|
||||
|
||||
%install
|
||||
make LIBDIR=%{_libdir} DESTDIR=%{buildroot} install-dev
|
||||
|
||||
@@ -135,21 +135,30 @@ static const GBinderConfigPresetGroup gbinder_config_30[] = {
|
||||
|
||||
/* API level 31 */
|
||||
|
||||
static const GBinderConfigPresetEntry gbinder_config_31_servicemanager[] = {
|
||||
static const GBinderConfigPresetEntry gbinder_config_31_protocol[] = {
|
||||
{ "/dev/binder", "aidl4" },
|
||||
{ "/dev/vndbinder", "aidl4" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const GBinderConfigPresetGroup gbinder_config_31[] = {
|
||||
{ GBINDER_CONFIG_GROUP_PROTOCOL, gbinder_config_31_protocol },
|
||||
{ GBINDER_CONFIG_GROUP_SERVICEMANAGER, gbinder_config_30_servicemanager },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* API level 33 - reverts back to AIDL3 protocol */
|
||||
|
||||
static const GBinderConfigPresetGroup gbinder_config_33[] = {
|
||||
{ GBINDER_CONFIG_GROUP_PROTOCOL, gbinder_config_30_protocol },
|
||||
{ GBINDER_CONFIG_GROUP_SERVICEMANAGER, gbinder_config_31_servicemanager },
|
||||
{ GBINDER_CONFIG_GROUP_SERVICEMANAGER, gbinder_config_30_servicemanager },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Presets sorted by API level in descending order */
|
||||
|
||||
static const GBinderConfigPreset gbinder_config_presets[] = {
|
||||
{ 33, gbinder_config_33 },
|
||||
{ 31, gbinder_config_31 },
|
||||
{ 30, gbinder_config_30 },
|
||||
{ 29, gbinder_config_29 },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -813,7 +813,7 @@ gbinder_driver_txstatus(
|
||||
gbinder_driver_verbose_transaction_data("BR_REPLY", &tx);
|
||||
|
||||
/* Transfer data ownership to the reply */
|
||||
if (tx.data && tx.size) {
|
||||
if (tx.data && tx.size && reply) {
|
||||
GBinderBuffer* buf = gbinder_buffer_new(self,
|
||||
tx.data, tx.size, tx.objects);
|
||||
|
||||
@@ -1173,7 +1173,7 @@ gbinder_driver_free_buffer(
|
||||
write.ptr = (uintptr_t)wbuf;
|
||||
write.size = len;
|
||||
write.consumed = 0;
|
||||
gbinder_driver_write(self, &write);
|
||||
(void) gbinder_driver_write(self, &write);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -175,12 +175,10 @@ GBINDER_IO_FN(encode_local_object)(
|
||||
struct flat_binder_object* dest = out;
|
||||
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
dest->hdr.type = BINDER_TYPE_BINDER;
|
||||
if (obj) {
|
||||
dest->hdr.type = BINDER_TYPE_BINDER;
|
||||
dest->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
|
||||
dest->binder = (uintptr_t)obj;
|
||||
} else {
|
||||
dest->hdr.type = BINDER_TYPE_HANDLE;
|
||||
}
|
||||
if (protocol->finish_flatten_binder) {
|
||||
protocol->finish_flatten_binder(dest + 1, obj);
|
||||
|
||||
@@ -905,28 +905,25 @@ gbinder_ipc_looper_check(
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
GBinderIpcPriv* priv = self->priv;
|
||||
GBinderIpcLooper* new_looper = NULL;
|
||||
|
||||
/* Lock */
|
||||
g_mutex_lock(&priv->looper_mutex);
|
||||
if (!priv->primary_loopers) {
|
||||
GBinderIpcLooper* looper;
|
||||
priv->primary_loopers = gbinder_ipc_looper_new(self);
|
||||
new_looper = priv->primary_loopers;
|
||||
if (new_looper) {
|
||||
gbinder_ipc_looper_ref(new_looper);
|
||||
}
|
||||
}
|
||||
g_mutex_unlock(&priv->looper_mutex);
|
||||
/* Unlock */
|
||||
|
||||
/* Lock */
|
||||
g_mutex_lock(&priv->looper_mutex);
|
||||
if (!priv->primary_loopers) {
|
||||
priv->primary_loopers = gbinder_ipc_looper_new(self);
|
||||
}
|
||||
looper = priv->primary_loopers;
|
||||
if (looper) {
|
||||
gbinder_ipc_looper_ref(looper);
|
||||
}
|
||||
g_mutex_unlock(&priv->looper_mutex);
|
||||
/* Unlock */
|
||||
|
||||
/* We are not ready to accept incoming transactions until
|
||||
* looper has started. We may need to wait a bit. */
|
||||
if (looper) {
|
||||
gbinder_ipc_looper_start(looper);
|
||||
gbinder_ipc_looper_unref(looper);
|
||||
}
|
||||
/* We are not ready to accept incoming transactions until
|
||||
* looper has started. We may need to wait a bit. */
|
||||
if (new_looper) {
|
||||
gbinder_ipc_looper_start(new_looper);
|
||||
gbinder_ipc_looper_unref(new_looper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -442,6 +442,7 @@ gbinder_local_object_init_base(
|
||||
|
||||
self->ipc = gbinder_ipc_ref(ipc);
|
||||
self->ifaces = (const char**)priv->ifaces;
|
||||
self->stability = GBINDER_STABILITY_SYSTEM;
|
||||
priv->txproc = txproc;
|
||||
priv->user_data = user_data;
|
||||
}
|
||||
@@ -611,6 +612,16 @@ gbinder_local_object_handle_release(
|
||||
gbinder_local_object_handle_later(self, gbinder_local_object_release_proc);
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_object_set_stability(
|
||||
GBinderLocalObject* self,
|
||||
GBINDER_STABILITY_LEVEL stability) /* Since 1.1.40 */
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
self->stability = stability;
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internals
|
||||
*==========================================================================*/
|
||||
|
||||
@@ -59,6 +59,7 @@ struct gbinder_local_object {
|
||||
const char* const* ifaces;
|
||||
gint weak_refs;
|
||||
gint strong_refs;
|
||||
GBINDER_STABILITY_LEVEL stability;
|
||||
};
|
||||
|
||||
typedef enum gbinder_local_transaction_support {
|
||||
|
||||
@@ -617,6 +617,7 @@ gbinder_reader_read_hidl_string_vec(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The equivalent of Android's Parcel::readCString */
|
||||
const char*
|
||||
gbinder_reader_read_string8(
|
||||
GBinderReader* reader)
|
||||
@@ -641,6 +642,49 @@ gbinder_reader_read_string8(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The equivalent of Android's Parcel::readString8 */
|
||||
gboolean
|
||||
gbinder_reader_read_nullable_string8(
|
||||
GBinderReader* reader,
|
||||
const char** out,
|
||||
gsize* out_len) /* Since 1.1.41 */
|
||||
{
|
||||
GBinderReaderPriv* p = gbinder_reader_cast(reader);
|
||||
|
||||
if ((p->ptr + 4) <= p->end) {
|
||||
const gint32* len_ptr = (gint32*)p->ptr;
|
||||
const gint32 len = *len_ptr;
|
||||
|
||||
if (len == -1) {
|
||||
/* NULL string */
|
||||
p->ptr += 4;
|
||||
if (out) {
|
||||
*out = NULL;
|
||||
}
|
||||
if (out_len) {
|
||||
*out_len = 0;
|
||||
}
|
||||
return TRUE;
|
||||
} else if (len >= 0) {
|
||||
const guint32 padded_len = G_ALIGN4(len + 1);
|
||||
const char* str = (char*)(p->ptr + 4);
|
||||
|
||||
if ((p->ptr + padded_len + 4) <= p->end && !str[len]) {
|
||||
p->ptr += padded_len + 4;
|
||||
if (out) {
|
||||
*out = str;
|
||||
}
|
||||
if (out_len) {
|
||||
*out_len = len;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The equivalent of Android's Parcel::readString16 */
|
||||
gboolean
|
||||
gbinder_reader_read_nullable_string16(
|
||||
GBinderReader* reader,
|
||||
@@ -682,17 +726,20 @@ gbinder_reader_read_nullable_string16_utf16(
|
||||
return TRUE;
|
||||
} else if (len >= 0) {
|
||||
const guint32 padded_len = G_ALIGN4((len + 1)*2);
|
||||
const gunichar2* utf16 = (gunichar2*)(p->ptr + 4);
|
||||
|
||||
if ((p->ptr + padded_len + 4) <= p->end) {
|
||||
p->ptr += padded_len + 4;
|
||||
if (out) {
|
||||
*out = utf16;
|
||||
const gunichar2* utf16 = (gunichar2*)(p->ptr + 4);
|
||||
|
||||
if (!utf16[len]) {
|
||||
p->ptr += padded_len + 4;
|
||||
if (out) {
|
||||
*out = utf16;
|
||||
}
|
||||
if (out_len) {
|
||||
*out_len = len;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (out_len) {
|
||||
*out_len = len;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -728,26 +775,7 @@ gboolean
|
||||
gbinder_reader_skip_string16(
|
||||
GBinderReader* reader)
|
||||
{
|
||||
GBinderReaderPriv* p = gbinder_reader_cast(reader);
|
||||
|
||||
if ((p->ptr + 4) <= p->end) {
|
||||
const gint32* len_ptr = (gint32*)p->ptr;
|
||||
const gint32 len = *len_ptr;
|
||||
|
||||
if (len == -1) {
|
||||
/* NULL string */
|
||||
p->ptr += 4;
|
||||
return TRUE;
|
||||
} else if (len >= 0) {
|
||||
const guint32 padded_len = G_ALIGN4((len+1)*2);
|
||||
|
||||
if ((p->ptr + padded_len + 4) <= p->end) {
|
||||
p->ptr += padded_len + 4;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return gbinder_reader_read_nullable_string16_utf16(reader, NULL, NULL);
|
||||
}
|
||||
|
||||
const void*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -73,15 +73,12 @@ gbinder_remote_reply_set_data(
|
||||
GBinderRemoteReply* self,
|
||||
GBinderBuffer* buffer)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
GBinderReaderData* data = &self->data;
|
||||
/* The caller checks the pointer for NULL */
|
||||
GBinderReaderData* data = &self->data;
|
||||
|
||||
gbinder_buffer_free(data->buffer);
|
||||
data->buffer = buffer;
|
||||
data->objects = gbinder_buffer_objects(buffer);
|
||||
} else {
|
||||
gbinder_buffer_free(buffer);
|
||||
}
|
||||
gbinder_buffer_free(data->buffer);
|
||||
data->buffer = buffer;
|
||||
data->objects = gbinder_buffer_objects(buffer);
|
||||
}
|
||||
|
||||
GBinderRemoteReply*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -162,29 +162,25 @@ gbinder_remote_request_set_data(
|
||||
guint32 txcode,
|
||||
GBinderBuffer* buffer)
|
||||
{
|
||||
/* The caller never passes NULL req */
|
||||
GBinderRemoteRequestPriv* self = gbinder_remote_request_cast(req);
|
||||
GBinderReaderData* data = &self->data;
|
||||
GBinderReader reader;
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GBinderReaderData* data = &self->data;
|
||||
GBinderReader reader;
|
||||
g_free(self->iface2);
|
||||
gbinder_buffer_free(data->buffer);
|
||||
data->buffer = buffer;
|
||||
data->objects = gbinder_buffer_objects(buffer);
|
||||
|
||||
g_free(self->iface2);
|
||||
gbinder_buffer_free(data->buffer);
|
||||
data->buffer = buffer;
|
||||
data->objects = gbinder_buffer_objects(buffer);
|
||||
|
||||
/* Parse RPC header */
|
||||
gbinder_remote_request_init_reader2(self, &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;
|
||||
}
|
||||
/* Parse RPC header */
|
||||
gbinder_remote_request_init_reader2(self, &reader);
|
||||
self->iface = self->protocol->read_rpc_header(&reader, txcode,
|
||||
&self->iface2);
|
||||
if (self->iface) {
|
||||
self->header_size = gbinder_reader_bytes_read(&reader);
|
||||
} else {
|
||||
gbinder_buffer_free(buffer);
|
||||
/* No RPC header */
|
||||
self->header_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include "gbinder_writer.h"
|
||||
#include "gbinder_config.h"
|
||||
#include "gbinder_log.h"
|
||||
#include "gbinder_local_object_p.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
|
||||
#define BINDER_RPC_FLAGS (STRICT_MODE_PENALTY_GATHER)
|
||||
@@ -218,7 +221,11 @@ gbinder_rpc_protocol_aidl3_finish_flatten_binder(
|
||||
void* out,
|
||||
GBinderLocalObject* obj)
|
||||
{
|
||||
*(guint32*)out = GBINDER_STABILITY_SYSTEM;
|
||||
if (G_LIKELY(obj)) {
|
||||
*(guint32*)out = obj->stability;
|
||||
} else {
|
||||
*(guint32*)out = GBINDER_STABILITY_UNDECLARED;
|
||||
}
|
||||
}
|
||||
|
||||
static const GBinderRpcProtocol gbinder_rpc_protocol_aidl3 = {
|
||||
@@ -231,6 +238,44 @@ static const GBinderRpcProtocol gbinder_rpc_protocol_aidl3 = {
|
||||
.finish_flatten_binder = gbinder_rpc_protocol_aidl3_finish_flatten_binder
|
||||
};
|
||||
|
||||
/*==========================================================================*
|
||||
* AIDL protocol appeared in Android 12 (API level 31), but reverted in
|
||||
* Android 13 (API level 33).
|
||||
*==========================================================================*/
|
||||
|
||||
#define BINDER_WIRE_FORMAT_VERSION_AIDL4 1
|
||||
struct stability_category {
|
||||
guint8 binder_wire_format_version;
|
||||
guint8 reserved[2];
|
||||
guint8 stability_level;
|
||||
};
|
||||
G_STATIC_ASSERT(sizeof(struct stability_category) == sizeof(guint32));
|
||||
|
||||
static
|
||||
void
|
||||
gbinder_rpc_protocol_aidl4_finish_flatten_binder(
|
||||
void* out,
|
||||
GBinderLocalObject* obj)
|
||||
{
|
||||
struct stability_category cat = {
|
||||
.binder_wire_format_version = BINDER_WIRE_FORMAT_VERSION_AIDL4,
|
||||
.reserved = { 0, 0, },
|
||||
.stability_level = obj ? obj->stability : GBINDER_STABILITY_UNDECLARED,
|
||||
};
|
||||
|
||||
memcpy(out, &cat, sizeof(cat));
|
||||
}
|
||||
|
||||
static const GBinderRpcProtocol gbinder_rpc_protocol_aidl4 = {
|
||||
.name = "aidl4",
|
||||
.ping_tx = GBINDER_PING_TRANSACTION,
|
||||
.write_ping = gbinder_rpc_protocol_aidl_write_ping, /* no payload */
|
||||
.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
|
||||
};
|
||||
|
||||
/*==========================================================================*
|
||||
* The original /dev/hwbinder protocol.
|
||||
*==========================================================================*/
|
||||
@@ -284,6 +329,7 @@ static const GBinderRpcProtocol* gbinder_rpc_protocol_list[] = {
|
||||
&gbinder_rpc_protocol_aidl,
|
||||
&gbinder_rpc_protocol_aidl2,
|
||||
&gbinder_rpc_protocol_aidl3,
|
||||
&gbinder_rpc_protocol_aidl4,
|
||||
&gbinder_rpc_protocol_hidl
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -993,36 +993,33 @@ gbinder_servicemanager_remove_handlers(
|
||||
guint count) /* Since 1.0.25 */
|
||||
{
|
||||
if (G_LIKELY(self) && G_LIKELY(ids) && G_LIKELY(count)) {
|
||||
guint i, disconnected = 0;
|
||||
GBinderServiceManagerClass* klass =
|
||||
GBINDER_SERVICEMANAGER_GET_CLASS(self);
|
||||
GBinderServiceManagerPriv* priv = self->priv;
|
||||
GHashTableIter it;
|
||||
gpointer value;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (ids[i]) {
|
||||
g_signal_handler_disconnect(self, ids[i]);
|
||||
disconnected++;
|
||||
ids[i] = 0;
|
||||
}
|
||||
}
|
||||
gutil_disconnect_handlers(self, ids, count);
|
||||
|
||||
if (disconnected) {
|
||||
GBinderServiceManagerClass* klass =
|
||||
GBINDER_SERVICEMANAGER_GET_CLASS(self);
|
||||
GBinderServiceManagerPriv* priv = self->priv;
|
||||
GHashTableIter it;
|
||||
gpointer value;
|
||||
/*
|
||||
* Regardless of whether we have actually removed any handlers, still
|
||||
* check all watchers because there's a possibility that some handlers
|
||||
* got removed with a straight g_signal_handler_disconnect() call.
|
||||
*/
|
||||
g_hash_table_iter_init(&it, priv->watch_table);
|
||||
while (g_hash_table_iter_next(&it, NULL, &value)) {
|
||||
GBinderServiceManagerWatch* watch = value;
|
||||
|
||||
g_hash_table_iter_init(&it, priv->watch_table);
|
||||
while (disconnected && g_hash_table_iter_next(&it, NULL, &value)) {
|
||||
GBinderServiceManagerWatch* watch = value;
|
||||
|
||||
if (watch->watched && !g_signal_has_handler_pending(self,
|
||||
gbinder_servicemanager_signals[SIGNAL_REGISTRATION],
|
||||
watch->quark, TRUE)) {
|
||||
/* This must be one of those we have just removed */
|
||||
GDEBUG("Unwatching %s", watch->name);
|
||||
if (!g_signal_has_handler_pending(self,
|
||||
gbinder_servicemanager_signals[SIGNAL_REGISTRATION],
|
||||
watch->quark, TRUE)) {
|
||||
/* No need to keep the watch around if no one is listening */
|
||||
GDEBUG("Dropping watch %s", watch->name);
|
||||
if (watch->watched) {
|
||||
watch->watched = FALSE;
|
||||
klass->unwatch(self, watch->name);
|
||||
disconnected--;
|
||||
}
|
||||
g_hash_table_iter_remove(&it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -45,8 +45,15 @@
|
||||
typedef struct gbinder_servicemanager_hidl_watch {
|
||||
char* name;
|
||||
GBinderLocalObject* callback;
|
||||
GBinderClient* client;
|
||||
gulong tx_id;
|
||||
} GBinderServiceManagerHidlWatch;
|
||||
|
||||
typedef struct gbinder_servicemanager_hidl_watch_call {
|
||||
GBinderLocalObject* callback;
|
||||
GBinderServiceManagerHidlWatch* watch;
|
||||
} GBinderServiceManagerHidlWatchCall;
|
||||
|
||||
typedef GBinderServiceManagerClass GBinderServiceManagerHidlClass;
|
||||
typedef struct gbinder_servicemanager_hidl {
|
||||
GBinderServiceManager manager;
|
||||
@@ -253,11 +260,68 @@ gbinder_servicemanager_hidl_watch_free(
|
||||
{
|
||||
GBinderServiceManagerHidlWatch* watch = data;
|
||||
|
||||
g_free(watch->name);
|
||||
gbinder_local_object_drop(watch->callback);
|
||||
gbinder_client_cancel(watch->client, watch->tx_id);
|
||||
gbinder_client_unref(watch->client);
|
||||
g_free(watch->name);
|
||||
g_free(watch);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gbinder_servicemanager_hidl_watch_call_reply(
|
||||
GBinderClient* client,
|
||||
GBinderRemoteReply* reply,
|
||||
int tx_status,
|
||||
void* user_data)
|
||||
{
|
||||
GBinderServiceManagerHidlWatchCall* call = user_data;
|
||||
GBinderServiceManagerHidlWatch* watch = call->watch;
|
||||
|
||||
/*
|
||||
* We can only get here if the call wasn't cancelled by
|
||||
* gbinder_servicemanager_hidl_watch_free() meaning that
|
||||
* we can safely access GBinderServiceManagerHidlWatch.
|
||||
*/
|
||||
watch->tx_id = 0;
|
||||
if (tx_status == GBINDER_STATUS_OK) {
|
||||
GBinderReader reader;
|
||||
gint32 status;
|
||||
gboolean success;
|
||||
|
||||
gbinder_remote_reply_init_reader(reply, &reader);
|
||||
if (gbinder_reader_read_int32(&reader, &status) &&
|
||||
gbinder_reader_read_bool(&reader, &success)) {
|
||||
if (status == GBINDER_STATUS_OK && success) {
|
||||
/* Successfully registered */
|
||||
return;
|
||||
} else {
|
||||
GWARN("registerForNotifications(%s) failed", watch->name);
|
||||
}
|
||||
} else {
|
||||
GWARN("Unexpected registerForNotifications(%s) reply", watch->name);
|
||||
}
|
||||
} else {
|
||||
GWARN("registerForNotifications(%s) tx failed", watch->name);
|
||||
}
|
||||
|
||||
/* There's no need to keep this object around if its registration failed */
|
||||
gbinder_local_object_drop(watch->callback);
|
||||
watch->callback = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gbinder_servicemanager_hidl_watch_call_destroy(
|
||||
void* user_data)
|
||||
{
|
||||
GBinderServiceManagerHidlWatchCall* call = user_data;
|
||||
|
||||
/* call->watch may be destroyed by now, don't touch it */
|
||||
gbinder_local_object_unref(call->callback);
|
||||
g_free(call);
|
||||
}
|
||||
|
||||
static
|
||||
GBINDER_SERVICEMANAGER_NAME_CHECK
|
||||
gbinder_servicemanager_hidl_check_name(
|
||||
@@ -297,13 +361,13 @@ gbinder_servicemanager_hidl_watch(
|
||||
{
|
||||
GBinderServiceManagerHidl* self = GBINDER_SERVICEMANAGER_HIDL(manager);
|
||||
GBinderLocalRequest* req = gbinder_client_new_request(manager->client);
|
||||
GBinderRemoteReply* reply;
|
||||
GBinderServiceManagerHidlWatch* watch =
|
||||
g_new0(GBinderServiceManagerHidlWatch, 1);
|
||||
gboolean success = FALSE;
|
||||
int status;
|
||||
GBinderServiceManagerHidlWatchCall* call =
|
||||
g_new0(GBinderServiceManagerHidlWatchCall, 1);
|
||||
|
||||
watch->name = g_strdup(name);
|
||||
watch->client = gbinder_client_ref(manager->client);
|
||||
watch->callback = gbinder_servicemanager_new_local_object(manager,
|
||||
SERVICEMANAGER_HIDL_NOTIFICATION_IFACE,
|
||||
gbinder_servicemanager_hidl_notification, self);
|
||||
@@ -314,26 +378,37 @@ gbinder_servicemanager_hidl_watch(
|
||||
gbinder_local_request_append_hidl_string(req, name);
|
||||
gbinder_local_request_append_hidl_string(req, "");
|
||||
gbinder_local_request_append_local_object(req, watch->callback);
|
||||
reply = gbinder_client_transact_sync_reply(manager->client,
|
||||
REGISTER_FOR_NOTIFICATIONS_TRANSACTION, req, &status);
|
||||
|
||||
if (status == GBINDER_STATUS_OK && reply) {
|
||||
GBinderReader reader;
|
||||
|
||||
gbinder_remote_reply_init_reader(reply, &reader);
|
||||
if (gbinder_reader_read_int32(&reader, &status) &&
|
||||
status == GBINDER_STATUS_OK) {
|
||||
gbinder_reader_read_bool(&reader, &success);
|
||||
}
|
||||
}
|
||||
gbinder_remote_reply_unref(reply);
|
||||
/*
|
||||
* GBinderServiceManagerHidlWatchCall keeps the additional reference
|
||||
* to the callback object for the duration of the transaction. Since
|
||||
* the transaction is asynchronous, the object may be unrefed before
|
||||
* the transaction actually gets submitted, and we don't want to pass
|
||||
* an invalid object pointer to the kernel. This extra ref makes sure
|
||||
* that the pointer remains valid.
|
||||
*/
|
||||
call->watch = watch;
|
||||
call->callback = gbinder_local_object_ref(watch->callback);
|
||||
watch->tx_id = gbinder_client_transact(watch->client,
|
||||
REGISTER_FOR_NOTIFICATIONS_TRANSACTION, 0, req,
|
||||
gbinder_servicemanager_hidl_watch_call_reply,
|
||||
gbinder_servicemanager_hidl_watch_call_destroy, call);
|
||||
gbinder_local_request_unref(req);
|
||||
|
||||
if (!success) {
|
||||
if (watch->tx_id) {
|
||||
/*
|
||||
* At this point, we don't really know whether the registration
|
||||
* will actually succeed. Since in the worst case we just won't
|
||||
* get any notifications, I don't see a good enough reason to
|
||||
* complicate the internal interface to handle such an unlikely
|
||||
* and non-critical issue.
|
||||
*/
|
||||
return TRUE;
|
||||
} else {
|
||||
/* unwatch() won't be called if we return FALSE */
|
||||
g_hash_table_remove(self->watch_table, watch->name);
|
||||
return FALSE;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -40,13 +40,12 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
typedef struct gbinder_servicemanager_priv GBinderServiceManagerPriv;
|
||||
|
||||
typedef struct gbinder_servicemanager {
|
||||
struct gbinder_servicemanager {
|
||||
GObject parent;
|
||||
GBinderServiceManagerPriv* priv;
|
||||
const char* dev;
|
||||
GBinderClient* client;
|
||||
} GBinderServiceManager;
|
||||
};
|
||||
|
||||
typedef enum gbinder_servicemanager_name_check {
|
||||
GBINDER_SERVICEMANAGER_NAME_OK,
|
||||
|
||||
@@ -77,13 +77,6 @@ typedef struct gbinder_ipc_sync_api GBinderIpcSyncApi;
|
||||
/* As a special case, ServiceManager's handle is zero */
|
||||
#define GBINDER_SERVICEMANAGER_HANDLE (0)
|
||||
|
||||
typedef enum gbinder_stability_level {
|
||||
GBINDER_STABILITY_UNDECLARED = 0,
|
||||
GBINDER_STABILITY_VENDOR = 0x03,
|
||||
GBINDER_STABILITY_SYSTEM = 0x0c,
|
||||
GBINDER_STABILITY_VINTF = 0x3f
|
||||
} GBINDER_STABILITY_LEVEL;
|
||||
|
||||
#endif /* GBINDER_TYPES_PRIVATE_H */
|
||||
|
||||
/*
|
||||
|
||||
@@ -1176,8 +1176,11 @@ gbinder_writer_data_append_local_object(
|
||||
n = data->io->encode_local_object(buf->data + offset, obj, data->protocol);
|
||||
/* Fix the data size */
|
||||
g_byte_array_set_size(buf, offset + n);
|
||||
/* Record the offset */
|
||||
gbinder_writer_data_record_offset(data, offset);
|
||||
|
||||
if (obj) {
|
||||
/* Record the offset */
|
||||
gbinder_writer_data_record_offset(data, offset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1308,8 +1311,11 @@ gbinder_writer_data_append_remote_object(
|
||||
n = data->io->encode_remote_object(buf->data + offset, obj);
|
||||
/* Fix the data size */
|
||||
g_byte_array_set_size(buf, offset + n);
|
||||
/* Record the offset */
|
||||
gbinder_writer_data_record_offset(data, offset);
|
||||
|
||||
if (obj) {
|
||||
/* Record the offset */
|
||||
gbinder_writer_data_record_offset(data, offset);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -531,11 +531,25 @@ static const TestPresetsData test_presets_data [] = {
|
||||
"[General]\n"
|
||||
"ApiLevel = 31\n"
|
||||
"[Protocol]\n"
|
||||
"/dev/binder = aidl4\n"
|
||||
"/dev/vndbinder = aidl4\n"
|
||||
"[ServiceManager]\n"
|
||||
"/dev/binder = aidl3\n"
|
||||
"/dev/vndbinder = aidl3\n"
|
||||
},{
|
||||
"33",
|
||||
|
||||
"[General]\n"
|
||||
"ApiLevel = 33",
|
||||
|
||||
"[General]\n"
|
||||
"ApiLevel = 33\n"
|
||||
"[Protocol]\n"
|
||||
"/dev/binder = aidl3\n"
|
||||
"/dev/vndbinder = aidl3\n"
|
||||
"[ServiceManager]\n"
|
||||
"/dev/binder = aidl4\n"
|
||||
"/dev/vndbinder = aidl4\n"
|
||||
"/dev/binder = aidl3\n"
|
||||
"/dev/vndbinder = aidl3\n"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
static TestOpt test_opt;
|
||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-ipc-XXXXXX";
|
||||
|
||||
static
|
||||
gboolean
|
||||
@@ -1346,6 +1347,9 @@ test_cancel_on_exit(
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConfig test_config;
|
||||
int result;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
g_type_init();
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
@@ -1375,7 +1379,10 @@ int main(int argc, char* argv[])
|
||||
g_test_add_func(TEST_("drop_remote_refs"), test_drop_remote_refs);
|
||||
g_test_add_func(TEST_("cancel_on_exit"), test_cancel_on_exit);
|
||||
test_init(&test_opt, argc, argv);
|
||||
return g_test_run();
|
||||
test_config_init(&test_config, TMP_DIR_TEMPLATE);
|
||||
result = g_test_run();
|
||||
test_config_cleanup(&test_config);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
@@ -140,6 +140,8 @@ test_null(
|
||||
gbinder_local_object_handle_decrefs(NULL);
|
||||
gbinder_local_object_handle_acquire(NULL, NULL);
|
||||
gbinder_local_object_handle_release(NULL);
|
||||
gbinder_local_object_handle_release(NULL);
|
||||
gbinder_local_object_set_stability(NULL, GBINDER_STABILITY_UNDECLARED);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <gutil_intarray.h>
|
||||
|
||||
static TestOpt test_opt;
|
||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-local-reply-XXXXXX";
|
||||
|
||||
static
|
||||
void
|
||||
@@ -453,10 +454,7 @@ test_local_object(
|
||||
reply = test_local_reply_new();
|
||||
gbinder_local_reply_append_local_object(reply, NULL);
|
||||
data = gbinder_local_reply_data(reply);
|
||||
offsets = gbinder_output_data_offsets(data);
|
||||
g_assert(offsets);
|
||||
g_assert_cmpuint(offsets->count, == ,1);
|
||||
g_assert_cmpuint(offsets->data[0], == ,0);
|
||||
g_assert(!gbinder_output_data_offsets(data));
|
||||
g_assert_cmpuint(gbinder_output_data_buffers_size(data), == ,0);
|
||||
g_assert_cmpuint(data->bytes->len, == ,BINDER_OBJECT_SIZE_32);
|
||||
gbinder_local_reply_unref(reply);
|
||||
@@ -474,14 +472,10 @@ test_remote_object(
|
||||
{
|
||||
GBinderLocalReply* reply = test_local_reply_new();
|
||||
GBinderOutputData* data;
|
||||
GUtilIntArray* offsets;
|
||||
|
||||
gbinder_local_reply_append_remote_object(reply, NULL);
|
||||
data = gbinder_local_reply_data(reply);
|
||||
offsets = gbinder_output_data_offsets(data);
|
||||
g_assert(offsets);
|
||||
g_assert(offsets->count == 1);
|
||||
g_assert(offsets->data[0] == 0);
|
||||
g_assert(!gbinder_output_data_offsets(data));
|
||||
g_assert(!gbinder_output_data_buffers_size(data));
|
||||
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_32);
|
||||
gbinder_local_reply_unref(reply);
|
||||
@@ -538,6 +532,9 @@ test_remote_reply(
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConfig test_config;
|
||||
int result;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
g_type_init();
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
@@ -558,7 +555,10 @@ int main(int argc, char* argv[])
|
||||
g_test_add_func(TEST_PREFIX "remote_object", test_remote_object);
|
||||
g_test_add_func(TEST_PREFIX "remote_reply", test_remote_reply);
|
||||
test_init(&test_opt, argc, argv);
|
||||
return g_test_run();
|
||||
test_config_init(&test_config, TMP_DIR_TEMPLATE);
|
||||
result = g_test_run();
|
||||
test_config_cleanup(&test_config);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "test_common.h"
|
||||
#include "test_binder.h"
|
||||
|
||||
#include "gbinder_local_object.h"
|
||||
#include "gbinder_local_request_p.h"
|
||||
#include "gbinder_output_data.h"
|
||||
#include "gbinder_rpc_protocol.h"
|
||||
@@ -40,10 +41,12 @@
|
||||
#include "gbinder_driver.h"
|
||||
#include "gbinder_writer.h"
|
||||
#include "gbinder_io.h"
|
||||
#include "gbinder_ipc.h"
|
||||
|
||||
#include <gutil_intarray.h>
|
||||
|
||||
static TestOpt test_opt;
|
||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-local-request-XXXXXX";
|
||||
|
||||
static
|
||||
void
|
||||
@@ -431,19 +434,36 @@ void
|
||||
test_local_object(
|
||||
void)
|
||||
{
|
||||
GBinderLocalRequest* req = test_local_request_new();
|
||||
GBinderLocalRequest* req;
|
||||
GBinderOutputData* data;
|
||||
GUtilIntArray* offsets;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(NULL, NULL);
|
||||
const char* const ifaces[] = { "android.hidl.base@1.0::IBase", NULL };
|
||||
GBinderLocalObject* obj = gbinder_local_object_new(ipc, ifaces, NULL, NULL);
|
||||
|
||||
gbinder_local_request_append_local_object(req, NULL);
|
||||
/* Append a real object */
|
||||
req = test_local_request_new();
|
||||
gbinder_local_request_append_local_object(req, obj);
|
||||
data = gbinder_local_request_data(req);
|
||||
offsets = gbinder_output_data_offsets(data);
|
||||
g_assert(offsets);
|
||||
g_assert(offsets->count == 1);
|
||||
g_assert(offsets->data[0] == 0);
|
||||
g_assert_cmpuint(offsets->count, == ,1);
|
||||
g_assert_cmpuint(offsets->data[0], == ,0);
|
||||
g_assert_cmpuint(gbinder_output_data_buffers_size(data), == ,0);
|
||||
g_assert_cmpuint(data->bytes->len, == ,BINDER_OBJECT_SIZE_32);
|
||||
gbinder_local_request_unref(req);
|
||||
|
||||
/* Append NULL object */
|
||||
req = test_local_request_new();
|
||||
gbinder_local_request_append_local_object(req, NULL);
|
||||
data = gbinder_local_request_data(req);
|
||||
g_assert(!gbinder_output_data_offsets(data));
|
||||
g_assert(!gbinder_output_data_buffers_size(data));
|
||||
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_32);
|
||||
gbinder_local_request_unref(req);
|
||||
|
||||
gbinder_local_object_unref(obj);
|
||||
gbinder_ipc_unref(ipc);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
@@ -457,14 +477,10 @@ test_remote_object(
|
||||
{
|
||||
GBinderLocalRequest* req = test_local_request_new();
|
||||
GBinderOutputData* data;
|
||||
GUtilIntArray* offsets;
|
||||
|
||||
gbinder_local_request_append_remote_object(req, NULL);
|
||||
data = gbinder_local_request_data(req);
|
||||
offsets = gbinder_output_data_offsets(data);
|
||||
g_assert(offsets);
|
||||
g_assert(offsets->count == 1);
|
||||
g_assert(offsets->data[0] == 0);
|
||||
g_assert(!gbinder_output_data_offsets(data));
|
||||
g_assert(!gbinder_output_data_buffers_size(data));
|
||||
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_32);
|
||||
gbinder_local_request_unref(req);
|
||||
@@ -538,12 +554,10 @@ test_remote_request_obj_validate_data(
|
||||
const GByteArray* bytes = data->bytes;
|
||||
GUtilIntArray* offsets = gbinder_output_data_offsets(data);
|
||||
|
||||
offsets = gbinder_output_data_offsets(data);
|
||||
g_assert(offsets);
|
||||
g_assert(offsets->count == 3);
|
||||
g_assert(offsets->count == 2);
|
||||
g_assert(offsets->data[0] == 4);
|
||||
g_assert(offsets->data[1] == 4 + BUFFER_OBJECT_SIZE_64);
|
||||
g_assert(offsets->data[2] == 4 + 2*BUFFER_OBJECT_SIZE_64);
|
||||
g_assert(bytes->len == 4 + 2*BUFFER_OBJECT_SIZE_64 + BINDER_OBJECT_SIZE_64);
|
||||
/* GBinderHidlString + the contents (2 bytes) aligned at 8-byte boundary */
|
||||
g_assert(gbinder_output_data_buffers_size(data) ==
|
||||
@@ -600,6 +614,9 @@ test_remote_request_obj(
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConfig test_config;
|
||||
int result;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
g_test_add_func(TEST_PREFIX "null", test_null);
|
||||
g_test_add_func(TEST_PREFIX "cleanup", test_cleanup);
|
||||
@@ -618,7 +635,10 @@ int main(int argc, char* argv[])
|
||||
g_test_add_func(TEST_PREFIX "remote_request", test_remote_request);
|
||||
g_test_add_func(TEST_PREFIX "remote_request_obj", test_remote_request_obj);
|
||||
test_init(&test_opt, argc, argv);
|
||||
return g_test_run();
|
||||
test_config_init(&test_config, TMP_DIR_TEMPLATE);
|
||||
result = g_test_run();
|
||||
test_config_cleanup(&test_config);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2023 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -194,6 +193,7 @@ void
|
||||
test_bool(
|
||||
void)
|
||||
{
|
||||
const guint8 in_short[] = { 0 };
|
||||
const guint8 in_true[] = { TEST_INT8_BYTES_4(TRUE) };
|
||||
const guint8 in_false[] = { TEST_INT8_BYTES_4(FALSE) };
|
||||
gboolean out = FALSE;
|
||||
@@ -203,10 +203,21 @@ test_bool(
|
||||
|
||||
g_assert(driver);
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/* not enough data */
|
||||
data.buffer = gbinder_buffer_new(driver,
|
||||
g_memdup(&in_true, sizeof(in_true)), sizeof(in_true), NULL);
|
||||
g_memdup(TEST_ARRAY_AND_SIZE(in_short)), sizeof(in_short), NULL);
|
||||
|
||||
gbinder_reader_init(&reader, &data, 0, data.buffer->size);
|
||||
g_assert(!gbinder_reader_read_bool(&reader, NULL));
|
||||
g_assert(!gbinder_reader_read_bool(&reader, &out));
|
||||
g_assert(!gbinder_reader_at_end(&reader));
|
||||
|
||||
/* true */
|
||||
gbinder_buffer_free(data.buffer);
|
||||
data.buffer = gbinder_buffer_new(driver,
|
||||
g_memdup(TEST_ARRAY_AND_SIZE(in_true)), sizeof(in_true), NULL);
|
||||
|
||||
gbinder_reader_init(&reader, &data, 0, data.buffer->size);
|
||||
g_assert(gbinder_reader_read_bool(&reader, NULL));
|
||||
g_assert(gbinder_reader_at_end(&reader));
|
||||
@@ -219,7 +230,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), NULL);
|
||||
g_memdup(TEST_ARRAY_AND_SIZE(in_false)), sizeof(in_false), NULL);
|
||||
|
||||
gbinder_reader_init(&reader, &data, 0, data.buffer->size);
|
||||
g_assert(gbinder_reader_read_bool(&reader, NULL));
|
||||
@@ -493,7 +504,7 @@ test_double(
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* string8
|
||||
* cstring
|
||||
*==========================================================================*/
|
||||
|
||||
typedef struct test_string_data {
|
||||
@@ -504,28 +515,28 @@ typedef struct test_string_data {
|
||||
gboolean remaining;
|
||||
} TestStringData;
|
||||
|
||||
static const guint8 test_string8_in_short [] = {
|
||||
static const guint8 test_cstring_in_short [] = {
|
||||
't', 'e', 's', 't', 0, 0, 0
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_basic1 [] = {
|
||||
static const guint8 test_cstring_in_basic1 [] = {
|
||||
't', 'e', 's', 't', 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_basic2 [] = {
|
||||
static const guint8 test_cstring_in_basic2 [] = {
|
||||
't', 'e', 's', 't', 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const TestStringData test_string8_tests [] = {
|
||||
{ "short", TEST_ARRAY_AND_SIZE(test_string8_in_short), NULL,
|
||||
sizeof(test_string8_in_short)},
|
||||
{ "ok1", TEST_ARRAY_AND_SIZE(test_string8_in_basic1), "test", 0 },
|
||||
{ "ok2", TEST_ARRAY_AND_SIZE(test_string8_in_basic2), "test", 1 }
|
||||
static const TestStringData test_cstring_tests [] = {
|
||||
{ "err", TEST_ARRAY_AND_SIZE(test_cstring_in_short), NULL,
|
||||
sizeof(test_cstring_in_short)},
|
||||
{ "ok1", TEST_ARRAY_AND_SIZE(test_cstring_in_basic1), "test", 0 },
|
||||
{ "ok2", TEST_ARRAY_AND_SIZE(test_cstring_in_basic2), "test", 1 }
|
||||
};
|
||||
|
||||
static
|
||||
void
|
||||
test_string8(
|
||||
test_cstring(
|
||||
gconstpointer test_data)
|
||||
{
|
||||
const TestStringData* test = test_data;
|
||||
@@ -549,6 +560,119 @@ test_string8(
|
||||
gbinder_driver_unref(driver);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* string8
|
||||
*==========================================================================*/
|
||||
|
||||
static const guint8 test_string8_in_null [] = {
|
||||
TEST_INT32_BYTES(-1)
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_invalid [] = {
|
||||
TEST_INT32_BYTES(-2)
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_short1 [] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_short2 [] = {
|
||||
TEST_INT32_BYTES(3), 'f', 'o', 'o'
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_noterm [] = {
|
||||
TEST_INT32_BYTES(3), 'f', 'o', 'o', 'x' /* Missing terminator */
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_basic1 [] = {
|
||||
TEST_INT32_BYTES(3), 'f', 'o', 'o', 0x00
|
||||
};
|
||||
|
||||
static const guint8 test_string8_in_basic2 [] = {
|
||||
TEST_INT32_BYTES(3), 'f', 'o', 'o', 0x00, 0x00
|
||||
};
|
||||
|
||||
static const TestStringData test_string8_tests [] = {
|
||||
{ "invalid", TEST_ARRAY_AND_SIZE(test_string8_in_invalid), NULL,
|
||||
sizeof(test_string8_in_invalid) },
|
||||
{ "short1", TEST_ARRAY_AND_SIZE(test_string8_in_short1), NULL,
|
||||
sizeof(test_string8_in_short1) },
|
||||
{ "short2", TEST_ARRAY_AND_SIZE(test_string8_in_short2), NULL,
|
||||
sizeof(test_string8_in_short2) },
|
||||
{ "noterm", TEST_ARRAY_AND_SIZE(test_string8_in_noterm), NULL,
|
||||
sizeof(test_string8_in_noterm) },
|
||||
{ "ok1", TEST_ARRAY_AND_SIZE(test_string8_in_basic1), "foo", 0 },
|
||||
{ "ok2", TEST_ARRAY_AND_SIZE(test_string8_in_basic2), "foo", 1 }
|
||||
};
|
||||
|
||||
static
|
||||
void
|
||||
test_string8_null(
|
||||
void)
|
||||
{
|
||||
GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
|
||||
GBinderReader reader;
|
||||
GBinderReaderData data;
|
||||
gsize len = 1;
|
||||
char dummy;
|
||||
const char* out = &dummy;
|
||||
|
||||
g_assert(driver);
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.buffer = gbinder_buffer_new(driver,
|
||||
g_memdup(TEST_ARRAY_AND_SIZE(test_string8_in_null)),
|
||||
sizeof(test_string8_in_null), NULL);
|
||||
|
||||
gbinder_reader_init(&reader, &data, 0, sizeof(test_string8_in_null));
|
||||
g_assert(gbinder_reader_skip_nullable_string8(&reader));
|
||||
g_assert(gbinder_reader_at_end(&reader));
|
||||
|
||||
gbinder_reader_init(&reader, &data, 0, sizeof(test_string8_in_null));
|
||||
g_assert(gbinder_reader_read_nullable_string8(&reader, &out, &len));
|
||||
g_assert(gbinder_reader_at_end(&reader));
|
||||
g_assert(!out);
|
||||
g_assert(!len);
|
||||
|
||||
gbinder_buffer_free(data.buffer);
|
||||
gbinder_driver_unref(driver);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_string8(
|
||||
gconstpointer test_data)
|
||||
{
|
||||
const TestStringData* test = test_data;
|
||||
GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
|
||||
GBinderReader r;
|
||||
GBinderReaderData data;
|
||||
const gboolean valid = (test->out != NULL);
|
||||
const char* out = NULL;
|
||||
gsize len = 0;
|
||||
|
||||
g_assert(driver);
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.buffer = gbinder_buffer_new(driver, g_memdup(test->in, test->in_size),
|
||||
test->in_size, NULL);
|
||||
|
||||
gbinder_reader_init(&r, &data, 0, test->in_size);
|
||||
g_assert(gbinder_reader_skip_nullable_string8(&r) == valid);
|
||||
g_assert(gbinder_reader_at_end(&r) == (!test->remaining));
|
||||
g_assert_cmpuint(gbinder_reader_bytes_remaining(&r), == ,test->remaining);
|
||||
|
||||
gbinder_reader_init(&r, &data, 0, test->in_size);
|
||||
g_assert(gbinder_reader_read_nullable_string8(&r, &out, &len) == valid);
|
||||
g_assert(gbinder_reader_at_end(&r) == (!test->remaining));
|
||||
g_assert_cmpuint(gbinder_reader_bytes_remaining(&r), == ,test->remaining);
|
||||
if (valid) {
|
||||
g_assert_cmpstr(out, ==, test->out);
|
||||
g_assert_cmpuint(len, == ,strlen(test->out));
|
||||
}
|
||||
|
||||
gbinder_buffer_free(data.buffer);
|
||||
gbinder_driver_unref(driver);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* string16
|
||||
*==========================================================================*/
|
||||
@@ -567,6 +691,12 @@ static const guint8 test_string16_in_short [] = {
|
||||
TEST_INT16_BYTES('o'), 0x00
|
||||
};
|
||||
|
||||
static const guint8 test_string16_in_noterm [] = {
|
||||
TEST_INT32_BYTES(3),
|
||||
TEST_INT16_BYTES('f'), TEST_INT16_BYTES('o'),
|
||||
TEST_INT16_BYTES('o'), TEST_INT16_BYTES('o') /* Missing terminator */
|
||||
};
|
||||
|
||||
static const guint8 test_string16_in_basic1 [] = {
|
||||
TEST_INT32_BYTES(3),
|
||||
TEST_INT16_BYTES('f'), TEST_INT16_BYTES('o'),
|
||||
@@ -584,6 +714,8 @@ static const TestStringData test_string16_tests [] = {
|
||||
sizeof(test_string16_in_invalid) },
|
||||
{ "short", TEST_ARRAY_AND_SIZE(test_string16_in_short), NULL,
|
||||
sizeof(test_string16_in_short) },
|
||||
{ "noterm", TEST_ARRAY_AND_SIZE(test_string16_in_noterm), NULL,
|
||||
sizeof(test_string16_in_noterm) },
|
||||
{ "ok1", TEST_ARRAY_AND_SIZE(test_string16_in_basic1), "foo", 0 },
|
||||
{ "ok2", TEST_ARRAY_AND_SIZE(test_string16_in_basic2), "foo", 1 }
|
||||
};
|
||||
@@ -2434,6 +2566,15 @@ int main(int argc, char* argv[])
|
||||
g_test_add_func(TEST_("float"), test_float);
|
||||
g_test_add_func(TEST_("double"), test_double);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(test_cstring_tests); i++) {
|
||||
const TestStringData* test = test_cstring_tests + i;
|
||||
char* path = g_strconcat(TEST_("cstring/"), test->name, NULL);
|
||||
|
||||
g_test_add_data_func(path, test, test_cstring);
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
g_test_add_func(TEST_("string8/null"), test_string8_null);
|
||||
for (i = 0; i < G_N_ELEMENTS(test_string8_tests); i++) {
|
||||
const TestStringData* test = test_string8_tests + i;
|
||||
char* path = g_strconcat(TEST_("string8/"), test->name, NULL);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
*
|
||||
@@ -95,7 +95,6 @@ test_null(
|
||||
|
||||
g_assert(!gbinder_remote_reply_ref(NULL));
|
||||
gbinder_remote_reply_unref(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));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
@@ -74,7 +74,6 @@ test_null(
|
||||
|
||||
g_assert(!gbinder_remote_request_ref(NULL));
|
||||
gbinder_remote_request_unref(NULL);
|
||||
gbinder_remote_request_set_data(NULL, 0, NULL);
|
||||
gbinder_remote_request_init_reader(NULL, &reader);
|
||||
gbinder_remote_request_block(NULL);
|
||||
gbinder_remote_request_complete(NULL, NULL, 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
@@ -449,10 +449,13 @@ test_invalid(
|
||||
{
|
||||
int status = 0;
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
TestConfig config;
|
||||
gulong id = 0;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
test_setup_ping(ipc);
|
||||
g_assert(!gbinder_servicemanager_new2(GBINDER_DEFAULT_HWBINDER, "a", NULL));
|
||||
sm = gbinder_servicemanager_new(dev);
|
||||
@@ -484,6 +487,7 @@ test_invalid(
|
||||
gbinder_servicemanager_unref(sm);
|
||||
gbinder_ipc_unref(ipc);
|
||||
test_binder_exit_wait(&test_opt, NULL);
|
||||
test_config_cleanup(&config);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
@@ -496,12 +500,13 @@ test_basic(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
GBinderLocalObject* obj;
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_servicemanager_new(dev);
|
||||
g_assert(sm);
|
||||
@@ -530,11 +535,12 @@ test_legacy(
|
||||
{
|
||||
const char* otherdev = "/dev/otherbinder";
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_hwservicemanager_new(dev);
|
||||
g_assert(TEST_IS_HWSERVICEMANAGER(sm));
|
||||
@@ -649,12 +655,14 @@ test_not_present(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
const int fd = gbinder_driver_fd(ipc->driver);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
TestConfig config;
|
||||
int fd;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
fd = gbinder_driver_fd(ipc->driver);
|
||||
|
||||
/* This makes presence detection PING fail */
|
||||
test_binder_br_reply_status(fd, THIS_THREAD, -1);
|
||||
@@ -679,16 +687,17 @@ test_wait(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
const int fd = gbinder_driver_fd(ipc->driver);
|
||||
const glong forever = (test_opt.flags & TEST_FLAG_DEBUG) ?
|
||||
(TEST_TIMEOUT_SEC * 1000) : -1;
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
gulong id;
|
||||
int count = 0;
|
||||
int fd, count = 0;
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
fd = gbinder_driver_fd(ipc->driver);
|
||||
|
||||
/* This makes presence detection PING fail */
|
||||
test_binder_br_reply_status(fd, THIS_THREAD, -1);
|
||||
@@ -734,14 +743,15 @@ test_wait_long(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
const int fd = gbinder_driver_fd(ipc->driver);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
gulong id;
|
||||
int count = 0;
|
||||
int fd, count = 0;
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
fd = gbinder_driver_fd(ipc->driver);
|
||||
|
||||
/* This makes presence detection PING fail */
|
||||
test_binder_br_reply_status(fd, THIS_THREAD, -1);
|
||||
@@ -784,15 +794,16 @@ test_wait_async(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
const int fd = gbinder_driver_fd(ipc->driver);
|
||||
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
gulong id[2];
|
||||
int count = 0;
|
||||
int fd, count = 0;
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
fd = gbinder_driver_fd(ipc->driver);
|
||||
|
||||
/* This makes presence detection PING fail */
|
||||
test_binder_br_reply_status(fd, THIS_THREAD, -1);
|
||||
@@ -832,15 +843,17 @@ void
|
||||
test_death_run()
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
const int fd = gbinder_driver_fd(ipc->driver);
|
||||
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
gulong id[3];
|
||||
int count = 0, reg_count = 0;
|
||||
int fd, count = 0, reg_count = 0;
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
fd = gbinder_driver_fd(ipc->driver);
|
||||
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_servicemanager_new(dev);
|
||||
g_assert(sm);
|
||||
@@ -909,16 +922,18 @@ test_reanimate(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
const int fd = gbinder_driver_fd(ipc->driver);
|
||||
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
gulong id[3];
|
||||
int count = 0, reg_count = 0;
|
||||
int fd, count = 0, reg_count = 0;
|
||||
TestConfig config;
|
||||
|
||||
/* Create live service manager */
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
fd = gbinder_driver_fd(ipc->driver);
|
||||
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_servicemanager_new(dev);
|
||||
g_assert(sm);
|
||||
@@ -965,9 +980,9 @@ test_reuse(
|
||||
const char* binder_dev = GBINDER_DEFAULT_BINDER;
|
||||
const char* vndbinder_dev = "/dev/vpnbinder";
|
||||
const char* hwbinder_dev = GBINDER_DEFAULT_HWBINDER;
|
||||
GBinderIpc* binder_ipc = gbinder_ipc_new(binder_dev, NULL);
|
||||
GBinderIpc* vndbinder_ipc = gbinder_ipc_new(vndbinder_dev, NULL);
|
||||
GBinderIpc* hwbinder_ipc = gbinder_ipc_new(hwbinder_dev, NULL);
|
||||
GBinderIpc* binder_ipc;
|
||||
GBinderIpc* vndbinder_ipc;
|
||||
GBinderIpc* hwbinder_ipc;
|
||||
GBinderServiceManager* m1;
|
||||
GBinderServiceManager* m2;
|
||||
GBinderServiceManager* vnd1;
|
||||
@@ -977,6 +992,10 @@ test_reuse(
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
binder_ipc = gbinder_ipc_new(binder_dev, NULL);
|
||||
vndbinder_ipc = gbinder_ipc_new(vndbinder_dev, NULL);
|
||||
hwbinder_ipc = gbinder_ipc_new(hwbinder_dev, NULL);
|
||||
|
||||
test_setup_ping(binder_ipc);
|
||||
test_setup_ping(vndbinder_ipc);
|
||||
test_setup_ping(hwbinder_ipc);
|
||||
@@ -1023,7 +1042,7 @@ test_notify_type(
|
||||
GType t,
|
||||
const char* dev)
|
||||
{
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
TestHwServiceManager* test;
|
||||
const char* name = "foo";
|
||||
@@ -1032,6 +1051,7 @@ test_notify_type(
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_servicemanager_new_with_type(t, NULL, NULL);
|
||||
test = TEST_SERVICEMANAGER2(sm, t);
|
||||
@@ -1094,8 +1114,8 @@ test_list(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_BINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
TestHwServiceManager* test;
|
||||
char** list;
|
||||
@@ -1103,6 +1123,7 @@ test_list(
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_servicemanager_new(dev);
|
||||
test = TEST_SERVICEMANAGER(sm);
|
||||
@@ -1146,8 +1167,8 @@ test_get(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_BINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
TestHwServiceManager* test;
|
||||
int status = -1;
|
||||
@@ -1156,6 +1177,7 @@ test_get(
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_servicemanager_new(dev);
|
||||
test = TEST_SERVICEMANAGER(sm);
|
||||
@@ -1211,8 +1233,8 @@ test_add(
|
||||
void)
|
||||
{
|
||||
const char* dev = GBINDER_DEFAULT_BINDER;
|
||||
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
|
||||
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
|
||||
GBinderIpc* ipc;
|
||||
GBinderServiceManager* sm;
|
||||
TestHwServiceManager* test;
|
||||
GBinderLocalObject* obj;
|
||||
@@ -1220,6 +1242,7 @@ test_add(
|
||||
TestConfig config;
|
||||
|
||||
test_config_init(&config, TMP_DIR_TEMPLATE);
|
||||
ipc = gbinder_ipc_new(dev, NULL);
|
||||
test_setup_ping(ipc);
|
||||
sm = gbinder_servicemanager_new(dev);
|
||||
test = TEST_SERVICEMANAGER(sm);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2021-2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2021-2022 Jolla Ltd.
|
||||
*
|
||||
* You may use this file under the terms of BSD license as follows:
|
||||
@@ -333,6 +333,16 @@ test_notify_add_cb(
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_notify_unreached_cb(
|
||||
GBinderServiceManager* sm,
|
||||
const char* name,
|
||||
void* user_data)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_notify_cb(
|
||||
@@ -384,7 +394,13 @@ test_notify_run()
|
||||
g_assert(!gbinder_servicemanager_add_registration_handler(sm, ",",
|
||||
test_notify_never, NULL));
|
||||
|
||||
/* Start watching */
|
||||
/* Register and immediately unregister the handler */
|
||||
id = gbinder_servicemanager_add_registration_handler(sm, name,
|
||||
test_notify_unreached_cb, NULL);
|
||||
g_assert(id);
|
||||
gbinder_servicemanager_remove_handler(sm, id);
|
||||
|
||||
/* Actually start watching */
|
||||
id = gbinder_servicemanager_add_registration_handler(sm, name,
|
||||
test_notify_cb, &test);
|
||||
g_assert(id);
|
||||
|
||||
@@ -1350,7 +1350,6 @@ test_local_object(
|
||||
const TestLocalObjectData* test = test_data;
|
||||
GBinderLocalRequest* req;
|
||||
GBinderOutputData* data;
|
||||
GUtilIntArray* offsets;
|
||||
GBinderWriter writer;
|
||||
TestContext context;
|
||||
|
||||
@@ -1359,10 +1358,7 @@ test_local_object(
|
||||
gbinder_local_request_init_writer(req, &writer);
|
||||
gbinder_writer_append_local_object(&writer, NULL);
|
||||
data = gbinder_local_request_data(req);
|
||||
offsets = gbinder_output_data_offsets(data);
|
||||
g_assert(offsets);
|
||||
g_assert_cmpuint(offsets->count, == ,1);
|
||||
g_assert_cmpuint(offsets->data[0], == ,0);
|
||||
g_assert(!gbinder_output_data_offsets(data));
|
||||
g_assert_cmpuint(gbinder_output_data_buffers_size(data), == ,0);
|
||||
g_assert_cmpuint(data->bytes->len, == ,test->objsize);
|
||||
gbinder_local_request_unref(req);
|
||||
@@ -1380,7 +1376,6 @@ test_remote_object(
|
||||
{
|
||||
GBinderLocalRequest* req = test_local_request_new_64();
|
||||
GBinderOutputData* data;
|
||||
GUtilIntArray* offsets;
|
||||
GBinderWriter writer;
|
||||
TestContext test;
|
||||
|
||||
@@ -1388,10 +1383,7 @@ test_remote_object(
|
||||
gbinder_local_request_init_writer(req, &writer);
|
||||
gbinder_writer_append_remote_object(&writer, NULL);
|
||||
data = gbinder_local_request_data(req);
|
||||
offsets = gbinder_output_data_offsets(data);
|
||||
g_assert(offsets);
|
||||
g_assert(offsets->count == 1);
|
||||
g_assert(offsets->data[0] == 0);
|
||||
g_assert(!gbinder_output_data_offsets(data));
|
||||
g_assert(!gbinder_output_data_buffers_size(data));
|
||||
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_64);
|
||||
gbinder_local_request_unref(req);
|
||||
|
||||
Reference in New Issue
Block a user