Compare commits

..

13 Commits

Author SHA1 Message Date
2778ec3a88 debug logs 2025-10-18 13:49:55 +08:00
6697470380 debian files 2025-10-17 23:30:56 +08:00
Ratchanan Srirattanamet
a9dfd6e453 writer: don't write object offset for NULL binder object
Writing offset will trigger the kernel-side code to transform the flat
binder object into the handle form, which (in my understanding) is not
a valid operation for a NULL binder object. Meanwhile, the receiving
side will create a corresponding Binder object from such handle,
tripping the stability check as it will no longer accept UNDECLARED.

OTOH, if the offset is not written, then the receiving side will receive
the flat binder object as-is, with type BINDER and pointer NULL, which
will be interpreted as NULL binder. This is also what Android's
Parcel.cpp does [1][2].

IMO, this is sort of a hack. Binder kernel driver should handle the NULL
binder internally, and not relying on the sender doing the correct
thing. Meanwhile, the receiver should always reject a flat binder object
of type BINDER. But that's how Android work, so... 🤷

[1]: https://github.com/LineageOS/android_frameworks_native/blob/lineage-19.1/libs/binder/Parcel.cpp#L1327-L1332
[2]: https://github.com/LineageOS/android_frameworks_native/blob/lineage-19.1/libs/binder/Parcel.cpp#L2023-L2029

Origin: vendor
Forwarded: https://github.com/mer-hybris/libgbinder/pull/135
2025-10-17 23:29:53 +08:00
Ratchanan Srirattanamet
2439ff878d use BINDER_TYPE_BINDER for NULL local object
3 reasons:
- This is what encode_remote_object() does. I see no reason a NULL local
  object should be encoded differently than a NULL remote object.
- This is what Parcel.cpp does when flattening a NULL binder [1]. This
  is contrary to what is said in PR #99 [2]; I'm not sure why PR #99
  said it uses BINDER_TYPE_HANDLE.
- More importantly, BINDER_TYPE_HANDLE number 0 does NOT represent a
  NULL binder. According to the comment at [3], handle number 0 actually
  represent the context manager. So, by sending BINDER_TYPE_HANDLE
  number 0, we're sending context manager, not a NULL binder.

[1]: https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-14.0.0_r1/libs/binder/Parcel.cpp#277
[2]: https://github.com/mer-hybris/libgbinder/pull/99
[3]: https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-14.0.0_r1/libs/binder/ProcessState.cpp#336

Origin: vendor
Bug-UBports: https://gitlab.com/ubports/development/core/packaging/libgbinder/-/merge_requests/9#note_2138653925
Forwarded: https://github.com/mer-hybris/libgbinder/pull/135
2025-10-17 23:29:52 +08:00
Ratchanan Srirattanamet
8c65520173 uses aidl3 servicemanager on API level 31 & 32
Nikita (@NotKit) noticed that the change in commit f227ae4291
("[gbinder] All binder objects need stability field in Android 11.
JB#58951") has made the aidl4 servicemanager variant redundant. In fact,
using aidl4 variant will cause an extra stability field to be sent on
the wire (luckily it has not caused any problem).

I've tried using aidl3 variant on Volla Phone X23 which runs Halium 12
(API level 32), and service registration still work, which seems to
validate this theory. Thus, stop using aidl4 servicemanager variant on
any of the API level-based config, as it no longer correspond to any of
Android versions.

Note that this commit doesn't outright remove aidl4 variant, as doing so
would break configurations which explicitly request its use. This commit
doesn't doesn't alias the aidl4 variant to aidl3 variant either.
Manually requesting a certain variant could mean some unusual setup;
aliasing aidl4 to aidl3 could break such setup.

Origin: vendor
Forwarded: https://github.com/mer-hybris/libgbinder/pull/133
2025-10-17 23:29:52 +08:00
Ratchanan Srirattanamet
e3764d7002 correct stability field wire format on Android 12
On Android 12, the wire format of stability field is changed to also
include so-called "Binder wire format version", which starts at 1 [1].
A 32-bit-sized struct is re-interpreted into a 32-bit integer, with a
layout which makes it incompatible with the old version. Interestingly,
they reverted this idea in Android 13 [2], which makes the wire format
of the stability field the same as Android 11 again (as far as I know).

Add a new RPC protocol variant 'aidl4' to account for this difference.
Use this protocol on API level 31 through 32 and use 'aidl3' from API
level 33 onwards. The only difference from 'aidl3' is `finish_flatten_
binder()` function.

Interestingly, there is also a 16-bit-sized struct variant of the field
too [3]. However, to the best of my knowledge, this version is not used
in any of the released Android versions.

[1]: 89ddfc5f8c
[2]: 16a4106cb7
[3]: 14e4cfae36

Origin: vendor
Forwarded: https://github.com/mer-hybris/libgbinder/pull/133
2025-10-17 23:29:52 +08:00
Slava Monich
624bfa843d Version 1.1.40 2024-07-18 05:35:00 +03:00
Slava Monich
6d71a0649c [gbinder] Housekeeping 2024-07-18 05:32:36 +03:00
Slava Monich
c31cd7e964 Acknowledge Nikita's contribution 2024-07-18 05:08:47 +03:00
Slava Monich
c1db86e734 Merge pull request #130 from mer-hybris/aidl-stability
Make stability field of local object configurable
2024-07-18 05:04:50 +03:00
Nikita Ukhrenkov
bfb95f2bf5 [gbinder] Make stability field of local object configurable. JB#61912
AIDL HALs require stability field value to be set to VINTF as
opposed to the default SYSTEM, so expose a way to let the caller
set the value to used by finish_flatten_binder per local object.
2024-07-15 18:42:20 +03:00
Slava Monich
6f4c69d58a Merge pull request #131 from monich/unit_conf
Make more unit tests independent on system config
2024-07-15 17:29:17 +03:00
Slava Monich
c6b09a10d4 [unit] Make more unit tests independent on system config. JB#42956
System gbinder config shouldn't break unit tests.
2024-07-14 06:15:19 +03:00
29 changed files with 314 additions and 142 deletions

View File

@@ -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>
@@ -10,3 +10,4 @@ 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>

View File

@@ -16,7 +16,7 @@
VERSION_MAJOR = 1
VERSION_MINOR = 1
VERSION_RELEASE = 39
VERSION_RELEASE = 40
# Version for pkg-config
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)

10
debian/Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,10 @@
@Library('ubports-build-tools') _
buildAndProvideDebianPackage()
// Or if the package consists entirely of arch-independent packages:
// (optional optimization, will confuse BlueOcean's live view at build stage)
// buildAndProvideDebianPackage(/* isArchIndependent */ true)
// Optionally, to skip building on some architectures (amd64 is always built):
// buildAndProvideDebianPackage(false, /* ignoredArchs */ ['arm64'])

74
debian/changelog vendored
View File

@@ -1,60 +1,26 @@
libgbinder (1.1.39) unstable; urgency=low
libgbinder (1.1.40-0ubports1) UNRELEASED; urgency=medium
* Eliminate defects found by Coverity
* Upstream release v1.1.40
-- Slava Monich <slava@monich.com> Sun, 05 May 2024 20:03:44 +0300
-- TheKit <thekit@disroot.org> Thu, 15 Aug 2024 15:56:51 +0300
libgbinder (1.1.38) unstable; urgency=low
libgbinder (1.1.35-0ubports1) UNRELEASED; urgency=unknown
* Fixed byte array padding
* New upstream release v1.1.35
-- Slava Monich <slava@monich.com> Sat, 02 Mar 2024 02:11:50 +0200
-- UBports package upgrader bot <dev@ubports.com> Thu, 23 Nov 2023 23:02:23 +0000
libgbinder (1.1.37) unstable; urgency=low
libgbinder (1.1.34-0ubports1) focal; urgency=medium
* Fixed gbinder_driver_reply_data return value
* New upstream release v1.1.34
-- Slava Monich <slava@monich.com> Mon, 26 Feb 2024 16:22:29 +0200
-- Marius Gripsgard <mariogrip@debian.org> Thu, 31 Aug 2023 12:09:35 +0200
libgbinder (1.1.36) unstable; urgency=low
libgbinder (1.1.30-0ubports1) focal; urgency=medium
* Support pkg-config cross-compilation
* Fixed handling of UTF-16 surrogate pairs
* Upstream release v1.1.30
-- Slava Monich <slava@monich.com> Sat, 10 Feb 2024 05:04:13 +0200
libgbinder (1.1.35) unstable; urgency=low
* Make unit tests independent on system config
* Use MAKE var instead of explicitly calling make
-- Slava Monich <slava@monich.com> Thu, 23 Nov 2023 01:42:56 +0200
libgbinder (1.1.34) unstable; urgency=low
* Fixed binder-call help message
* Require glib 2.32
-- Slava Monich <slava@monich.com> Sun, 30 Apr 2023 06:04:38 +0300
libgbinder (1.1.33) unstable; urgency=low
* Fixed GBinderWriterType for byte and int32
-- Slava Monich <slava@monich.com> Sun, 26 Feb 2023 03:13:49 +0200
libgbinder (1.1.32) unstable; urgency=low
* Improved reliability of unit tests
-- Slava Monich <slava@monich.com> Mon, 23 Jan 2023 11:48:00 +0200
libgbinder (1.1.31) unstable; urgency=low
* Fixed serialization issues on big-endian
* Refactored binder simulation for unit tests
-- Slava Monich <slava@monich.com> Wed, 04 Jan 2023 19:10:37 +0200
-- Jami Kettunen <jami.kettunen@protonmail.com> Wed, 07 Dec 2022 00:58:38 +0200
libgbinder (1.1.30) unstable; urgency=low
@@ -125,6 +91,16 @@ libgbinder (1.1.20) unstable; urgency=low
-- Slava Monich <slava.monich@jolla.com> Sat, 11 Jun 2022 02:49:49 +0300
libgbinder (1.1.19-0ubports1) xenial; urgency=medium
* New upstream version 1.1.19.
* debian/ubports.source_location: update the location for 1.1.19
* debian/*: bring in upstream Debian packaging changes where appropriate
* debian/rules: pass KEEP_SYMBOLS to let dh do the strip (& auto dbgsym)
* debian/libgbinder-tools.install: add the missing .install file
-- Ratchanan Srirattanamet <ratchanan@ubports.com> Thu, 21 Apr 2022 17:22:20 +0700
libgbinder (1.1.19) unstable; urgency=low
* Added reader and writer for aidl parcelables
@@ -219,6 +195,12 @@ libgbinder (1.1.7) unstable; urgency=low
-- Slava Monich <slava.monich@jolla.com> Wed, 31 Mar 2021 23:10:37 +0300
libgbinder (1.1.6-0ubports1) xenial; urgency=medium
* Import v1.1.6 to ubports
-- Marius Gripsgard <marius@ubports.com> Fri, 05 Mar 2021 01:02:27 +0100
libgbinder (1.1.6) unstable; urgency=low
* Implemented support for passing object over the bridge

2
debian/control vendored
View File

@@ -14,7 +14,7 @@ Description: Binder client library
Package: libgbinder-dev
Section: libdevel
Architecture: any
Depends: libgbinder (= ${binary:Version}), libglibutil-dev (>= 1.0.52)
Depends: libgbinder (= ${binary:Version}), libglibutil-dev (>= 1.0.52), ${misc:Depends}
Description: Development files for libgbinder
Package: libgbinder-tools

6
debian/copyright vendored
View File

@@ -1,5 +1,7 @@
Copyright (C) 2018-2024 Jolla Ltd.
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:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

37
debian/gbinder.conf vendored Normal file
View File

@@ -0,0 +1,37 @@
# Android keeps changing both low-level RPC and service manager
# protocols from version to version. To counter that, libgbinder
# implements configirable backends for different variants of those,
# and yet keeping its own API unchanged.
# Configuration is loaded from [Protocol] and [ServiceManager] sections
# of /etc/gbinder.conf file. The keys are binder device names or the
# special Default value, the value is the identifier of the protocol
# or service manager variant, respectively.
# In addition to reading /etc/gbinder.conf if it exists, /etc/gbinder.d
# directory is scanned for .conf files, the file list is sorted, files are
# loaded one by one, overwriting the entries loaded from /etc/gbinder.conf
# or from the previously processed file.
# Known protocol and service manager variants are aidl, aidl2, aidl3 and
# hidl. This list is expected to expand further in the future. The default
# configuration is as follows:
# [Protocol]
# Default = aidl
# /dev/binder = aidl
# /dev/hwbinder = hidl
# [ServiceManager]
# Default = aidl
# /dev/binder = aidl
# /dev/hwbinder = hidl
# Alternatively and preferably, one can specify the desired Android API
# level:
# [General]
# ApiLevel = 29
# and let libgbinder pick the appropriate preset. Full list of presets can
# be found in src/gbinder_config.c

View File

@@ -1 +1 @@
debian/tmp/usr/bin/* usr/bin
debian/tmp/usr/bin/* usr/bin/

1
debian/libgbinder.dirs vendored Normal file
View File

@@ -0,0 +1 @@
/etc/gbinder.d/

View File

@@ -1 +1,2 @@
debian/tmp/@LIBDIR@/libgbinder.so.* @LIBDIR@
debian/gbinder.conf /etc/

2
debian/rules vendored
View File

@@ -7,7 +7,7 @@
LIBDIR=usr/lib/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
override_dh_auto_build:
dh_auto_build -- LIBDIR=$(LIBDIR) release pkgconfig debian/libgbinder.install debian/libgbinder-dev.install
dh_auto_build -- LIBDIR=$(LIBDIR) KEEP_SYMBOLS=1 release pkgconfig debian/libgbinder.install debian/libgbinder-dev.install
dh_auto_build -- -C test/binder-bridge release
dh_auto_build -- -C test/binder-call release
dh_auto_build -- -C test/binder-list release

View File

@@ -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 */

View File

@@ -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))

View File

@@ -1,6 +1,6 @@
Name: libgbinder
Version: 1.1.39
Version: 1.1.40
Release: 0
Summary: Binder client library
License: BSD
@@ -21,7 +21,7 @@ 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}}
%{!?make_build:%define make_build make %{_smp_mflags}}
Requires: glib2 >= %{glib_version}
Requires: libglibutil >= %{libglibutil_version}

View File

@@ -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 },

View File

@@ -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);

View File

@@ -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
*==========================================================================*/

View File

@@ -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 {

View File

@@ -38,6 +38,9 @@
#define GLOG_MODULE_NAME GBINDER_LOG_MODULE
#include <gutil_log.h>
#define DBG(fmt, ...) \
gutil_log(GLOG_MODULE_CURRENT, GLOG_LEVEL_ALWAYS, "gbinder:"fmt, ##__VA_ARGS__)
/* Declared for unit tests */
__attribute__((constructor))
void

View File

@@ -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
};

View File

@@ -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 */
/*

View File

@@ -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

View File

@@ -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"
}
};

View File

@@ -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;
}
/*

View File

@@ -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);
}
/*==========================================================================*

View File

@@ -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;
}
/*

View File

@@ -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;
}
/*

View File

@@ -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);

View File

@@ -1359,10 +1359,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 +1377,6 @@ test_remote_object(
{
GBinderLocalRequest* req = test_local_request_new_64();
GBinderOutputData* data;
GUtilIntArray* offsets;
GBinderWriter writer;
TestContext test;
@@ -1388,10 +1384,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);