Compare commits

...

36 Commits

Author SHA1 Message Date
Slava Monich
32b3d4455a Version 1.1.28 2022-11-22 18:22:37 +02:00
Slava Monich
09e9a9d5c1 Merge pull request #103 from monich/minus
Allow to pass negative number as a parameter
2022-11-22 18:12:34 +02:00
Slava Monich
83b04757c6 Merge pull request #105 from monich/pie
Compile executables with -fPIE
2022-11-22 18:12:09 +02:00
Slava Monich
c636814500 [test] Compile executables with -fPIE. JB#42956 2022-11-20 18:02:58 +02:00
Slava Monich
2592ea60ce Merge pull request #104 from monich/spec
Tweak the spec file
2022-11-20 05:18:12 +02:00
Slava Monich
f04e21b462 [packaging] Tweak the spec file. JB#42956
1. Some packaging guides suggest not to do rm -rf %{buildroot}
2. Own the directory containing the header files, not just the files
2022-11-20 01:17:19 +02:00
Slava Monich
d739912faa [binder-call] Allow to pass negative number as a parameter. JB#59412
Note that the user would have to use  "--" flag to stop GOptionContext
from parsing negative numbers as command line options.
2022-11-19 21:48:54 +02:00
Slava Monich
c2263874ec [binder-call] Removed unused app_options field 2022-11-19 21:43:32 +02:00
Slava Monich
aa23e44677 Version 1.1.27 2022-11-17 03:26:48 +02:00
Slava Monich
ca38c15d3c Merge pull request #102 from monich/append-struct
Convenience API for writing nested structures
2022-11-17 03:20:33 +02:00
Slava Monich
6f9220aedb [gbinder] Added gbinder_writer_append_struct(). JB#42956
It simplifies writing buffers for nested structures.
2022-11-17 03:19:33 +02:00
Slava Monich
eafec68ff8 Verision 1.1.26 2022-10-14 16:49:58 +03:00
Slava Monich
0dc84b0748 Merge pull request #100 from monich/stability
All binder objects need stability field in Android 11
2022-10-14 16:39:53 +03:00
Slava Monich
f227ae4291 [gbinder] All binder objects need stability field in Android 11. JB#58951
According to Parcel::finishFlattenBinder() in native/libs/binder/Parcel.cpp
2022-10-14 16:16:19 +03:00
Slava Monich
b14b68717f Merge pull request #99 from monich/null
Use BINDER_TYPE_HANDLE for NULL binders
2022-10-11 18:44:37 +03:00
Slava Monich
8bf0d63960 [gbinder] Use BINDER_TYPE_HANDLE for NULL binders
That's what Parcel.cpp seems to be doing on the Android side
2022-10-11 17:14:10 +03:00
Slava Monich
c22eafe49e Version 1.1.25 2022-07-19 02:04:30 +03:00
Slava Monich
66122a2ce6 [unit] Added unit test for device + protocol combo. JB#42254 2022-07-19 02:01:26 +03:00
Slava Monich
c1ff25f6ae [gbinder] Housekeeping. JB#42254 2022-07-19 01:57:13 +03:00
Slava Monich
af3c23a18f Merge pull request #98 from aleasto/master
Handle changing the rpc protocol during execution
2022-07-19 01:49:19 +03:00
Alessandro Astone
5a14796c4c [gbinder] Handle changing the rpc protocol during execution
When calling gbinder_ipc_new with a different protocol for the same
device node, we would end up getting the old cached GBinderIpc object
referencing the old protocol.

Make the hash table key uniquely identify a (dev,protocol) pair.
2022-07-19 00:47:51 +02:00
Slava Monich
3bb8a38f5f Version 1.1.24 2022-07-14 01:35:45 +03:00
Slava Monich
f29f0b5a1b [debian] Bumped debhelper compat level to 7. JB#42956 2022-07-14 01:34:45 +03:00
Slava Monich
2da1c7b5ca Version 1.1.23 2022-06-23 20:12:08 +03:00
Slava Monich
8348bc76bd Merge pull request #96 from monich/build-deps
Fix debian build dependencies
2022-06-23 20:06:28 +03:00
Slava Monich
a97a153c94 [debian] Fix build dependencies. JB#42956 2022-06-23 04:09:12 +03:00
Slava Monich
94ddc9f0e5 Version 1.1.22 2022-06-22 17:05:07 +03:00
Slava Monich
370d2dedb3 [unit] Improved gbinder_config.c coverage. JB#42956 2022-06-22 16:57:15 +03:00
Slava Monich
58c9a7fe93 Merge pull request #83 from adglkh/api_31_support
[gbinder] Support for Android 12 (API level 31). JB#42254
2022-06-22 16:29:38 +03:00
gary-wzl77
3742e2ca8e [test] make the binder device configurable for binder-dump test 2022-06-22 18:36:52 +08:00
gary-wzl77
ede15da9e2 [gbinder] Add preset gbinder config to support Android API version 31 2022-06-22 18:36:52 +08:00
gary-wzl77
771444a8ac [gbinder] Add "aidl4" variant of service manager
Introduce "aidl4" variant of service manager to adapt the change
to service related protocol for Android 12.

From Android 12, when reading nullable strong binder, the format of
the `stability` field passed on the wire was changed and evolved to
`struct Category`, which consists of the following members with 4 bytes long.
```
struct Category {
  uint8_t version;
  uint8_t reserved[2];
  Level level;        <- bitmask of Stability::Level
}
```
Please check the following link for details:

  https://cs.android.com/android/platform/superproject/+/android-12.0.0_r3:frameworks/native/libs/binder/include/binder/Stability.h;l=140

To honor the change on AOSP side for Android 12, we need to adapt
the protocol change in Service Manager.
2022-06-22 18:36:51 +08:00
Slava Monich
956fa90cbf Version 1.1.21 2022-06-20 18:54:33 +03:00
Slava Monich
17ff87510c [gbinder] Housekeeping. JB#42956 2022-06-20 13:28:20 +03:00
Slava Monich
552fc4f172 [gbinder] Don't finalize GObject twice. JB#42956 2022-06-20 13:26:11 +03:00
Slava Monich
4b179477ad [gbinder] Properly finalize GBinderServicePoll. JB#42956 2022-06-20 13:01:34 +03:00
70 changed files with 1969 additions and 1507 deletions

View File

@@ -16,7 +16,7 @@
VERSION_MAJOR = 1
VERSION_MINOR = 1
VERSION_RELEASE = 20
VERSION_RELEASE = 28
# Version for pkg-config
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
@@ -105,6 +105,7 @@ SRC += \
gbinder_servicemanager_aidl.c \
gbinder_servicemanager_aidl2.c \
gbinder_servicemanager_aidl3.c \
gbinder_servicemanager_aidl4.c \
gbinder_servicemanager_hidl.c
SRC += \

51
debian/changelog vendored
View File

@@ -1,3 +1,54 @@
libgbinder (1.1.28) unstable; urgency=low
* Allow to pass negative number as a parameter to binder-call
* Compile tools as PIE
-- Slava Monich <slava.monich@jolla.com> Tue, 22 Nov 2022 18:21:29 +0200
libgbinder (1.1.27) unstable; urgency=low
* Added gbinder_writer_append_struct()
-- Slava Monich <slava.monich@jolla.com> Thu, 17 Nov 2022 03:25:37 +0200
libgbinder (1.1.26) unstable; urgency=low
* Use BINDER_TYPE_HANDLE for NULL binders
* Fixed binder object encoding in aidl3 protocol
-- Slava Monich <slava.monich@jolla.com> Fri, 14 Oct 2022 16:48:29 +0300
libgbinder (1.1.25) unstable; urgency=low
* Handle RPC protocol change at run time
-- Slava Monich <slava.monich@jolla.com> Tue, 19 Jul 2022 02:02:41 +0300
libgbinder (1.1.24) unstable; urgency=low
* Bumped debhelper compat level to 7
-- Slava Monich <slava.monich@jolla.com> Thu, 14 Jul 2022 01:32:11 +0300
libgbinder (1.1.23) unstable; urgency=low
* Fixed Debian build dependencies
-- Slava Monich <slava.monich@jolla.com> Thu, 23 Jun 2022 20:09:35 +0300
libgbinder (1.1.22) unstable; urgency=low
* Added support for Android 12 (API level 31)
* Made binder device configurable for binder-dump
-- Slava Monich <slava.monich@jolla.com> Wed, 22 Jun 2022 17:02:20 +0300
libgbinder (1.1.21) unstable; urgency=low
* Properly finalize GBinderIpc and GBinderServicePoll
-- Slava Monich <slava.monich@jolla.com> Mon, 20 Jun 2022 18:53:26 +0300
libgbinder (1.1.20) unstable; urgency=low
* Made RPC protocol selectable at runtime

2
debian/compat vendored
View File

@@ -1 +1 @@
5
7

4
debian/control vendored
View File

@@ -2,7 +2,7 @@ Source: libgbinder
Section: libs
Priority: optional
Maintainer: Slava Monich <slava.monich@jolla.com>
Build-Depends: debhelper (>= 8.1.3), libglib2.0-dev (>= 2.0), libglibutil (>= 1.0.52), flex, bison
Build-Depends: debhelper (>= 8.1.3), libglib2.0-dev (>= 2.0), libglibutil-dev (>= 1.0.52), flex, bison
Standards-Version: 3.8.4
Package: libgbinder
@@ -14,7 +14,7 @@ Description: Binder client library
Package: libgbinder-dev
Section: libdevel
Architecture: any
Depends: libgbinder (= ${binary:Version}), ${misc:Depends}
Depends: libgbinder (= ${binary:Version}), libglibutil-dev (>= 1.0.52)
Description: Development files for libgbinder
Package: libgbinder-tools

View File

@@ -55,6 +55,102 @@ struct gbinder_parent {
guint32 offset;
};
/*
* Note that gbinder_writer_append_struct() doesn't copy the data, it writes
* buffer objects pointing to whatever was passed in. The caller must make
* sure that those pointers outlive the transaction. That's most commonly
* done with by using gbinder_writer_malloc() and friends for allocating
* memory for the transaction.
*
* Below is an example of initializing GBinderWriterType which can then
* be passed to gbinder_writer_append_struct(). Fields have to be listed
* in the order in which they appear in the structure.
*
* typedef struct data {
* int x;
* } Data;
*
* typedef struct data2 {
* int y;
* GBinderHidlString str;
* GBinderHidlVec vec; // vec<Data>
* } Data2;
*
* static const GBinderWriterType data_t = {
* GBINDER_WRITER_STRUCT_NAME_AND_SIZE(Data), NULL
* };
*
* static const GBinderWriterField data2_f[] = {
* GBINDER_WRITER_FIELD_HIDL_STRING(Data2,str),
* GBINDER_WRITER_FIELD_HIDL_VEC(Data2, vec, &data_t),
* GBINDER_WRITER_FIELD_END()
* };
*
* static const GBinderWriterType data2_t = {
* GBINDER_WRITER_STRUCT_NAME_AND_SIZE(Data2), data2_f
* };
*/
typedef struct gbinder_writer_type {
const char* name;
gsize size;
const struct gbinder_writer_field* fields;
} GBinderWriterType; /* Since 1.1.27 */
typedef struct gbinder_writer_field {
const char* name;
gsize offset;
const GBinderWriterType* type;
void (*write_buf)(GBinderWriter* writer, const void* ptr,
const struct gbinder_writer_field* field, const GBinderParent* parent);
gpointer reserved;
} GBinderWriterField; /* Since 1.1.27 */
#define GBINDER_WRITER_STRUCT_NAME_AND_SIZE(type) \
#type, sizeof(type)
#define GBINDER_WRITER_FIELD_NAME_AND_OFFSET(type,field) \
#type "." #field, G_STRUCT_OFFSET(type,field)
#define GBINDER_WRITER_FIELD_POINTER(type,field,field_type) { \
GBINDER_WRITER_FIELD_NAME_AND_OFFSET(type,field), field_type, NULL, NULL }
#define GBINDER_WRITER_FIELD_HIDL_VEC(type,field,elem) { \
GBINDER_WRITER_FIELD_NAME_AND_OFFSET(type,field), elem, \
gbinder_writer_field_hidl_vec_write_buf, NULL }
#define GBINDER_WRITER_FIELD_HIDL_VEC_INT32(type,field) \
GBINDER_WRITER_FIELD_HIDL_VEC(type,field, &gbinder_writer_type_int32)
#define GBINDER_WRITER_FIELD_HIDL_VEC_BYTE(type,field) \
GBINDER_WRITER_FIELD_HIDL_VEC(type,field, &gbinder_writer_type_byte)
#define GBINDER_WRITER_FIELD_HIDL_VEC_STRING(type,field) \
GBINDER_WRITER_FIELD_HIDL_VEC(type,field, &gbinder_writer_type_hidl_string)
#define GBINDER_WRITER_FIELD_HIDL_STRING(type,field) { \
GBINDER_WRITER_FIELD_NAME_AND_OFFSET(type,field), NULL, \
gbinder_writer_field_hidl_string_write_buf, NULL }
#define GBINDER_WRITER_FIELD_END() { NULL, 0, NULL, NULL, NULL }
extern const GBinderWriterType gbinder_writer_type_byte; /* Since 1.1.27 */
extern const GBinderWriterType gbinder_writer_type_int32; /* Since 1.1.27 */
extern const GBinderWriterType gbinder_writer_type_hidl_string; /* 1.1.27 */
void
gbinder_writer_append_struct(
GBinderWriter* writer,
const void* ptr,
const GBinderWriterType* type,
const GBinderParent* parent); /* Since 1.1.27 */
void
gbinder_writer_field_hidl_vec_write_buf(
GBinderWriter* writer,
const void* ptr,
const GBinderWriterField* field,
const GBinderParent* parent); /* Since 1.1.27 */
void
gbinder_writer_field_hidl_string_write_buf(
GBinderWriter* writer,
const void* ptr,
const GBinderWriterField* field,
const GBinderParent* parent); /* Since 1.1.27 */
void
gbinder_writer_append_int8(
GBinderWriter* writer,

View File

@@ -1,6 +1,6 @@
Name: libgbinder
Version: 1.1.20
Version: 1.1.28
Release: 0
Summary: Binder client library
License: BSD
@@ -44,7 +44,6 @@ make -C test/binder-ping KEEP_SYMBOLS=1 release
make -C test/binder-call KEEP_SYMBOLS=1 release
%install
rm -rf %{buildroot}
make LIBDIR=%{_libdir} DESTDIR=%{buildroot} install-dev
make -C test/binder-bridge DESTDIR=%{buildroot} install
make -C test/binder-list DESTDIR=%{buildroot} install
@@ -67,6 +66,7 @@ make -C unit test
%files devel
%defattr(-,root,root,-)
%dir %{_includedir}/gbinder
%{_libdir}/pkgconfig/*.pc
%{_libdir}/%{name}.so
%{_includedir}/gbinder/*.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-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:
*
@@ -251,6 +251,15 @@ gbinder_buffer_io(
return driver ? gbinder_driver_io(driver) : NULL;
}
const GBinderRpcProtocol*
gbinder_buffer_protocol(
GBinderBuffer* buf)
{
GBinderDriver* driver = gbinder_buffer_driver(buf);
return driver ? gbinder_driver_protocol(driver) : NULL;
}
void**
gbinder_buffer_objects(
GBinderBuffer* self)

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-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:
*
@@ -73,6 +73,11 @@ gbinder_buffer_io(
GBinderBuffer* buf)
GBINDER_INTERNAL;
const GBinderRpcProtocol*
gbinder_buffer_protocol(
GBinderBuffer* buf)
GBINDER_INTERNAL;
void**
gbinder_buffer_objects(
GBinderBuffer* buffer)

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-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:
*
@@ -282,7 +282,8 @@ gbinder_client_new2(
priv->ranges = g_new0(GBinderClientIfaceRange, 1);
priv->ranges[0].last_code = UINT_MAX;
priv->ranges[0].basic_req = gbinder_local_request_new
(gbinder_driver_io(driver), NULL);
(gbinder_driver_io(driver), gbinder_driver_protocol(driver),
NULL);
}
return self;
}
@@ -373,9 +374,10 @@ gbinder_client_new_request(
{
if (G_LIKELY(self)) {
GBinderClientPriv* priv = gbinder_client_cast(self);
const GBinderIo* io = gbinder_driver_io(self->remote->ipc->driver);
GBinderDriver* driver = self->remote->ipc->driver;
return gbinder_local_request_new(io, priv->ranges->rpc_header);
return gbinder_local_request_new(gbinder_driver_io(driver),
gbinder_driver_protocol(driver), priv->ranges->rpc_header);
}
return NULL;
}
@@ -387,13 +389,14 @@ gbinder_client_new_request2(
{
if (G_LIKELY(self)) {
GBinderClientPriv* priv = gbinder_client_cast(self);
const GBinderClientIfaceRange* r = gbinder_client_find_range
const GBinderClientIfaceRange* range = gbinder_client_find_range
(priv, code);
if (r) {
const GBinderIo* io = gbinder_driver_io(self->remote->ipc->driver);
if (range) {
GBinderDriver* driver = self->remote->ipc->driver;
return gbinder_local_request_new(io, r->rpc_header);
return gbinder_local_request_new(gbinder_driver_io(driver),
gbinder_driver_protocol(driver), range->rpc_header);
}
}
return NULL;

View File

@@ -133,9 +133,24 @@ static const GBinderConfigPresetGroup gbinder_config_30[] = {
{ NULL, NULL }
};
/* API level 31 */
static const GBinderConfigPresetEntry gbinder_config_31_servicemanager[] = {
{ "/dev/binder", "aidl4" },
{ "/dev/vndbinder", "aidl4" },
{ NULL, NULL }
};
static const GBinderConfigPresetGroup gbinder_config_31[] = {
{ GBINDER_CONFIG_GROUP_PROTOCOL, gbinder_config_30_protocol },
{ GBINDER_CONFIG_GROUP_SERVICEMANAGER, gbinder_config_31_servicemanager },
{ NULL, NULL }
};
/* Presets sorted by API level in descending order */
static const GBinderConfigPreset gbinder_config_presets[] = {
{ 31, gbinder_config_31 },
{ 30, gbinder_config_30 },
{ 29, gbinder_config_29 },
{ 28, gbinder_config_28 }

View File

@@ -1324,8 +1324,9 @@ GBinderLocalRequest*
gbinder_driver_local_request_new_ping(
GBinderDriver* self)
{
GBinderLocalRequest* req = gbinder_local_request_new(self->io, NULL);
GBinderWriter writer;
GBinderLocalRequest* req = gbinder_local_request_new(self->io,
self->protocol, NULL);
gbinder_local_request_init_writer(req, &writer);
self->protocol->write_ping(&writer);

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-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:
*
@@ -35,6 +35,7 @@
#include "gbinder_local_object_p.h"
#include "gbinder_remote_object_p.h"
#include "gbinder_object_registry.h"
#include "gbinder_rpc_protocol.h"
#include "gbinder_writer.h"
#include "gbinder_system.h"
#include "gbinder_log.h"
@@ -94,7 +95,8 @@ GBINDER_IO_FN(write_read)(
static
gsize
GBINDER_IO_FN(object_size)(
const void* obj)
const void* obj,
const GBinderRpcProtocol* protocol)
{
if (obj) {
const struct binder_object_header* hdr = obj;
@@ -104,7 +106,8 @@ GBINDER_IO_FN(object_size)(
case BINDER_TYPE_WEAK_BINDER:
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE:
return sizeof(struct flat_binder_object);
return sizeof(struct flat_binder_object) +
protocol->flat_binder_object_extra;
case BINDER_TYPE_FD:
return sizeof(struct binder_fd_object);
case BINDER_TYPE_FDA:
@@ -166,7 +169,8 @@ static
guint
GBINDER_IO_FN(encode_local_object)(
void* out,
GBinderLocalObject* obj)
GBinderLocalObject* obj,
const GBinderRpcProtocol* protocol)
{
struct flat_binder_object* dest = out;
@@ -176,9 +180,14 @@ GBINDER_IO_FN(encode_local_object)(
dest->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
dest->binder = (uintptr_t)obj;
} else {
dest->hdr.type = BINDER_TYPE_WEAK_BINDER;
dest->hdr.type = BINDER_TYPE_HANDLE;
}
return sizeof(*dest);
if (protocol->finish_flatten_binder) {
protocol->finish_flatten_binder(dest + 1, obj);
} else if (protocol->flat_binder_object_extra) {
memset(dest + 1, 0, protocol->flat_binder_object_extra);
}
return sizeof(*dest) + protocol->flat_binder_object_extra;
}
static
@@ -500,7 +509,8 @@ static
guint
GBINDER_IO_FN(decode_binder_handle)(
const void* data,
guint32* handle)
guint32* handle,
const GBinderRpcProtocol* protocol)
{
const struct flat_binder_object* obj = data;
@@ -509,7 +519,7 @@ GBINDER_IO_FN(decode_binder_handle)(
if (handle) {
*handle = obj->handle;
}
return sizeof(*obj);
return sizeof(*obj) + protocol->flat_binder_object_extra;
}
return 0;
}
@@ -520,7 +530,8 @@ GBINDER_IO_FN(decode_binder_object)(
const void* data,
gsize size,
GBinderObjectRegistry* reg,
GBinderRemoteObject** out)
GBinderRemoteObject** out,
const GBinderRpcProtocol* protocol)
{
const struct flat_binder_object* obj = data;
@@ -530,15 +541,18 @@ GBINDER_IO_FN(decode_binder_object)(
if (out) {
*out = gbinder_object_registry_get_remote(reg, obj->handle,
REMOTE_REGISTRY_CAN_CREATE_AND_ACQUIRE);
if (*out && protocol->finish_unflatten_binder) {
protocol->finish_unflatten_binder(obj + 1, *out);
}
}
return sizeof(*obj);
return sizeof(*obj) + protocol->flat_binder_object_extra;
case BINDER_TYPE_BINDER:
if (!obj->binder) {
/* That's a NULL reference */
if (out) {
*out = NULL;
}
return sizeof(*obj);
return sizeof(*obj) + protocol->flat_binder_object_extra;
}
/* fallthrough */
default:

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-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:
*
@@ -126,7 +126,7 @@ struct gbinder_io {
} br;
/* Size of the object and its extra data */
gsize (*object_size)(const void* obj);
gsize (*object_size)(const void* obj, const GBinderRpcProtocol* protocol);
gsize (*object_data_size)(const void* obj);
/* Writes pointer to the buffer. The destination buffer must have
@@ -142,8 +142,9 @@ struct gbinder_io {
guint (*encode_cookie)(void* out, guint64 cookie);
/* Encode flat_buffer_object */
#define GBINDER_MAX_BINDER_OBJECT_SIZE (24)
guint (*encode_local_object)(void* out, GBinderLocalObject* obj);
#define GBINDER_MAX_BINDER_OBJECT_SIZE (28)
guint (*encode_local_object)(void* out, GBinderLocalObject* obj,
const GBinderRpcProtocol* protocol);
guint (*encode_remote_object)(void* out, GBinderRemoteObject* obj);
guint (*encode_fd_object)(void* out, int fd);
guint (*encode_fda_object)(void* out, const GBinderFds *fds,
@@ -189,9 +190,11 @@ struct gbinder_io {
void (*decode_transaction_data)(const void* data, GBinderIoTxData* tx);
void* (*decode_ptr_cookie)(const void* data);
guint (*decode_cookie)(const void* data, guint64* cookie);
guint (*decode_binder_handle)(const void* obj, guint32* handle);
guint (*decode_binder_handle)(const void* obj, guint32* handle,
const GBinderRpcProtocol* protocol);
guint (*decode_binder_object)(const void* data, gsize size,
GBinderObjectRegistry* reg, GBinderRemoteObject** obj);
GBinderObjectRegistry* reg, GBinderRemoteObject** obj,
const GBinderRpcProtocol* protocol);
guint (*decode_buffer_object)(GBinderBuffer* buf, gsize offset,
GBinderIoBufferObject* out);
guint (*decode_fd_object)(const void* data, gsize size, int* fd);

View File

@@ -58,11 +58,13 @@
#include <time.h>
typedef struct gbinder_ipc_looper GBinderIpcLooper;
typedef GObjectClass GBinderIpcClass;
struct gbinder_ipc_priv {
GBinderIpc* self;
GThreadPool* tx_pool;
GHashTable* tx_table;
char* dev;
char* key;
const char* name;
GBinderObjectRegistry object_registry;
@@ -78,11 +80,12 @@ struct gbinder_ipc_priv {
GBinderIpcLooper* blocked_loopers;
};
typedef GObjectClass GBinderIpcClass;
#define PARENT_CLASS gbinder_ipc_parent_class
#define THIS_TYPE gbinder_ipc_get_type()
#define THIS(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, THIS_TYPE, GBinderIpc)
GType THIS_TYPE GBINDER_INTERNAL;
G_DEFINE_TYPE(GBinderIpc, gbinder_ipc, G_TYPE_OBJECT)
#define GBINDER_TYPE_IPC (gbinder_ipc_get_type())
#define GBINDER_IPC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GBINDER_TYPE_IPC, GBinderIpc))
/*
* Binder requests are blocking, worker threads are needed in order to
@@ -263,6 +266,15 @@ gbinder_ipc_wait(
return FALSE;
}
static
char*
gbinder_ipc_make_key(
const char* dev,
const char* protocol)
{
return g_strdup_printf("%s:%s", protocol, dev);
}
/*==========================================================================*
* GBinderIpcLooperTx
*==========================================================================*/
@@ -1845,18 +1857,21 @@ gbinder_ipc_new(
const char* protocol_name)
{
GBinderIpc* self = NULL;
char* key;
const GBinderRpcProtocol* protocol = (protocol_name ?
gbinder_rpc_protocol_by_name(protocol_name) : NULL);
if (!dev || !dev[0]) dev = GBINDER_DEFAULT_BINDER;
if (!protocol) protocol = gbinder_rpc_protocol_for_device(dev);
key = gbinder_ipc_make_key(dev, protocol->name);
/* Lock */
pthread_mutex_lock(&gbinder_ipc_mutex);
if (gbinder_ipc_table) {
self = g_hash_table_lookup(gbinder_ipc_table, dev);
self = g_hash_table_lookup(gbinder_ipc_table, key);
}
if (self) {
g_free(key);
gbinder_ipc_ref(self);
} else {
GBinderDriver* driver = gbinder_driver_new(dev, protocol);
@@ -1864,10 +1879,11 @@ gbinder_ipc_new(
if (driver) {
GBinderIpcPriv* priv;
self = g_object_new(GBINDER_TYPE_IPC, NULL);
self = g_object_new(THIS_TYPE, NULL);
priv = self->priv;
self->driver = driver;
self->dev = priv->key = g_strdup(dev);
self->dev = priv->dev = g_strdup(dev);
priv->key = key;
self->priv->object_registry.io = gbinder_driver_io(driver);
/* gbinder_ipc_dispose will remove iself from the table */
if (!gbinder_ipc_table) {
@@ -1875,8 +1891,10 @@ gbinder_ipc_new(
}
g_hash_table_replace(gbinder_ipc_table, priv->key, self);
/* With "/dev/" prefix, it may be too long to be a thread name */
priv->name = priv->key +
(g_str_has_prefix(priv->key, "/dev/") ? 5 : 0);
priv->name = self->dev +
(g_str_has_prefix(priv->dev, "/dev/") ? 5 : 0);
} else {
g_free(key);
}
}
pthread_mutex_unlock(&gbinder_ipc_mutex);
@@ -1889,7 +1907,7 @@ gbinder_ipc_ref(
GBinderIpc* self)
{
if (G_LIKELY(self)) {
g_object_ref(GBINDER_IPC(self));
g_object_ref(THIS(self));
return self;
} else {
return NULL;
@@ -1901,7 +1919,7 @@ gbinder_ipc_unref(
GBinderIpc* self)
{
if (G_LIKELY(self)) {
g_object_unref(GBINDER_IPC(self));
g_object_unref(THIS(self));
}
}
@@ -2039,7 +2057,7 @@ gbinder_ipc_init(
.get_local = gbinder_ipc_object_registry_get_local,
.get_remote = gbinder_ipc_object_registry_get_remote
};
GBinderIpcPriv* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, GBINDER_TYPE_IPC,
GBinderIpcPriv* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, THIS_TYPE,
GBinderIpcPriv);
g_mutex_init(&priv->looper_mutex);
@@ -2090,7 +2108,7 @@ void
gbinder_ipc_dispose(
GObject* object)
{
GBinderIpc* self = GBINDER_IPC(object);
GBinderIpc* self = THIS(object);
GVERBOSE_("%s", self->dev);
/* Lock */
@@ -2114,7 +2132,7 @@ gbinder_ipc_dispose(
/* Unlock */
gbinder_ipc_stop_loopers(self);
G_OBJECT_CLASS(gbinder_ipc_parent_class)->finalize(object);
G_OBJECT_CLASS(PARENT_CLASS)->dispose(object);
}
static
@@ -2122,7 +2140,7 @@ void
gbinder_ipc_finalize(
GObject* object)
{
GBinderIpc* self = GBINDER_IPC(object);
GBinderIpc* self = THIS(object);
GBinderIpcPriv* priv = self->priv;
GASSERT(!priv->local_objects);
@@ -2136,8 +2154,9 @@ gbinder_ipc_finalize(
GASSERT(!g_hash_table_size(priv->tx_table));
g_hash_table_unref(priv->tx_table);
gbinder_driver_unref(self->driver);
g_free(priv->dev);
g_free(priv->key);
G_OBJECT_CLASS(gbinder_ipc_parent_class)->finalize(object);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}
static
@@ -2173,7 +2192,7 @@ gbinder_ipc_exit()
/* Unlock */
for (i = ipcs; i; i = i->next) {
GBinderIpc* ipc = GBINDER_IPC(i->data);
GBinderIpc* ipc = THIS(i->data);
GBinderIpcPriv* priv = ipc->priv;
GThreadPool* pool = priv->tx_pool;
GSList* local_objs = NULL;

View File

@@ -89,6 +89,15 @@ static const char hidl_base_interface[] = "android.hidl.base@1.0::IBase";
* Implementation
*==========================================================================*/
static
GBinderLocalReply*
gbinder_local_object_create_reply(
GBinderLocalObject* self)
{
return gbinder_local_reply_new(gbinder_local_object_io(self),
gbinder_local_object_protocol(self));
}
static
GBINDER_LOCAL_TRANSACTION_SUPPORT
gbinder_local_object_default_can_handle_transaction(
@@ -139,8 +148,7 @@ gbinder_local_object_ping_transaction(
GBinderRemoteRequest* req,
int* status)
{
const GBinderIo* io = gbinder_local_object_io(self);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalReply* reply = gbinder_local_object_create_reply(self);
GVERBOSE(" PING_TRANSACTION");
gbinder_local_reply_append_int32(reply, GBINDER_STATUS_OK);
@@ -155,9 +163,8 @@ gbinder_local_object_interface_transaction(
GBinderRemoteRequest* req,
int* status)
{
const GBinderIo* io = gbinder_local_object_io(self);
GBinderLocalObjectPriv* priv = self->priv;
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalReply* reply = gbinder_local_object_create_reply(self);
GVERBOSE(" INTERFACE_TRANSACTION");
gbinder_local_reply_append_string16(reply, priv->ifaces[0]);
@@ -173,8 +180,7 @@ gbinder_local_object_hidl_ping_transaction(
int* status)
{
/*android.hidl.base@1.0::IBase interfaceDescriptor() */
const GBinderIo* io = gbinder_local_object_io(self);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalReply* reply = gbinder_local_object_create_reply(self);
GVERBOSE(" HIDL_PING_TRANSACTION \"%s\"",
gbinder_remote_request_interface(req));
@@ -191,9 +197,8 @@ gbinder_local_object_hidl_get_descriptor_transaction(
int* status)
{
/*android.hidl.base@1.0::IBase interfaceDescriptor() */
const GBinderIo* io = gbinder_local_object_io(self);
GBinderLocalObjectPriv* priv = self->priv;
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalReply* reply = gbinder_local_object_create_reply(self);
GBinderWriter writer;
GVERBOSE(" HIDL_GET_DESCRIPTOR_TRANSACTION \"%s\"",
@@ -213,8 +218,7 @@ gbinder_local_object_hidl_descriptor_chain_transaction(
int* status)
{
/*android.hidl.base@1.0::IBase interfaceChain() */
const GBinderIo* io = gbinder_local_object_io(self);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalReply* reply = gbinder_local_object_create_reply(self);
GBinderWriter writer;
GVERBOSE(" HIDL_DESCRIPTOR_CHAIN_TRANSACTION \"%s\"",
@@ -480,7 +484,7 @@ gbinder_local_object_new_reply(
GBinderLocalObject* self)
{
if (G_LIKELY(self)) {
return gbinder_local_reply_new(gbinder_local_object_io(self));
return gbinder_local_object_create_reply(self);
}
return NULL;
}

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-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:
*
@@ -92,6 +92,8 @@ GType gbinder_local_object_get_type(void) GBINDER_INTERNAL;
#define gbinder_local_object_dev(obj) (gbinder_driver_dev((obj)->ipc->driver))
#define gbinder_local_object_io(obj) (gbinder_driver_io((obj)->ipc->driver))
#define gbinder_local_object_protocol(obj) \
(gbinder_driver_protocol((obj)->ipc->driver))
GBinderLocalObject*
gbinder_local_object_new_with_type(

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-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:
*
@@ -72,10 +72,12 @@ gbinder_local_reply_output_buffers_size(
GBinderLocalReply*
gbinder_local_reply_new(
const GBinderIo* io)
const GBinderIo* io,
const GBinderRpcProtocol* protocol)
{
GASSERT(io);
if (io) {
GASSERT(protocol);
if (io && protocol) {
GBinderLocalReply* self = g_slice_new0(GBinderLocalReply);
GBinderWriterData* data = &self->data;
GBinderOutputData* out = &self->out;
@@ -87,6 +89,7 @@ gbinder_local_reply_new(
g_atomic_int_set(&self->refcount, 1);
data->io = io;
data->protocol = protocol;
out->bytes = data->bytes = g_byte_array_new();
out->f = &local_reply_output_fn;
return self;

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-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:
*
@@ -39,7 +39,8 @@
GBinderLocalReply*
gbinder_local_reply_new(
const GBinderIo* io)
const GBinderIo* io,
const GBinderRpcProtocol* protocol)
GBINDER_INTERNAL;
GBinderOutputData*

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-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:
*
@@ -74,10 +74,12 @@ gbinder_local_request_output_buffers_size(
GBinderLocalRequest*
gbinder_local_request_new(
const GBinderIo* io,
const GBinderRpcProtocol* protocol,
GBytes* init)
{
GASSERT(io);
if (io) {
GASSERT(protocol);
if (io && protocol) {
GBinderLocalRequest* self = g_slice_new0(GBinderLocalRequest);
GBinderWriterData* writer = &self->data;
GBinderOutputData* out = &self->out;
@@ -89,6 +91,7 @@ gbinder_local_request_new(
g_atomic_int_set(&self->refcount, 1);
writer->io = io;
writer->protocol = protocol;
if (init) {
gsize size;
gconstpointer data = g_bytes_get_data(init, &size);
@@ -111,9 +114,10 @@ gbinder_local_request_new_iface(
const GBinderRpcProtocol* protocol,
const char* iface)
{
GBinderLocalRequest* self = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* self = gbinder_local_request_new(io, protocol, NULL);
if (self && G_LIKELY(protocol) && G_LIKELY(iface)) {
/* gbinder_local_request_new() fails if protocol is NULL */
if (self && G_LIKELY(iface)) {
GBinderWriter writer;
gbinder_local_request_init_writer(self, &writer);
@@ -128,7 +132,7 @@ gbinder_local_request_new_from_data(
GBinderObjectConverter* convert)
{
GBinderLocalRequest* self = gbinder_local_request_new
(gbinder_buffer_io(buffer), NULL);
(gbinder_buffer_io(buffer), gbinder_buffer_protocol(buffer), NULL);
if (self) {
gbinder_writer_data_append_contents(&self->data, buffer, 0, convert);

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-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:
*
@@ -40,6 +40,7 @@
GBinderLocalRequest*
gbinder_local_request_new(
const GBinderIo* io,
const GBinderRpcProtocol* protocol,
GBytes* init)
GBINDER_INTERNAL;

View File

@@ -352,7 +352,8 @@ gbinder_reader_read_nullable_object(
if (gbinder_reader_can_read_object(p)) {
const GBinderReaderData* data = p->data;
const guint eaten = data->reg->io->decode_binder_object(p->ptr,
gbinder_reader_bytes_remaining(reader), data->reg, out);
gbinder_reader_bytes_remaining(reader), data->reg, out,
gbinder_buffer_protocol(data->buffer));
if (eaten) {
p->ptr += eaten;

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-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:
*
@@ -131,8 +131,9 @@ gbinder_remote_reply_convert_to_local(
GBinderObjectRegistry* reg = d->reg;
if (reg) {
return gbinder_local_reply_set_contents
(gbinder_local_reply_new(reg->io), d->buffer, convert);
return gbinder_local_reply_set_contents(gbinder_local_reply_new
(reg->io, gbinder_buffer_protocol(d->buffer)),
d->buffer, convert);
}
}
return NULL;

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.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:
*
@@ -212,12 +212,23 @@ gbinder_rpc_protocol_aidl3_read_rpc_header(
return *iface;
}
static
void
gbinder_rpc_protocol_aidl3_finish_flatten_binder(
void* out,
GBinderLocalObject* obj)
{
*(guint32*)out = GBINDER_STABILITY_SYSTEM;
}
static const GBinderRpcProtocol gbinder_rpc_protocol_aidl3 = {
.name = "aidl3",
.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
.read_rpc_header = gbinder_rpc_protocol_aidl3_read_rpc_header,
.flat_binder_object_extra = 4,
.finish_flatten_binder = gbinder_rpc_protocol_aidl3_finish_flatten_binder
};
/*==========================================================================*

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.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:
*
@@ -47,6 +47,17 @@ struct gbinder_rpc_protocol {
void (*write_rpc_header)(GBinderWriter* writer, const char* iface);
const char* (*read_rpc_header)(GBinderReader* reader, guint32 txcode,
char** iface);
/*
* For the sake of simplicity, let's assume that the trailer has a
* fixed size and that size is the same on both 32 and 64 bit platforms.
* Also note that finish_unflatten_binder() is only invoked for the
* remote objects that are not NULL, otherwise flat_binder_object_extra
* bytes are just skipped.
*/
gsize flat_binder_object_extra;
void (*finish_flatten_binder)(void* out, GBinderLocalObject* obj);
void (*finish_unflatten_binder)(const void* in, GBinderRemoteObject* obj);
};
const GBinderRpcProtocol*

View File

@@ -83,11 +83,12 @@ static const GBinderServiceManagerType gbinder_servicemanager_types[] = {
{ "aidl", gbinder_servicemanager_aidl_get_type },
{ "aidl2", gbinder_servicemanager_aidl2_get_type },
{ "aidl3", gbinder_servicemanager_aidl3_get_type },
{ "aidl4", gbinder_servicemanager_aidl4_get_type },
{ "hidl", gbinder_servicemanager_hidl_get_type }
};
#define SERVICEMANAGER_TYPE_AIDL (gbinder_servicemanager_types + 0)
#define SERVICEMANAGER_TYPE_HIDL (gbinder_servicemanager_types + 3)
#define SERVICEMANAGER_TYPE_HIDL (gbinder_servicemanager_types + 4)
#define SERVICEMANAGER_TYPE_DEFAULT SERVICEMANAGER_TYPE_AIDL
static GHashTable* gbinder_servicemanager_map = NULL;

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020-2022 Jolla Ltd.
* Copyright (C) 2020-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -51,10 +51,6 @@ typedef struct gbinder_servicemanager_aidl_class {
#define GBINDER_TYPE_SERVICEMANAGER_AIDL \
gbinder_servicemanager_aidl_get_type()
#define GBINDER_SERVICEMANAGER_AIDL_CLASS(klass) \
G_TYPE_CHECK_CLASS_CAST((klass), GBINDER_TYPE_SERVICEMANAGER_AIDL, \
GBinderServiceManagerAidlClass)
#define GBINDER_SERVICEMANAGER_AIDL_GET_CLASS(obj) \
G_TYPE_INSTANCE_GET_CLASS((obj), GBINDER_TYPE_SERVICEMANAGER_AIDL, \
GBinderServiceManagerAidlClass)

View File

@@ -45,8 +45,6 @@ G_DEFINE_TYPE(GBinderServiceManagerAidl2,
GBINDER_TYPE_SERVICEMANAGER_AIDL)
#define PARENT_CLASS gbinder_servicemanager_aidl2_parent_class
#define DUMP_FLAG_PRIORITY_DEFAULT (0x08)
#define DUMP_FLAG_PRIORITY_ALL (0x0f)
static
GBinderLocalRequest*

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021 Gary Wang <gary.wang@canonical.com>
* Copyright (C) 2021 Madhushan Nishantha <jlmadushan@gmail.com>
*
@@ -32,7 +32,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gbinder_servicemanager_aidl.h"
#include "gbinder_servicemanager_aidl_p.h"
#include "gbinder_client_p.h"
#include "gbinder_reader_p.h"
@@ -50,14 +50,6 @@ G_DEFINE_TYPE(GBinderServiceManagerAidl3,
#define PARENT_CLASS gbinder_servicemanager_aidl3_parent_class
enum gbinder_stability_level {
UNDECLARED = 0,
VENDOR = 0b000011,
SYSTEM = 0b001100,
VINTF = 0b111111
};
static
GBinderRemoteObject*
gbinder_servicemanager_aidl3_get_service(
GBinderServiceManager* self,
@@ -76,7 +68,7 @@ gbinder_servicemanager_aidl3_get_service(
CHECK_SERVICE_TRANSACTION, req, status, api);
gbinder_remote_reply_init_reader(reply, &reader);
gbinder_reader_read_int32(&reader, NULL /* stability */);
gbinder_reader_read_int32(&reader, NULL /* status? */);
obj = gbinder_reader_read_object(&reader);
gbinder_remote_reply_unref(reply);
@@ -84,28 +76,6 @@ gbinder_servicemanager_aidl3_get_service(
return obj;
}
static
GBinderLocalRequest*
gbinder_servicemanager_aidl3_add_service_req(
GBinderClient* client,
const char* name,
GBinderLocalObject* obj)
{
GBinderLocalRequest* req = gbinder_client_new_request(client);
gbinder_local_request_append_string16(req, name);
gbinder_local_request_append_local_object(req, obj);
/*
* Starting from Android 11, to add a service, Android framework requires
* an additional field `stability` when reading a strong binder.
*/
gbinder_local_request_append_int32(req, SYSTEM);
gbinder_local_request_append_int32(req, 0);
gbinder_local_request_append_int32(req, DUMP_FLAG_PRIORITY_DEFAULT);
return req;
}
static
char**
gbinder_servicemanager_aidl3_list(
GBinderServiceManager* manager,
@@ -148,6 +118,22 @@ gbinder_servicemanager_aidl3_list(
return (char**)g_ptr_array_free(list, FALSE);
}
static
GBinderLocalRequest*
gbinder_servicemanager_aidl3_add_service_req(
GBinderClient* client,
const char* name,
GBinderLocalObject* obj)
{
GBinderLocalRequest* req = gbinder_client_new_request(client);
gbinder_local_request_append_string16(req, name);
gbinder_local_request_append_local_object(req, obj);
gbinder_local_request_append_int32(req, 0);
gbinder_local_request_append_int32(req, DUMP_FLAG_PRIORITY_DEFAULT);
return req;
}
static
void
gbinder_servicemanager_aidl3_init(

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2020-2022 Jolla Ltd.
* Copyright (C) 2020-2022 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021 Gary Wang <gary.wang@canonical.com>
* Copyright (C) 2021 Madhushan Nishantha <jlmadushan@gmail.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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gbinder_servicemanager_aidl_p.h"
#include "gbinder_client_p.h"
#include "gbinder_reader_p.h"
#include <gbinder_local_request.h>
#include <gbinder_remote_reply.h>
/* Variant of AIDL servicemanager appeared in Android 12 (API level 31) */
typedef GBinderServiceManagerAidl GBinderServiceManagerAidl4;
typedef GBinderServiceManagerAidlClass GBinderServiceManagerAidl4Class;
G_DEFINE_TYPE(GBinderServiceManagerAidl4,
gbinder_servicemanager_aidl4,
GBINDER_TYPE_SERVICEMANAGER_AIDL)
#define PARENT_CLASS gbinder_servicemanager_aidl4_parent_class
#define BINDER_WIRE_FORMAT_VERSION (1)
static
GBinderLocalRequest*
gbinder_servicemanager_aidl4_add_service_req(
GBinderClient* client,
const char* name,
GBinderLocalObject* obj)
{
GBinderLocalRequest* req = gbinder_client_new_request(client);
gbinder_local_request_append_string16(req, name);
gbinder_local_request_append_local_object(req, obj);
/*
* When reading nullable strong binder, from Android 12, the format of
* the `stability` field passed on the wire was changed and evolved to
* `struct Category`, which consists of the following members with 4 bytes
* long.
*
* struct Category {
* uint8_t version;
* uint8_t reserved[2];
* Level level; <- bitmask of Stability::Level
* }
*
* Hmmm, is that ^ really true?
*/
gbinder_local_request_append_int32(req,
GBINDER_FOURCC(GBINDER_STABILITY_SYSTEM, 0, 0,
BINDER_WIRE_FORMAT_VERSION));
gbinder_local_request_append_int32(req, 0);
gbinder_local_request_append_int32(req, DUMP_FLAG_PRIORITY_DEFAULT);
return req;
}
static
void
gbinder_servicemanager_aidl4_init(
GBinderServiceManagerAidl* self)
{
}
static
void
gbinder_servicemanager_aidl4_class_init(
GBinderServiceManagerAidl4Class* cls)
{
GBinderServiceManagerClass* manager = GBINDER_SERVICEMANAGER_CLASS(cls);
cls->add_service_req = gbinder_servicemanager_aidl4_add_service_req;
manager->list = gbinder_servicemanager_aidl3_list;
manager->get_service = gbinder_servicemanager_aidl3_get_service;
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021 Gary Wang <gary.wang@canonical.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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GBINDER_SERVICEMANAGER_AIDL_PRIVATE_H
#define GBINDER_SERVICEMANAGER_AIDL_PRIVATE_H
#include "gbinder_servicemanager_aidl.h"
char**
gbinder_servicemanager_aidl3_list(
GBinderServiceManager* manager,
const GBinderIpcSyncApi* api)
GBINDER_INTERNAL;
GBinderRemoteObject*
gbinder_servicemanager_aidl3_get_service(
GBinderServiceManager* manager,
const char* name,
int* status,
const GBinderIpcSyncApi* api)
GBINDER_INTERNAL;
#endif /* GBINDER_SERVICEMANAGER_AIDL_PRIVATE_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -112,6 +112,7 @@ gbinder_servicemanager_exit(
GType gbinder_servicemanager_aidl_get_type(void) GBINDER_INTERNAL;
GType gbinder_servicemanager_aidl2_get_type(void) GBINDER_INTERNAL;
GType gbinder_servicemanager_aidl3_get_type(void) GBINDER_INTERNAL;
GType gbinder_servicemanager_aidl4_get_type(void) GBINDER_INTERNAL;
GType gbinder_servicemanager_hidl_get_type(void) GBINDER_INTERNAL;
#endif /* GBINDER_SERVICEMANAGER_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.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:
*
@@ -50,10 +50,12 @@ struct gbinder_servicepoll {
GBinderEventLoopTimeout* timer;
};
#define PARENT_CLASS gbinder_servicepoll_parent_class
#define THIS_TYPE gbinder_servicepoll_get_type()
#define THIS(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, THIS_TYPE, GBinderServicePoll)
GType THIS_TYPE GBINDER_INTERNAL;
G_DEFINE_TYPE(GBinderServicePoll, gbinder_servicepoll, G_TYPE_OBJECT)
#define GBINDER_TYPE_SERVICEPOLL (gbinder_servicepoll_get_type())
#define GBINDER_SERVICEPOLL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GBINDER_TYPE_SERVICEPOLL, GBinderServicePoll))
enum gbinder_servicepoll_signal {
SIGNAL_NAME_ADDED,
@@ -76,7 +78,7 @@ gbinder_servicepoll_list(
char** services,
void* user_data)
{
GBinderServicePoll* self = GBINDER_SERVICEPOLL(user_data);
GBinderServicePoll* self = THIS(user_data);
gbinder_servicepoll_ref(self);
self->list_id = 0;
@@ -122,7 +124,7 @@ gboolean
gbinder_servicepoll_timer(
gpointer user_data)
{
GBinderServicePoll* self = GBINDER_SERVICEPOLL(user_data);
GBinderServicePoll* self = THIS(user_data);
if (!self->list_id) {
self->list_id = gbinder_servicemanager_list(self->manager,
@@ -136,7 +138,7 @@ GBinderServicePoll*
gbinder_servicepoll_create(
GBinderServiceManager* manager)
{
GBinderServicePoll* self = g_object_new(GBINDER_TYPE_SERVICEPOLL, NULL);
GBinderServicePoll* self = g_object_new(THIS_TYPE, NULL);
self->manager = gbinder_servicemanager_ref(manager);
self->list_id = gbinder_servicemanager_list(manager,
@@ -171,7 +173,7 @@ gbinder_servicepoll_ref(
GBinderServicePoll* self)
{
if (G_LIKELY(self)) {
g_object_ref(GBINDER_SERVICEPOLL(self));
g_object_ref(THIS(self));
return self;
} else {
return NULL;
@@ -183,7 +185,7 @@ gbinder_servicepoll_unref(
GBinderServicePoll* self)
{
if (G_LIKELY(self)) {
g_object_unref(GBINDER_SERVICEPOLL(self));
g_object_unref(THIS(self));
}
}
@@ -240,12 +242,13 @@ void
gbinder_servicepoll_finalize(
GObject* object)
{
GBinderServicePoll* self = GBINDER_SERVICEPOLL(object);
GBinderServicePoll* self = THIS(object);
gbinder_timeout_remove(self->timer);
gbinder_servicemanager_cancel(self->manager, self->list_id);
gbinder_servicemanager_unref(self->manager);
g_strfreev(self->list);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}
static

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-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:
*
@@ -77,6 +77,13 @@ 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

@@ -52,6 +52,20 @@ typedef struct gbinder_writer_priv {
GBinderWriterData* data;
} GBinderWriterPriv;
const GBinderWriterType gbinder_writer_type_byte = { "int32", 4, NULL };
const GBinderWriterType gbinder_writer_type_int32 = { "byte", 1, NULL };
static const GBinderWriterField gbinder_writer_type_hidl_string_f[] = {
{
"hidl_string.data.str", 0, NULL,
gbinder_writer_field_hidl_string_write_buf, NULL
},
GBINDER_WRITER_FIELD_END()
};
const GBinderWriterType gbinder_writer_type_hidl_string = {
"hidl_string", sizeof(GBinderHidlString),
gbinder_writer_type_hidl_string_f
};
G_STATIC_ASSERT(sizeof(GBinderWriter) >= sizeof(GBinderWriterPriv));
GBINDER_INLINE_FUNC GBinderWriterPriv* gbinder_writer_cast(GBinderWriter* pub)
@@ -92,6 +106,7 @@ gbinder_writer_data_append_contents(
gbinder_buffer_contents_ref(contents));
if (objects && *objects) {
const GBinderIo* io = gbinder_buffer_io(buffer);
const GBinderRpcProtocol* proto = gbinder_buffer_protocol(buffer);
/* GBinderIo must be the same because it's defined by the kernel */
GASSERT(io == data->io);
@@ -114,21 +129,22 @@ gbinder_writer_data_append_contents(
gutil_int_array_append(data->offsets, dest->len);
/* Convert remote object into local if necessary */
if (convert && io->decode_binder_handle(obj, &handle) &&
if (convert && io->decode_binder_handle(obj, &handle, proto) &&
(local = gbinder_object_converter_handle_to_local
(convert, handle))) {
const guint pos = dest->len;
g_byte_array_set_size(dest, pos +
GBINDER_MAX_BINDER_OBJECT_SIZE);
objsize = io->encode_local_object(dest->data + pos, local);
objsize = io->encode_local_object(dest->data + pos,
local, proto);
g_byte_array_set_size(dest, pos + objsize);
/* Keep the reference */
data->cleanup = gbinder_cleanup_add(data->cleanup,
(GDestroyNotify) gbinder_local_object_unref, local);
} else {
objsize = io->object_size(obj);
objsize = io->object_size(obj, proto);
g_byte_array_append(dest, obj, objsize);
}
@@ -729,6 +745,102 @@ gbinder_writer_append_buffer_object(
return 0;
}
static
void
gbinder_writer_append_fields(
GBinderWriter* writer,
const void* obj,
const GBinderWriterField* fields,
const GBinderParent* parent) /* Since 1.1.27 */
{
if (fields) {
const GBinderWriterField* field = fields;
const guint8* base_ptr = obj;
GBinderParent parent2;
parent2.index = parent->index;
for (field = fields; field->type || field->write_buf; field++) {
const void* field_ptr = base_ptr + field->offset;
parent2.offset = parent->offset + field->offset;
if (field->write_buf) {
field->write_buf(writer, field_ptr, field, &parent2);
} else {
gbinder_writer_append_buffer_object_with_parent(writer,
*(void**)field_ptr, field->type->size, &parent2);
}
}
}
}
/*
* Note that gbinder_writer_append_struct doesn't copy the data, it writes
* buffer objects pointing to whatever was passed in. The caller must make
* sure that those pointers outlive the transaction. That's most commonly
* done with by using gbinder_writer_malloc() and friends for allocating
* memory for the transaction.
*/
void
gbinder_writer_append_struct(
GBinderWriter* writer,
const void* ptr,
const GBinderWriterType* type,
const GBinderParent* parent) /* Since 1.1.27 */
{
if (type) {
GBinderParent child;
child.offset = 0;
child.index = gbinder_writer_append_buffer_object_with_parent(writer,
ptr, type->size, parent);
gbinder_writer_append_fields(writer, ptr, type->fields, &child);
} else {
/* No type - no fields */
gbinder_writer_append_buffer_object_with_parent(writer, ptr, 0, parent);
}
}
void
gbinder_writer_field_hidl_vec_write_buf(
GBinderWriter* writer,
const void* ptr,
const GBinderWriterField* field,
const GBinderParent* parent) /* Since 1.1.27 */
{
const GBinderHidlVec* vec = ptr;
const guint8* buf = vec->data.ptr;
const GBinderWriterType* elem_type = field->type;
if (elem_type) {
GBinderParent child;
guint i;
child.index = gbinder_writer_append_buffer_object_with_parent
(writer, buf, vec->count * elem_type->size, parent);
for (i = 0; i < vec->count; i++) {
child.offset = elem_type->size * i;
gbinder_writer_append_fields(writer, buf + child.offset,
elem_type->fields, &child);
}
} else {
/* Probably a programming error but write an empty buffer anyway */
gbinder_writer_append_buffer_object_with_parent(writer, buf, 0, parent);
}
}
void
gbinder_writer_field_hidl_string_write_buf(
GBinderWriter* writer,
const void* ptr,
const GBinderWriterField* field,
const GBinderParent* parent) /* Since 1.1.27 */
{
const GBinderHidlString* str = ptr;
gbinder_writer_append_buffer_object_with_parent(writer, str->data.str,
str->data.str ? (str->len + 1) : 0, parent);
}
guint
gbinder_writer_data_append_buffer_object(
GBinderWriterData* data,
@@ -1012,7 +1124,7 @@ gbinder_writer_data_append_local_object(
/* Preallocate enough space */
g_byte_array_set_size(buf, offset + GBINDER_MAX_BINDER_OBJECT_SIZE);
/* Write the object */
n = data->io->encode_local_object(buf->data + offset, obj);
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 */

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-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:
*
@@ -39,6 +39,7 @@
typedef struct gbinder_writer_data {
const GBinderIo* io;
const GBinderRpcProtocol* protocol;
GByteArray* bytes;
GUtilIntArray* offsets;
gsize buffers_size;

View File

@@ -1,140 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = ashmem-test
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
include ../common/Makefile

View File

@@ -1,154 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = binder-bridge
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
#
# Install
#
INSTALL = install
INSTALL_BIN_DIR = $(DESTDIR)/usr/bin
install: release $(INSTALL_BIN_DIR)
$(INSTALL) -m 755 $(RELEASE_EXE) $(INSTALL_BIN_DIR)
$(INSTALL_BIN_DIR):
$(INSTALL) -d $@
include ../common/Makefile

View File

@@ -49,10 +49,9 @@ CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include -I$(GEN_DIR) -I$(SRC_DIR)
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
CFLAGS += -fPIC $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
LDFLAGS += -pie $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021 Franz-Josef Haider <franz.haider@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
@@ -80,9 +80,11 @@ go_through_transaction_ast(
switch(v->type) {
case INT8_TYPE:
if (cur_pass == BUILD_TRANSACTION) GDEBUG("int8");
if (cur_pass == BUILD_TRANSACTION) {
GDEBUG("int8 %u", (guint)(*((guint8*)v->value)));
}
if (parent_idx == -1) {
gbinder_writer_append_int32(&app->writer, *((int*)v->value));
gbinder_writer_append_int8(&app->writer, *((guint8*)v->value));
} else if (cur_pass == FILL_BUFFERS) {
*((unsigned char*)(((char*)buf)+offset)) =
*((unsigned char*)v->value);
@@ -91,7 +93,9 @@ go_through_transaction_ast(
break;
case INT32_TYPE:
if (cur_pass == BUILD_TRANSACTION) GDEBUG("int32");
if (cur_pass == BUILD_TRANSACTION) {
GDEBUG("int32 %d", *((int*)v->value));
}
if (parent_idx == -1) {
gbinder_writer_append_int32(&app->writer, *((int*)v->value));
} else if (cur_pass == FILL_BUFFERS) {
@@ -101,7 +105,9 @@ go_through_transaction_ast(
break;
case INT64_TYPE:
if (cur_pass == BUILD_TRANSACTION) GDEBUG("int64");
if (cur_pass == BUILD_TRANSACTION) {
GDEBUG("int64 %" G_GINT64_MODIFIER "d", *((gint64*)v->value));
}
if (parent_idx == -1) {
gbinder_writer_append_int64(&app->writer, *((gint64*)v->value));
} else if (cur_pass == FILL_BUFFERS) {
@@ -111,7 +117,9 @@ go_through_transaction_ast(
break;
case FLOAT_TYPE:
if (cur_pass == BUILD_TRANSACTION) GDEBUG("float");
if (cur_pass == BUILD_TRANSACTION) {
GDEBUG("float %g", (double)*((float*)v->value));
}
if (parent_idx == -1) {
gbinder_writer_append_float(&app->writer, *((float*)v->value));
} else if (cur_pass == FILL_BUFFERS) {
@@ -120,7 +128,9 @@ go_through_transaction_ast(
offset += sizeof(float);
break;
case DOUBLE_TYPE:
if (cur_pass == BUILD_TRANSACTION) GDEBUG("double");
if (cur_pass == BUILD_TRANSACTION) {
GDEBUG("double %g", *((double*)v->value));
}
if (parent_idx == -1) {
gbinder_writer_append_double(&app->writer,*((double*)v->value));
} else if (cur_pass == FILL_BUFFERS) {
@@ -130,7 +140,9 @@ go_through_transaction_ast(
break;
case STRING8_TYPE:
if (cur_pass == BUILD_TRANSACTION) GDEBUG("string8");
if (cur_pass == BUILD_TRANSACTION) {
GDEBUG("string8 %s", (char*)v->value);
}
gbinder_writer_append_string8(&app->writer, v->value);
/* offset not incremented since it only makes sense for hidl */
break;
@@ -579,7 +591,7 @@ app_run(
App* app)
{
const AppOptions* opt = app->opt;
char* iface = opt->iface ? g_strdup(opt->iface) : NULL;
char* iface;
int status = 0;
int rargc = 1;
char* service = opt->argv[rargc++];
@@ -598,7 +610,6 @@ app_run(
service, &status);
if (!obj) {
GERR("No such service: %s", service);
g_free(iface);
return;
}
@@ -764,14 +775,34 @@ app_init(
gutil_log_default.level = GLOG_LEVEL_DEFAULT;
if (g_option_context_parse(options, &argc, &argv, &error)) {
char* help;
int i;
/*
* Remove the "--" argument. If any of our arguments is a negative
* number, the user will have to add the "--" flag to stop the parser.
* But "--" is still passed to us and we have to ignore it.
*/
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--")) {
if (i < (argc - 1)) {
memmove(argv + i, argv + (i + 1),
sizeof(char*) * (argc - i - 1));
}
i--;
argc--;
/*
* There's no need to have more than one "--", but let's
* remove any number of those.
*/
}
}
if (argc > 2) {
opt->argc = argc;
opt->argv = argv;
ok = TRUE;
} else {
help = g_option_context_get_help(options, TRUE, NULL);
char* help = g_option_context_get_help(options, TRUE, NULL);
fprintf(stderr, "%s", help);
g_free(help);
}
@@ -800,7 +831,6 @@ int main(int argc, char* argv[])
GERR("servicemanager seems to be missing");
}
}
g_free(opt.iface);
g_free(opt.dev);
return app.ret;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021-2022 Jolla Ltd.
*
* You may use this file under the terms of BSD license as follows:
*
@@ -36,7 +36,6 @@
typedef struct app_options {
char* dev;
char* iface;
gboolean oneway;
gboolean aidl;
gint transaction;

View File

@@ -55,11 +55,11 @@ char* handle_str8(char* text) {
"}" { return('}'); }
"[" { return('['); }
"]" { return(']'); }
{D}*{INT8_SUFFIX} { cmdlinelval.int8_value = atoi(yytext); return(INT8_VALUE); }
{D}*{INT64_SUFFIX} { cmdlinelval.int64_value = atol(yytext); return(INT64_VALUE); }
{D}* { cmdlinelval.int32_value = atoi(yytext); return(INT32_VALUE); }
{D}+"."{D}*{INT64_SUFFIX} { cmdlinelval.double_value = atof(yytext); return(DOUBLE_VALUE); }
{D}+"."{D}* { cmdlinelval.float_value = atof(yytext); return(FLOAT_VALUE); }
-?{D}+{INT8_SUFFIX} { cmdlinelval.int8_value = atoi(yytext); return(INT8_VALUE); }
-?{D}+{INT64_SUFFIX} { cmdlinelval.int64_value = atol(yytext); return(INT64_VALUE); }
-?{D}+ { cmdlinelval.int32_value = atoi(yytext); return(INT32_VALUE); }
-?{D}+"."{D}*{INT64_SUFFIX} { cmdlinelval.double_value = atof(yytext); return(DOUBLE_VALUE); }
-?{D}+"."{D}* { cmdlinelval.float_value = atof(yytext); return(FLOAT_VALUE); }
"reply" { return(REPLY); }
\".*\"{HSTRING_SUFFIX} { cmdlinelval.hstring_value = handle_str(yytext); return(HSTRING_VALUE); }
\".*\"{UTF16_SUFFIX} { cmdlinelval.string16_value = handle_str(yytext); return(STRING16_VALUE); }

View File

@@ -1,140 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = binder-client
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
include ../common/Makefile

View File

@@ -1,140 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = binder-dump
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
include ../common/Makefile

View File

@@ -171,6 +171,8 @@ app_init(
app_log_verbose, "Enable verbose output", NULL },
{ "quiet", 'q', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
app_log_quiet, "Be quiet", NULL },
{ "device", 'd', 0, G_OPTION_ARG_STRING, &opt->dev,
"Binder device [" DEV_DEFAULT "]", "DEVICE" },
{ NULL }
};
@@ -187,7 +189,7 @@ app_init(
if (g_option_context_parse(options, &argc, &argv, &error)) {
char* help;
opt->dev = g_strdup(DEV_DEFAULT);
if (!opt->dev || !opt->dev[0]) opt->dev = g_strdup(DEV_DEFAULT);
switch (argc) {
case 2:
opt->service = argv[1];

View File

@@ -1,154 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = binder-list
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
#
# Install
#
INSTALL = install
INSTALL_BIN_DIR = $(DESTDIR)/usr/bin
install: release $(INSTALL_BIN_DIR)
$(INSTALL) -m 755 $(RELEASE_EXE) $(INSTALL_BIN_DIR)
$(INSTALL_BIN_DIR):
$(INSTALL) -d $@
include ../common/Makefile

View File

@@ -1,154 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = binder-ping
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
#
# Install
#
INSTALL = install
INSTALL_BIN_DIR = $(DESTDIR)/usr/bin
install: release $(INSTALL_BIN_DIR)
$(INSTALL) -m 755 $(RELEASE_EXE) $(INSTALL_BIN_DIR)
$(INSTALL_BIN_DIR):
$(INSTALL) -d $@
include ../common/Makefile

View File

@@ -1,140 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = binder-service
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
include ../common/Makefile

152
test/common/Makefile Normal file
View File

@@ -0,0 +1,152 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release install clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Executable must be defined
#
ifndef EXE
${error EXE not defined}
endif
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Sources
#
SRC ?= $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
CFLAGS += -fPIC $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS += -pie $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
KEEP_SYMBOLS ?= 0
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@$(MAKE) $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@$(MAKE) $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
#
# Install
#
INSTALL = install
INSTALL_BIN_DIR = $(DESTDIR)/usr/bin
install: release $(INSTALL_BIN_DIR)
$(INSTALL) -m 755 $(RELEASE_EXE) $(INSTALL_BIN_DIR)
$(INSTALL_BIN_DIR):
$(INSTALL) -d $@

View File

@@ -1,140 +1,5 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all debug release clean cleaner
.PHONY: libgbinder-release libgbinder-debug
#
# Required packages
#
PKGS = glib-2.0 gio-2.0 gio-unix-2.0 libglibutil
#
# Default target
#
all: debug release
#
# Executable
#
EXE = rild-card-status
#
# Sources
#
SRC = $(EXE).c
#
# Directories
#
SRC_DIR = .
BUILD_DIR = build
LIB_DIR = ../..
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
#
# Tools and flags
#
CC ?= $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall
INCLUDES = -I$(LIB_DIR)/include
BASE_FLAGS = -fPIC
CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
LDFLAGS = $(BASE_FLAGS) $(shell pkg-config --libs $(PKGS))
QUIET_MAKE = make --no-print-directory
DEBUG_FLAGS = -g
RELEASE_FLAGS =
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
SUBMAKE_OPTS += KEEP_SYMBOLS=1
endif
DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(CFLAGS) $(RELEASE_FLAGS) -O2
#
# Files
#
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
DEBUG_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_so)
RELEASE_SO_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_so)
DEBUG_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_link)
RELEASE_LINK_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_link)
DEBUG_SO = $(LIB_DIR)/$(DEBUG_SO_FILE)
RELEASE_SO = $(LIB_DIR)/$(RELEASE_SO_FILE)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
#
# Rules
#
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
debug: libgbinder-debug $(DEBUG_EXE)
release: libgbinder-release $(RELEASE_EXE)
clean:
rm -f *~
rm -fr $(BUILD_DIR)
cleaner: clean
@make -C $(LIB_DIR) clean
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
$(DEBUG_EXE): $(DEBUG_SO) $(DEBUG_BUILD_DIR) $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) $< -o $@
$(RELEASE_EXE): $(RELEASE_SO) $(RELEASE_BUILD_DIR) $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) $< -o $@
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
libgbinder-debug:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(DEBUG_SO_FILE) $(DEBUG_LINK_FILE)
libgbinder-release:
@make $(SUBMAKE_OPTS) -C $(LIB_DIR) $(RELEASE_SO_FILE) $(RELEASE_LINK_FILE)
include ../common/Makefile

View File

@@ -25,6 +25,7 @@ all:
@$(MAKE) -C unit_servicemanager_aidl $*
@$(MAKE) -C unit_servicemanager_aidl2 $*
@$(MAKE) -C unit_servicemanager_aidl3 $*
@$(MAKE) -C unit_servicemanager_aidl4 $*
@$(MAKE) -C unit_servicemanager_hidl $*
@$(MAKE) -C unit_servicename $*
@$(MAKE) -C unit_servicepoll $*

View File

@@ -69,11 +69,6 @@ static GMainLoop* test_binder_exit_loop = NULL;
#define BINDER_SET_MAX_THREADS _IOW('b', 5, guint32)
#define BINDER_BUFFER_FLAG_HAS_PARENT 0x01
#define B_TYPE_LARGE 0x85
#define BINDER_TYPE_BINDER GBINDER_FOURCC('s', 'b', '*', B_TYPE_LARGE)
#define BINDER_TYPE_HANDLE GBINDER_FOURCC('s', 'h', '*', B_TYPE_LARGE)
#define BINDER_TYPE_PTR GBINDER_FOURCC('p', 't', '*', B_TYPE_LARGE)
#define TF_ONE_WAY 0x01
#define TF_ROOT_OBJECT 0x04
#define TF_STATUS_CODE 0x08

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-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:
*
@@ -35,6 +35,16 @@
#include "test_common.h"
#define B_TYPE_LARGE 0x85
#define BINDER_TYPE_BINDER GBINDER_FOURCC('s', 'b', '*', B_TYPE_LARGE)
#define BINDER_TYPE_HANDLE GBINDER_FOURCC('s', 'h', '*', B_TYPE_LARGE)
#define BINDER_TYPE_PTR GBINDER_FOURCC('p', 't', '*', B_TYPE_LARGE)
#define BUFFER_OBJECT_SIZE_32 (24)
#define BUFFER_OBJECT_SIZE_64 (40)
#define BINDER_OBJECT_SIZE_32 (16)
#define BINDER_OBJECT_SIZE_64 (24)
typedef struct test_binder TestBinder;
void

View File

@@ -27,6 +27,7 @@ unit_servicemanager \
unit_servicemanager_aidl \
unit_servicemanager_aidl2 \
unit_servicemanager_aidl3 \
unit_servicemanager_aidl4 \
unit_servicemanager_hidl \
unit_servicename \
unit_servicepoll \

View File

@@ -277,7 +277,8 @@ test_sync_reply_tx(
GBinderDriver* driver = gbinder_client_ipc(client)->driver;
int fd = gbinder_driver_fd(driver);
const GBinderIo* io = gbinder_driver_io(driver);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
const GBinderRpcProtocol* protocol = gbinder_driver_protocol(driver);
GBinderLocalReply* reply = gbinder_local_reply_new(io, protocol);
GBinderRemoteReply* tx_reply;
GBinderOutputData* data;
const guint32 handle = 0;
@@ -380,7 +381,8 @@ test_reply_tx(
GBinderDriver* driver = gbinder_client_ipc(client)->driver;
int fd = gbinder_driver_fd(driver);
const GBinderIo* io = gbinder_driver_io(driver);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
const GBinderRpcProtocol* protocol = gbinder_driver_protocol(driver);
GBinderLocalReply* reply = gbinder_local_reply_new(io, protocol);
GBinderOutputData* data;
const guint32 handle = 0;
const guint32 code = 1;

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020-2022 Jolla Ltd.
* Copyright (C) 2020-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -231,6 +231,7 @@ test_dirs(
char* file1 = g_build_filename(subdir, "a.conf", NULL);
char* file2 = g_build_filename(subdir, "b.conf", NULL);
char* file3 = g_build_filename(subdir, "c.conf", NULL);
char* file4 = g_build_filename(subdir, "d.conf", NULL);
char* random_file = g_build_filename(subdir, "foo", NULL);
static const char garbage[] = "foo";
static const char config[] =
@@ -252,6 +253,11 @@ test_dirs(
"/dev/binder3 = aidl3\n"
"[ServiceManager]\n"
"/dev/binder3 = aidl3\n";
static const char config4[] =
"[Protocol]\n"
"/dev/binder4 = aidl3\n"
"[ServiceManager]\n"
"/dev/binder4 = aidl4\n";
g_assert_cmpint(mkdir(subdir, 0700), == ,0);
g_assert_cmpint(mkdir(notafile, 0700), == ,0);
@@ -259,6 +265,7 @@ test_dirs(
g_assert(g_file_set_contents(file1, config1, -1, NULL));
g_assert(g_file_set_contents(file2, config2, -1, NULL));
g_assert(g_file_set_contents(file3, config3, -1, NULL));
g_assert(g_file_set_contents(file4, config4, -1, NULL));
g_assert(g_file_set_contents(random_file, garbage, -1, NULL));
/* Reset the state */
@@ -271,10 +278,12 @@ test_dirs(
g_assert(k);
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder",b), == ,"aidl2");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder3",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder4",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"Protocol","/dev/hbinder",b), == ,"hidl");
g_assert_cmpstr(test_value(k,"Protocol","/dev/hwbinder",b), == ,"hidl");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder",b),==,"aidl2");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder3",b),==,"aidl3");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder4",b),==,"aidl4");
/* Remove the default file and try again */
gbinder_config_exit();
@@ -284,9 +293,11 @@ test_dirs(
g_assert(!test_value(k,"Protocol","/dev/hbinder",b));
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder",b), == ,"aidl2");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder3",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder4",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"Protocol","/dev/hwbinder",b), == ,"hidl");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder",b),==,"aidl2");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder3",b),==,"aidl3");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder4",b),==,"aidl4");
/* Damage one of the files and try again */
gbinder_config_exit();
@@ -297,8 +308,10 @@ test_dirs(
g_assert(!test_value(k,"Protocol","/dev/hwbinder",b));
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder",b), == ,"aidl2");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder3",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder4",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder",b),==,"aidl2");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder3",b),==,"aidl3");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder4",b),==,"aidl4");
/* Disallow access to one of the files and try again */
gbinder_config_exit();
@@ -309,14 +322,27 @@ test_dirs(
g_assert(!test_value(k,"Protocol","/dev/hwbinder",b));
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder",b), == ,"aidl2");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder3",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder4",b), == ,"aidl3");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder",b),==,"aidl2");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder3",b),==,"aidl3");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder4",b),==,"aidl4");
/* Delete the remaining files and try again */
/* Leave only one file (file4) in the subdirectory */
gbinder_config_exit();
g_assert_cmpint(remove(file1), == ,0);
g_assert_cmpint(remove(file2), == ,0);
g_assert_cmpint(remove(file3), == ,0);
k = gbinder_config_get();
g_assert(k);
g_assert(!test_value(k,"Protocol","/dev/hbinder",b));
g_assert(!test_value(k,"Protocol","/dev/hwbinder",b));
g_assert(!test_value(k,"Protocol","/dev/binder3",b));
g_assert_cmpstr(test_value(k,"Protocol","/dev/binder4",b),==,"aidl3");
g_assert_cmpstr(test_value(k,"ServiceManager","/dev/binder4",b),==,"aidl4");
/* Delete the remaining file and try again */
gbinder_config_exit();
g_assert_cmpint(remove(file4), == ,0);
g_assert(!gbinder_config_get());
/* Undo all the damage */
@@ -329,6 +355,7 @@ test_dirs(
g_free(file1);
g_free(file2);
g_free(file3);
g_free(file4);
g_free(random_file);
remove(notafile);
@@ -495,6 +522,20 @@ static const TestPresetsData test_presets_data [] = {
"[ServiceManager]\n"
"/dev/binder = aidl3\n"
"/dev/vndbinder = aidl3\n"
},{
"31",
"[General]\n"
"ApiLevel = 31",
"[General]\n"
"ApiLevel = 31\n"
"[Protocol]\n"
"/dev/binder = aidl3\n"
"/dev/vndbinder = aidl3\n"
"[ServiceManager]\n"
"/dev/binder = aidl4\n"
"/dev/vndbinder = aidl4\n"
}
};

View File

@@ -70,6 +70,24 @@ test_quit_when_destroyed(
test_quit_later((GMainLoop*)loop);
}
static
GBinderLocalRequest*
test_local_request_new(
GBinderIpc* ipc)
{
return gbinder_local_request_new(gbinder_driver_io(ipc->driver),
gbinder_driver_protocol(ipc->driver), NULL);
}
static
GBinderLocalReply*
test_local_reply_new(
GBinderIpc* ipc)
{
return gbinder_local_reply_new(gbinder_driver_io(ipc->driver),
gbinder_driver_protocol(ipc->driver));
}
/*==========================================================================*
* null
*==========================================================================*/
@@ -79,26 +97,25 @@ void
test_null(
void)
{
GBinderIpc* null = NULL;
int status = INT_MAX;
g_assert(!gbinder_ipc_ref(null));
gbinder_ipc_unref(null);
g_assert(!gbinder_ipc_sync_main.sync_reply(null, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_main.sync_reply(null, 0, 0, NULL, &status));
g_assert(!gbinder_ipc_ref(NULL));
gbinder_ipc_unref(NULL);
g_assert(!gbinder_ipc_sync_main.sync_reply(NULL, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_main.sync_reply(NULL, 0, 0, NULL, &status));
g_assert_cmpint(status, == ,-EINVAL);
g_assert(!gbinder_ipc_sync_worker.sync_reply(null, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_worker.sync_reply(null, 0, 0, NULL, &status));
g_assert(!gbinder_ipc_sync_worker.sync_reply(NULL, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_worker.sync_reply(NULL, 0, 0, NULL, &status));
g_assert_cmpint(status, == ,-EINVAL);
g_assert_cmpint(gbinder_ipc_sync_main.sync_oneway(null, 0, 0, NULL), == ,
g_assert_cmpint(gbinder_ipc_sync_main.sync_oneway(NULL, 0, 0, NULL), == ,
-EINVAL);
g_assert_cmpint(gbinder_ipc_sync_worker.sync_oneway(null, 0, 0, NULL), == ,
g_assert_cmpint(gbinder_ipc_sync_worker.sync_oneway(NULL, 0, 0, NULL), == ,
-EINVAL);
g_assert(!gbinder_ipc_transact(null, 0, 0, 0, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_transact_custom(null, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_object_registry(null));
gbinder_ipc_looper_check(null);
gbinder_ipc_cancel(null, 0);
g_assert(!gbinder_ipc_transact(NULL, 0, 0, 0, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_transact_custom(NULL, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_object_registry(NULL));
gbinder_ipc_looper_check(NULL);
gbinder_ipc_cancel(NULL, 0);
g_assert(!gbinder_object_registry_ref(NULL));
gbinder_object_registry_unref(NULL);
@@ -167,6 +184,29 @@ test_basic(
test_binder_exit_wait(&test_opt, NULL);
}
/*==========================================================================*
* protocol
*==========================================================================*/
static
void
test_protocol(
void)
{
/* GBinderIpc objects are identified by device + protocol combination */
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, "aidl");
GBinderIpc* ipc2 = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, "hidl");
g_assert(ipc);
g_assert(ipc2);
g_assert(ipc != ipc2);
gbinder_ipc_unref(ipc);
gbinder_ipc_unref(ipc2);
gbinder_ipc_exit();
test_binder_exit_wait(&test_opt, NULL);
}
/*==========================================================================*
* async_oneway
*==========================================================================*/
@@ -190,9 +230,8 @@ test_async_oneway(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = test_local_request_new(ipc);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id;
@@ -217,9 +256,8 @@ test_sync_oneway(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = test_local_request_new(ipc);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
test_binder_br_transaction_complete(fd);
g_assert_cmpint(gbinder_ipc_sync_main.sync_oneway(ipc, 0, 1, req), == ,0);
@@ -239,12 +277,11 @@ test_sync_reply_ok_status(
int* status)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalRequest* req = test_local_request_new(ipc);
GBinderLocalReply* reply = test_local_reply_new(ipc);
GBinderRemoteReply* tx_reply;
GBinderOutputData* data;
const int fd = gbinder_driver_fd(ipc->driver);
const guint32 handle = 0;
const guint32 code = 1;
const char* result_in = "foo";
@@ -296,9 +333,8 @@ test_sync_reply_error(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = test_local_request_new(ipc);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
const guint32 handle = 0;
const guint32 code = 1;
const gint expected_status = (-EINVAL);
@@ -365,13 +401,12 @@ test_transact_ok(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalRequest* req = test_local_request_new(ipc);
GBinderLocalReply* reply = test_local_reply_new(ipc);
GBinderOutputData* data;
const guint32 handle = 0;
const guint32 code = 1;
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id;
@@ -424,9 +459,8 @@ test_transact_dead(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = test_local_request_new(ipc);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id;
@@ -472,9 +506,8 @@ test_transact_failed(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = test_local_request_new(ipc);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id;
@@ -522,9 +555,8 @@ test_transact_status(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = test_local_request_new(ipc);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id;
@@ -776,7 +808,6 @@ test_transact_2way_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
const int fd = gbinder_driver_fd(ipc->driver);
const char* dev = gbinder_driver_dev(ipc->driver);
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
@@ -787,9 +818,9 @@ test_transact_2way_run(
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, ifaces, test_transact_2way_incoming_proc, &incoming_call);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* incoming_req = gbinder_local_request_new(io, NULL);
GBinderLocalReply* reply = gbinder_local_reply_new(io);
GBinderLocalRequest* req = test_local_request_new(ipc);
GBinderLocalRequest* incoming_req = test_local_request_new(ipc);
GBinderLocalReply* reply = test_local_reply_new(ipc);
GBinderWriter writer;
/* Prepare reply */
@@ -922,7 +953,6 @@ test_transact_incoming_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
const int fd = gbinder_driver_fd(ipc->driver);
const char* dev = gbinder_driver_dev(ipc->driver);
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
@@ -930,8 +960,8 @@ test_transact_incoming_run(
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, ifaces, test_transact_incoming_proc, loop);
GBinderLocalRequest* ping = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* ping = test_local_request_new(ipc);
GBinderLocalRequest* req = test_local_request_new(ipc);
GBinderWriter writer;
gbinder_local_request_init_writer(ping, &writer);
@@ -1003,7 +1033,6 @@ test_transact_status_reply_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
const int fd = gbinder_driver_fd(ipc->driver);
const char* dev = gbinder_driver_dev(ipc->driver);
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
@@ -1011,7 +1040,7 @@ test_transact_status_reply_run(
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, ifaces, test_transact_status_reply_proc, loop);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* req = test_local_request_new(ipc);
GBinderOutputData* data;
GBinderWriter writer;
@@ -1120,7 +1149,6 @@ test_transact_async_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
const int fd = gbinder_driver_fd(ipc->driver);
const char* dev = gbinder_driver_dev(ipc->driver);
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
@@ -1128,7 +1156,7 @@ test_transact_async_run(
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, ifaces, test_transact_async_proc, loop);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* req = test_local_request_new(ipc);
GBinderOutputData* data;
GBinderWriter writer;
@@ -1203,7 +1231,6 @@ test_transact_async_sync_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
const int fd = gbinder_driver_fd(ipc->driver);
const char* dev = gbinder_driver_dev(ipc->driver);
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
@@ -1211,7 +1238,7 @@ test_transact_async_sync_run(
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, ifaces, test_transact_async_sync_proc, loop);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* req = test_local_request_new(ipc);
GBinderOutputData* data;
GBinderWriter writer;
@@ -1318,8 +1345,7 @@ test_cancel_on_exit(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* req = test_local_request_new(ipc);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
int fd = gbinder_driver_fd(ipc->driver);
@@ -1350,6 +1376,7 @@ int main(int argc, char* argv[])
g_test_init(&argc, &argv, NULL);
g_test_add_func(TEST_("null"), test_null);
g_test_add_func(TEST_("basic"), test_basic);
g_test_add_func(TEST_("protocol"), test_protocol);
g_test_add_func(TEST_("async_oneway"), test_async_oneway);
g_test_add_func(TEST_("sync_oneway"), test_sync_oneway);
g_test_add_func(TEST_("sync_reply_ok"), test_sync_reply_ok);

View File

@@ -36,6 +36,7 @@
#include "gbinder_local_object.h"
#include "gbinder_local_reply_p.h"
#include "gbinder_output_data.h"
#include "gbinder_rpc_protocol.h"
#include "gbinder_buffer_p.h"
#include "gbinder_driver.h"
#include "gbinder_writer.h"
@@ -46,11 +47,6 @@
static TestOpt test_opt;
#define BUFFER_OBJECT_SIZE_32 (24)
#define BUFFER_OBJECT_SIZE_64 (GBINDER_MAX_BUFFER_OBJECT_SIZE)
#define BINDER_OBJECT_SIZE_32 (16)
#define BINDER_OBJECT_SIZE_64 (GBINDER_MAX_BINDER_OBJECT_SIZE)
static
void
test_int_inc(
@@ -70,6 +66,14 @@ test_buffer_from_bytes(
return gbinder_buffer_new(driver, bytes->data, bytes->len, NULL);
}
static
GBinderLocalReply*
test_local_reply_new()
{
return gbinder_local_reply_new(&gbinder_io_32,
gbinder_rpc_protocol_for_device(NULL));
}
/*==========================================================================*
* null
*==========================================================================*/
@@ -82,7 +86,10 @@ test_null(
GBinderWriter writer;
int count = 0;
g_assert(!gbinder_local_reply_new(NULL));
g_assert(!gbinder_local_reply_new(NULL, NULL));
g_assert(!gbinder_local_reply_new(&gbinder_io_32, NULL));
g_assert(!gbinder_local_reply_new(NULL,
gbinder_rpc_protocol_for_device(NULL)));
g_assert(!gbinder_local_reply_ref(NULL));
gbinder_local_reply_unref(NULL);
gbinder_local_reply_init_writer(NULL, NULL);
@@ -118,7 +125,7 @@ void
test_cleanup(
void)
{
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
int count = 0;
gbinder_local_reply_cleanup(reply, NULL, &count);
@@ -141,7 +148,7 @@ test_bool(
{
static const guint8 output_true[] = { 0x01, 0x00, 0x00, 0x00 };
static const guint8 output_false[] = { 0x00, 0x00, 0x00, 0x00 };
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
gbinder_local_reply_append_bool(reply, FALSE);
@@ -152,7 +159,7 @@ test_bool(
g_assert(!memcmp(data->bytes->data, output_false, data->bytes->len));
gbinder_local_reply_unref(reply);
reply = gbinder_local_reply_new(&gbinder_io_32);
reply = test_local_reply_new();
gbinder_local_reply_append_bool(reply, TRUE);
data = gbinder_local_reply_data(reply);
g_assert(!gbinder_output_data_offsets(data));
@@ -161,7 +168,7 @@ test_bool(
g_assert(!memcmp(data->bytes->data, output_true, data->bytes->len));
gbinder_local_reply_unref(reply);
reply = gbinder_local_reply_new(&gbinder_io_32);
reply = test_local_reply_new();
gbinder_local_reply_append_bool(reply, 42);
data = gbinder_local_reply_data(reply);
g_assert(!gbinder_output_data_offsets(data));
@@ -181,7 +188,7 @@ test_fd(
void)
{
const gint32 fd = 1;
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -206,7 +213,7 @@ test_int32(
void)
{
const guint32 value = 1234567;
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -221,7 +228,7 @@ test_int32(
gbinder_local_reply_unref(reply);
/* Same with writer */
reply = gbinder_local_reply_new(&gbinder_io_32);
reply = test_local_reply_new();
gbinder_local_reply_init_writer(reply, &writer);
gbinder_writer_append_int32(&writer, value);
data = gbinder_local_reply_data(reply);
@@ -242,7 +249,7 @@ test_int64(
void)
{
const guint64 value = 123456789;
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
gbinder_local_reply_append_int64(reply, value);
@@ -264,7 +271,7 @@ test_float(
void)
{
const gfloat value = 123456789;
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
gbinder_local_reply_append_float(reply, value);
@@ -286,7 +293,7 @@ test_double(
void)
{
const gdouble value = 123456789;
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
gbinder_local_reply_append_double(reply, value);
@@ -310,7 +317,7 @@ test_string8(
/* The size of the string gets aligned at 4-byte boundary */
static const char input[] = "test";
static const guint8 output[] = { 't', 'e', 's', 't', 0, 0, 0, 0 };
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
gbinder_local_reply_append_string8(reply, input);
@@ -322,7 +329,7 @@ test_string8(
gbinder_local_reply_unref(reply);
/* NULL string doesn't get encoded at all (should it be?) */
reply = gbinder_local_reply_new(&gbinder_io_32);
reply = test_local_reply_new();
gbinder_local_reply_append_string8(reply, NULL);
data = gbinder_local_reply_data(reply);
g_assert(!gbinder_output_data_offsets(data));
@@ -346,7 +353,7 @@ test_string16(
TEST_INT16_BYTES('x'), 0x00, 0x00
};
const gint32 null_output = -1;
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
gbinder_local_reply_append_string16(reply, input);
@@ -358,7 +365,7 @@ test_string16(
gbinder_local_reply_unref(reply);
/* NULL string gets encoded as -1 */
reply = gbinder_local_reply_new(&gbinder_io_32);
reply = test_local_reply_new();
gbinder_local_reply_append_string16(reply, NULL);
data = gbinder_local_reply_data(reply);
g_assert(!gbinder_output_data_offsets(data));
@@ -377,7 +384,7 @@ void
test_hidl_string(
void)
{
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -400,7 +407,7 @@ void
test_hidl_string_vec(
void)
{
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -436,22 +443,22 @@ test_local_object(
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_buffers_size(data));
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_64);
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_64);
gbinder_local_reply_unref(reply);
/* Append NULL object (with 32-bit I/O module) */
reply = gbinder_local_reply_new(&gbinder_io_32);
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(offsets->count == 1);
g_assert(offsets->data[0] == 0);
g_assert(!gbinder_output_data_buffers_size(data));
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_32);
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_reply_unref(reply);
gbinder_ipc_unref(ipc);
}
@@ -465,7 +472,7 @@ void
test_remote_object(
void)
{
GBinderLocalReply* reply = gbinder_local_reply_new(&gbinder_io_32);
GBinderLocalReply* reply = test_local_reply_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -494,7 +501,8 @@ test_remote_reply(
static const guint8 output[] = { 't', 'e', 's', 't', 0, 0, 0, 0 };
GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(driver);
GBinderLocalReply* req = gbinder_local_reply_new(io);
GBinderLocalReply* req = gbinder_local_reply_new(io,
gbinder_rpc_protocol_for_device(NULL));
GBinderLocalReply* req2;
GBinderOutputData* data2;
const GByteArray* bytes;
@@ -506,7 +514,7 @@ test_remote_reply(
/* Copy flat structures (no binder objects) */
buffer = test_buffer_from_bytes(driver, bytes);
req2 = gbinder_local_reply_new(io);
req2 = gbinder_local_reply_new(io, gbinder_rpc_protocol_for_device(NULL));
g_assert(gbinder_local_reply_set_contents(req2, buffer, NULL) == req2);
gbinder_buffer_free(buffer);

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-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:
*
@@ -35,6 +35,7 @@
#include "gbinder_local_request_p.h"
#include "gbinder_output_data.h"
#include "gbinder_rpc_protocol.h"
#include "gbinder_buffer_p.h"
#include "gbinder_driver.h"
#include "gbinder_writer.h"
@@ -44,11 +45,6 @@
static TestOpt test_opt;
#define BUFFER_OBJECT_SIZE_32 (24)
#define BUFFER_OBJECT_SIZE_64 (GBINDER_MAX_BUFFER_OBJECT_SIZE)
#define BINDER_OBJECT_SIZE_32 (16)
#define BINDER_OBJECT_SIZE_64 (GBINDER_MAX_BINDER_OBJECT_SIZE)
static
void
test_int_inc(
@@ -80,6 +76,14 @@ test_buffer_from_bytes_and_objects(
return gbinder_buffer_new(driver, bytes->data, bytes->len, objects);
}
static
GBinderLocalRequest*
test_local_request_new()
{
return gbinder_local_request_new(&gbinder_io_32,
gbinder_rpc_protocol_for_device(NULL), NULL);
}
/*==========================================================================*
* null
*==========================================================================*/
@@ -92,7 +96,10 @@ test_null(
GBinderWriter writer;
int count = 0;
g_assert(!gbinder_local_request_new(NULL, NULL));
g_assert(!gbinder_local_request_new(NULL, NULL, NULL));
g_assert(!gbinder_local_request_new(&gbinder_io_32, NULL, NULL));
g_assert(!gbinder_local_request_new(NULL,
gbinder_rpc_protocol_for_device(NULL), NULL));
g_assert(!gbinder_local_request_ref(NULL));
g_assert(!gbinder_local_request_new_from_data(NULL, NULL));
gbinder_local_request_unref(NULL);
@@ -125,7 +132,7 @@ void
test_cleanup(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
int count = 0;
gbinder_local_request_cleanup(req, NULL, &count);
@@ -149,7 +156,7 @@ test_init_data(
const guint8 init_data[] = { 0x01, 0x02, 0x03, 0x04 };
GBytes* init_bytes = g_bytes_new_static(init_data, sizeof(init_data));
GBinderLocalRequest* req = gbinder_local_request_new
(&gbinder_io_32, init_bytes);
(&gbinder_io_32, gbinder_rpc_protocol_for_device(NULL), init_bytes);
GBinderOutputData* data;
data = gbinder_local_request_data(req);
@@ -161,7 +168,7 @@ test_init_data(
gbinder_local_request_unref(req);
gbinder_local_request_unref(req);
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
data = gbinder_local_request_data(req);
g_assert(data->bytes);
g_assert(!data->bytes->len);
@@ -181,7 +188,7 @@ test_bool(
{
static const guint8 output_true[] = { 0x01, 0x00, 0x00, 0x00 };
static const guint8 output_false[] = { 0x00, 0x00, 0x00, 0x00 };
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
gbinder_local_request_append_bool(req, FALSE);
@@ -192,7 +199,7 @@ test_bool(
g_assert(!memcmp(data->bytes->data, output_false, data->bytes->len));
gbinder_local_request_unref(req);
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
gbinder_local_request_append_bool(req, TRUE);
data = gbinder_local_request_data(req);
g_assert(!gbinder_output_data_offsets(data));
@@ -201,7 +208,7 @@ test_bool(
g_assert(!memcmp(data->bytes->data, output_true, data->bytes->len));
gbinder_local_request_unref(req);
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
gbinder_local_request_append_bool(req, 42);
data = gbinder_local_request_data(req);
g_assert(!gbinder_output_data_offsets(data));
@@ -221,7 +228,7 @@ test_int32(
void)
{
const guint32 value = 1234567;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
gbinder_local_request_append_int32(req, value);
@@ -243,7 +250,7 @@ test_int64(
void)
{
const guint64 value = 123456789;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
gbinder_local_request_append_int64(req, value);
@@ -265,7 +272,7 @@ test_float(
void)
{
const gfloat value = 123456789;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
gbinder_local_request_append_float(req, value);
@@ -287,7 +294,7 @@ test_double(
void)
{
const gdouble value = 123456789;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
gbinder_local_request_append_double(req, value);
@@ -311,7 +318,7 @@ test_string8(
/* The size of the string gets aligned at 4-byte boundary */
static const char input[] = "test";
static const guint8 output[] = { 't', 'e', 's', 't', 0, 0, 0, 0 };
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
gbinder_local_request_append_string8(req, input);
@@ -323,7 +330,7 @@ test_string8(
gbinder_local_request_unref(req);
/* NULL string doesn't get encoded at all (should it be?) */
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
gbinder_local_request_append_string8(req, NULL);
data = gbinder_local_request_data(req);
g_assert(!gbinder_output_data_offsets(data));
@@ -347,7 +354,7 @@ test_string16(
TEST_INT16_BYTES('x'), 0x00, 0x00
};
const gint32 null_output = -1;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
gbinder_local_request_append_string16(req, input);
@@ -359,7 +366,7 @@ test_string16(
gbinder_local_request_unref(req);
/* NULL string gets encoded as -1 */
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
gbinder_local_request_append_string16(req, NULL);
data = gbinder_local_request_data(req);
g_assert(!gbinder_output_data_offsets(data));
@@ -378,7 +385,7 @@ void
test_hidl_string(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -401,7 +408,7 @@ void
test_hidl_string_vec(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -424,7 +431,7 @@ void
test_local_object(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -448,7 +455,7 @@ void
test_remote_object(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
@@ -477,7 +484,8 @@ test_remote_request(
static const guint8 output[] = { 't', 'e', 's', 't', 0, 0, 0, 0 };
GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
const GBinderRpcProtocol* protocol = gbinder_driver_protocol(driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, protocol, NULL);
GBinderLocalRequest* req2;
GBinderOutputData* data2;
const GByteArray* bytes;
@@ -549,7 +557,8 @@ test_remote_request_obj(
{
GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
const GBinderIo* io = gbinder_driver_io(driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
const GBinderRpcProtocol* protocol = gbinder_driver_protocol(driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, protocol, NULL);
GBinderLocalRequest* req2;
GBinderOutputData* data;
GUtilIntArray* offsets;

View File

@@ -393,7 +393,8 @@ test_write_header(
test_config_init2(&config, test->dev, test->prot);
prot = gbinder_rpc_protocol_for_device(test->dev);
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = gbinder_local_request_new(&gbinder_io_32,
gbinder_rpc_protocol_for_device(NULL), NULL);
gbinder_local_request_init_writer(req, &writer);
prot->write_rpc_header(&writer, test->iface);
data = gbinder_local_request_data(req);

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-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:
*
@@ -31,6 +31,7 @@
*/
#include "test_common.h"
#include "test_binder.h"
#include "gbinder_buffer_p.h"
#include "gbinder_driver.h"
@@ -44,9 +45,6 @@
static TestOpt test_opt;
#define BINDER_TYPE_BINDER GBINDER_FOURCC('s', 'b', '*', 0x85)
#define BINDER_OBJECT_SIZE_64 (GBINDER_MAX_BINDER_OBJECT_SIZE)
/*==========================================================================*
* Dummy GBinderObjectRegistry functions
*==========================================================================*/

View File

@@ -31,6 +31,7 @@
*/
#include "test_common.h"
#include "test_binder.h"
#include "gbinder_buffer_p.h"
#include "gbinder_config.h"
@@ -59,9 +60,6 @@ static TestOpt test_opt;
#define HIDL_RPC_HEADER \
'f', 'o', 'o', 0x00
#define BINDER_TYPE_BINDER GBINDER_FOURCC('s', 'b', '*', 0x85)
#define BINDER_OBJECT_SIZE_64 (GBINDER_MAX_BINDER_OBJECT_SIZE)
/*==========================================================================*
* null
*==========================================================================*/

View File

@@ -399,6 +399,14 @@ gbinder_servicemanager_aidl3_get_type()
return 0;
}
GType
gbinder_servicemanager_aidl4_get_type()
{
/* Dummy function to avoid pulling in gbinder_servicemanager_aidl4 */
g_assert_not_reached();
return 0;
}
/*==========================================================================*
* null
*==========================================================================*/

View File

@@ -71,6 +71,14 @@ gbinder_servicemanager_aidl3_get_type()
return 0;
}
GType
gbinder_servicemanager_aidl4_get_type()
{
/* Dummy function to avoid pulling in gbinder_servicemanager_aidl4 */
g_assert_not_reached();
return 0;
}
/*==========================================================================*
* Test service manager
*==========================================================================*/

View File

@@ -51,13 +51,6 @@ static TestOpt test_opt;
static const char TMP_DIR_TEMPLATE[] =
"gbinder-test-servicemanager_aidl3-XXXXXX";
enum gbinder_stability_level {
UNDECLARED = 0,
VENDOR = 0b000011,
SYSTEM = 0b001100,
VINTF = 0b111111
};
GType
gbinder_servicemanager_hidl_get_type()
{
@@ -109,7 +102,6 @@ servicemanager_aidl3_handler(
GBinderReader reader;
GBinderRemoteObject* remote_obj;
guint32 allow_isolated, dumpsys_priority;
gint32 stability;
char* str;
g_assert(!flags);
@@ -122,18 +114,18 @@ servicemanager_aidl3_handler(
gbinder_remote_request_init_reader(req, &reader);
str = gbinder_reader_read_string16(&reader);
if (str) {
reply = gbinder_local_object_new_reply(obj);
remote_obj = g_hash_table_lookup(self->objects, str);
if (remote_obj) {
GBinderWriter writer;
GBinderWriter writer;
remote_obj = g_hash_table_lookup(self->objects, str);
reply = gbinder_local_object_new_reply(obj);
gbinder_local_reply_init_writer(reply, &writer);
gbinder_writer_append_int32(&writer, GBINDER_STATUS_OK);
gbinder_writer_append_remote_object(&writer, remote_obj);
if (remote_obj) {
GDEBUG("Found name '%s' => %p", str, remote_obj);
gbinder_local_reply_init_writer(reply, &writer);
gbinder_writer_append_int32(&writer, UNDECLARED);
gbinder_writer_append_remote_object(&writer, remote_obj);
} else {
GDEBUG("Name '%s' not found", str);
gbinder_local_reply_append_int32(reply, GBINDER_STATUS_OK);
}
g_free(str);
}
@@ -142,8 +134,7 @@ servicemanager_aidl3_handler(
gbinder_remote_request_init_reader(req, &reader);
str = gbinder_reader_read_string16(&reader);
remote_obj = gbinder_reader_read_object(&reader);
gbinder_reader_read_int32(&reader, &stability);
if (str && remote_obj && stability == 0b001100 &&
if (str && remote_obj &&
gbinder_reader_read_uint32(&reader, &allow_isolated) &&
gbinder_reader_read_uint32(&reader, &dumpsys_priority)) {
GDEBUG("Adding '%s'", str);

View File

@@ -0,0 +1,5 @@
# -*- Mode: makefile-gmake -*-
EXE = unit_servicemanager_aidl4
include ../common/Makefile

View File

@@ -0,0 +1,485 @@
/*
* Copyright (C) 2020-2022 Jolla Ltd.
* Copyright (C) 2020-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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test_binder.h"
#include "gbinder_driver.h"
#include "gbinder_config.h"
#include "gbinder_ipc.h"
#include "gbinder_reader.h"
#include "gbinder_servicemanager_p.h"
#include "gbinder_rpc_protocol.h"
#include "gbinder_local_object_p.h"
#include "gbinder_local_reply.h"
#include "gbinder_remote_request.h"
#include "gbinder_remote_object.h"
#include "gbinder_writer.h"
#include <gutil_strv.h>
#include <gutil_log.h>
static TestOpt test_opt;
static const char TMP_DIR_TEMPLATE[] =
"gbinder-test-servicemanager_aidl4-XXXXXX";
GType
gbinder_servicemanager_hidl_get_type()
{
/* Dummy function to avoid pulling in gbinder_servicemanager_hidl */
g_assert_not_reached();
return 0;
}
/*==========================================================================*
* Test service manager
*==========================================================================*/
#define SVCMGR_HANDLE (0)
static const char SVCMGR_IFACE[] = "android.os.IServiceManager";
enum servicemanager_aidl_tx {
GET_SERVICE_TRANSACTION = GBINDER_FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION
};
const char* const servicemanager_aidl_ifaces[] = { SVCMGR_IFACE, NULL };
typedef GBinderLocalObjectClass ServiceManagerAidl4Class;
typedef struct service_manager_aidl4 {
GBinderLocalObject parent;
GHashTable* objects;
gboolean handle_on_looper_thread;
} ServiceManagerAidl4;
#define SERVICE_MANAGER_AIDL4_TYPE (service_manager_aidl4_get_type())
#define SERVICE_MANAGER_AIDL4(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
SERVICE_MANAGER_AIDL4_TYPE, ServiceManagerAidl4))
G_DEFINE_TYPE(ServiceManagerAidl4, service_manager_aidl4, \
GBINDER_TYPE_LOCAL_OBJECT)
/* This should be eventually handled at lower level. */
typedef struct category {
/*
* This is the version of the wire protocol associated with the host
* process of a particular binder. As the wire protocol changes, if
* sending a transaction to a binder with an old version, the Parcel
* class must write parcels according to the version documented here.
*/
gint8 version;
gint8 reserved[2];
gint8 level; /* bitmask of Stability::Level */
} Category;
static
GBinderLocalReply*
servicemanager_aidl4_handler(
GBinderLocalObject* obj,
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status,
void* user_data)
{
ServiceManagerAidl4* self = user_data;
GBinderLocalReply* reply = NULL;
GBinderReader reader;
GBinderRemoteObject* remote_obj;
guint32 allow_isolated, dumpsys_priority;
char* str;
Category category;
g_assert(!flags);
GDEBUG("%s %u", gbinder_remote_request_interface(req), code);
g_assert_cmpstr(gbinder_remote_request_interface(req), == ,SVCMGR_IFACE);
*status = -1;
switch (code) {
case GET_SERVICE_TRANSACTION:
case CHECK_SERVICE_TRANSACTION:
gbinder_remote_request_init_reader(req, &reader);
str = gbinder_reader_read_string16(&reader);
if (str) {
reply = gbinder_local_object_new_reply(obj);
remote_obj = g_hash_table_lookup(self->objects, str);
if (str) {
GBinderWriter writer;
remote_obj = g_hash_table_lookup(self->objects, str);
reply = gbinder_local_object_new_reply(obj);
gbinder_local_reply_init_writer(reply, &writer);
gbinder_writer_append_int32(&writer, GBINDER_STATUS_OK);
gbinder_writer_append_remote_object(&writer, remote_obj);
if (remote_obj) {
GDEBUG("Found name '%s' => %p", str, remote_obj);
} else {
GDEBUG("Name '%s' not found", str);
}
g_free(str);
}
}
break;
case ADD_SERVICE_TRANSACTION:
gbinder_remote_request_init_reader(req, &reader);
str = gbinder_reader_read_string16(&reader);
remote_obj = gbinder_reader_read_object(&reader);
gbinder_reader_read_uint32(&reader, (guint32*)&category);
if (str && remote_obj &&
category.level == GBINDER_STABILITY_SYSTEM &&
category.version == 1 &&
gbinder_reader_read_uint32(&reader, &allow_isolated) &&
gbinder_reader_read_uint32(&reader, &dumpsys_priority)) {
GDEBUG("Adding '%s'", str);
g_hash_table_replace(self->objects, str, remote_obj);
remote_obj = NULL;
str = NULL;
reply = gbinder_local_object_new_reply(obj);
*status = GBINDER_STATUS_OK;
}
g_free(str);
gbinder_remote_object_unref(remote_obj);
break;
case LIST_SERVICES_TRANSACTION:
gbinder_remote_request_init_reader(req, &reader);
if (gbinder_reader_read_uint32(&reader, &dumpsys_priority)) {
if (g_hash_table_size(self->objects) == 1) {
GList* keys = g_hash_table_get_keys(self->objects);
GList* l = g_list_nth(keys, 0);
gint32 srv_size = 1;
GBinderWriter writer;
reply = gbinder_local_object_new_reply(obj);
gbinder_local_reply_init_writer(reply, &writer);
gbinder_writer_append_int32(&writer, GBINDER_STATUS_OK);
gbinder_writer_append_int32(&writer, srv_size);
gbinder_writer_append_string16(&writer, l->data);
g_list_free(keys);
*status = GBINDER_STATUS_OK;
} else {
GDEBUG("Incorrect number of services %u",
g_hash_table_size(self->objects));
}
}
break;
default:
GDEBUG("Unhandled command %u", code);
break;
}
return reply;
}
static
ServiceManagerAidl4*
servicemanager_aidl4_new(
const char* dev,
gboolean handle_on_looper_thread)
{
ServiceManagerAidl4* self = g_object_new(SERVICE_MANAGER_AIDL4_TYPE, NULL);
GBinderLocalObject* obj = GBINDER_LOCAL_OBJECT(self);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
self->handle_on_looper_thread = handle_on_looper_thread;
gbinder_local_object_init_base(obj, ipc, servicemanager_aidl_ifaces,
servicemanager_aidl4_handler, self);
test_binder_set_looper_enabled(fd, TEST_LOOPER_ENABLE);
test_binder_register_object(fd, obj, SVCMGR_HANDLE);
gbinder_ipc_register_local_object(ipc, obj);
gbinder_ipc_unref(ipc);
return self;
}
static
GBINDER_LOCAL_TRANSACTION_SUPPORT
service_manager_aidl4_can_handle_transaction(
GBinderLocalObject* object,
const char* iface,
guint code)
{
ServiceManagerAidl4* self = SERVICE_MANAGER_AIDL4(object);
if (self->handle_on_looper_thread && !g_strcmp0(SVCMGR_IFACE, iface)) {
return GBINDER_LOCAL_TRANSACTION_LOOPER;
} else {
return GBINDER_LOCAL_OBJECT_CLASS(service_manager_aidl4_parent_class)->
can_handle_transaction(object, iface, code);
}
}
static
GBinderLocalReply*
service_manager_aidl4_handle_looper_transaction(
GBinderLocalObject* object,
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status)
{
if (!g_strcmp0(gbinder_remote_request_interface(req), SVCMGR_IFACE)) {
return GBINDER_LOCAL_OBJECT_CLASS(service_manager_aidl4_parent_class)->
handle_transaction(object, req, code, flags, status);
} else {
return GBINDER_LOCAL_OBJECT_CLASS(service_manager_aidl4_parent_class)->
handle_looper_transaction(object, req, code, flags, status);
}
}
static
void
service_manager_aidl4_finalize(
GObject* object)
{
ServiceManagerAidl4* self = SERVICE_MANAGER_AIDL4(object);
g_hash_table_destroy(self->objects);
G_OBJECT_CLASS(service_manager_aidl4_parent_class)->finalize(object);
}
static
void
service_manager_aidl4_init(
ServiceManagerAidl4* self)
{
self->objects = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gbinder_remote_object_unref);
}
static
void
service_manager_aidl4_class_init(
ServiceManagerAidl4Class* klass)
{
GObjectClass* object = G_OBJECT_CLASS(klass);
GBinderLocalObjectClass* local_object = GBINDER_LOCAL_OBJECT_CLASS(klass);
object->finalize = service_manager_aidl4_finalize;
local_object->can_handle_transaction =
service_manager_aidl4_can_handle_transaction;
local_object->handle_looper_transaction =
service_manager_aidl4_handle_looper_transaction;
}
/*==========================================================================*
* Test context
*==========================================================================*/
typedef struct test_context {
const char* default_config_dir;
const char* default_config_file;
char* config_dir;
char* config_subdir;
char* config_file;
GBinderLocalObject* object;
ServiceManagerAidl4* service;
GBinderServiceManager* client;
int fd;
} TestContext;
static
void
test_context_init(
TestContext* test)
{
const char* dev = GBINDER_DEFAULT_BINDER;
const char* other_dev = GBINDER_DEFAULT_BINDER "-private";
/*
* Also set defaults so that both /dev/binder and /dev/binder-private
* use the same protocol.
*/
const char* config =
"[Protocol]\n"
"Default = aidl3\n"
"/dev/binder = aidl3\n"
"[ServiceManager]\n"
"Default = aidl4\n"
"/dev/binder = aidl4\n";
GBinderIpc* ipc;
memset(test, 0, sizeof(*test));
test->default_config_dir = gbinder_config_dir;
test->default_config_file = gbinder_config_file;
test->config_dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
test->config_subdir = g_build_filename(test->config_dir, "d", NULL);
test->config_file = g_build_filename(test->config_dir, "test.conf", NULL);
g_assert(g_file_set_contents(test->config_file, config, -1, NULL));
GDEBUG("Config file %s", test->config_file);
gbinder_config_dir = test->config_subdir; /* Doesn't exist */
gbinder_config_file = test->config_file;
ipc = gbinder_ipc_new(dev, NULL);
test->fd = gbinder_driver_fd(ipc->driver);
test->object = gbinder_local_object_new(ipc, NULL, NULL, NULL);
/* Set up binder simulator */
test_binder_register_object(test->fd, test->object, AUTO_HANDLE);
test_binder_set_passthrough(test->fd, TRUE);
test->service = servicemanager_aidl4_new(other_dev, TRUE);
test->client = gbinder_servicemanager_new(dev);
gbinder_ipc_unref(ipc);
}
static
void
test_context_deinit(
TestContext* test)
{
test_binder_unregister_objects(test->fd);
gbinder_local_object_unref(test->object);
gbinder_local_object_drop(GBINDER_LOCAL_OBJECT(test->service));
gbinder_servicemanager_unref(test->client);
gbinder_ipc_exit();
test_binder_exit_wait(&test_opt, NULL);
remove(test->config_file);
remove(test->config_dir);
g_free(test->config_file);
g_free(test->config_subdir);
g_free(test->config_dir);
gbinder_config_dir = test->default_config_dir;
gbinder_config_file = test->default_config_file;
gbinder_config_exit();
}
/*==========================================================================*
* get
*==========================================================================*/
static
void
test_get_run()
{
TestContext test;
const char* name = "name";
int status = -1;
test_context_init(&test);
/* Query the object (it's not there yet) */
GDEBUG("Querying '%s'", name);
g_assert(!gbinder_servicemanager_get_service_sync(test.client,
name, &status));
g_assert_cmpint(status, == ,GBINDER_STATUS_OK);
/* Register object */
GDEBUG("Registering object '%s' => %p", name, test.object);
g_assert_cmpint(gbinder_servicemanager_add_service_sync(test.client,
name, test.object), == ,GBINDER_STATUS_OK);
g_assert_cmpuint(g_hash_table_size(test.service->objects), == ,1);
g_assert(g_hash_table_contains(test.service->objects, name));
/* Query the object (this time it must be there) */
GDEBUG("Querying '%s' again", name);
g_assert(gbinder_servicemanager_get_service_sync(test.client, name,
&status));
g_assert_cmpint(status, == ,GBINDER_STATUS_OK);
test_context_deinit(&test);
}
static
void
test_get()
{
test_run_in_context(&test_opt, test_get_run);
}
/*==========================================================================*
* list
*==========================================================================*/
static
void
test_list_run()
{
TestContext test;
const char* name = "name";
char** list;
test_context_init(&test);
/* Request the list */
list = gbinder_servicemanager_list_sync(test.client);
/* There's nothing there yet */
g_assert(list);
g_assert(!list[0]);
g_strfreev(list);
/* Register object */
GDEBUG("Registering object '%s' => %p", name, test.object);
g_assert_cmpint(gbinder_servicemanager_add_service_sync(test.client,
name, test.object), == ,GBINDER_STATUS_OK);
/* Request the list again */
list = gbinder_servicemanager_list_sync(test.client);
/* Now the name must be there */
g_assert_cmpuint(gutil_strv_length(list), == ,1);
g_assert_cmpstr(list[0], == ,name);
g_strfreev(list);
test_context_deinit(&test);
}
static
void
test_list()
{
test_run_in_context(&test_opt, test_list_run);
}
/*==========================================================================*
* Common
*==========================================================================*/
#define TEST_(t) "/servicemanager_aidl4/" t
int main(int argc, char* argv[])
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
g_type_init();
G_GNUC_END_IGNORE_DEPRECATIONS;
g_test_init(&argc, &argv, NULL);
g_test_add_func(TEST_("get"), test_get);
g_test_add_func(TEST_("list"), test_list);
test_init(&test_opt, argc, argv);
return g_test_run();
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -82,6 +82,14 @@ gbinder_servicemanager_aidl3_get_type()
return 0;
}
GType
gbinder_servicemanager_aidl4_get_type()
{
/* Dummy function to avoid pulling in gbinder_servicemanager_aidl4 */
g_assert_not_reached();
return 0;
}
/*==========================================================================*
* Common
*==========================================================================*/

View File

@@ -240,6 +240,12 @@ gbinder_servicemanager_aidl3_get_type()
return TEST_TYPE_SERVICEMANAGER;
}
GType
gbinder_servicemanager_aidl4_get_type()
{
return TEST_TYPE_SERVICEMANAGER;
}
GType
gbinder_servicemanager_hidl_get_type()
{

View File

@@ -206,6 +206,12 @@ gbinder_servicemanager_aidl3_get_type()
return TEST_TYPE_SERVICEMANAGER;
}
GType
gbinder_servicemanager_aidl4_get_type()
{
return TEST_TYPE_SERVICEMANAGER;
}
GType
gbinder_servicemanager_hidl_get_type()
{

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-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:
*
@@ -31,9 +31,12 @@
*/
#include "test_common.h"
#include "test_binder.h"
#include "gbinder_config.h"
#include "gbinder_fmq_p.h"
#include "gbinder_local_request_p.h"
#include "gbinder_rpc_protocol.h"
#include "gbinder_output_data.h"
#include "gbinder_writer_p.h"
#include "gbinder_io.h"
@@ -45,11 +48,82 @@
#include <errno.h>
static TestOpt test_opt;
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-writer-XXXXXX";
#define BUFFER_OBJECT_SIZE_32 (24)
#define BUFFER_OBJECT_SIZE_64 (GBINDER_MAX_BUFFER_OBJECT_SIZE)
#define BINDER_OBJECT_SIZE_32 (16)
#define BINDER_OBJECT_SIZE_64 (GBINDER_MAX_BINDER_OBJECT_SIZE)
static
GBinderLocalRequest*
test_local_request_new_with_io(
const GBinderIo* io)
{
return gbinder_local_request_new(io,
gbinder_rpc_protocol_for_device(GBINDER_DEFAULT_BINDER), NULL);
}
static
GBinderLocalRequest*
test_local_request_new()
{
return test_local_request_new_with_io(&gbinder_io_32);
}
static
GBinderLocalRequest*
test_local_request_new_64()
{
return test_local_request_new_with_io(&gbinder_io_64);
}
/*==========================================================================*
* Test context
*==========================================================================*/
typedef struct test_context {
const char* default_config_dir;
const char* default_config_file;
char* config_dir;
char* config_subdir;
char* config_file;
} TestContext;
static
void
test_context_init(
TestContext* test,
const char* prot)
{
memset(test, 0, sizeof(*test));
test->default_config_dir = gbinder_config_dir;
test->default_config_file = gbinder_config_file;
test->config_dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
test->config_subdir = g_build_filename(test->config_dir, "d", NULL);
test->config_file = g_build_filename(test->config_dir, "test.conf", NULL);
gbinder_config_dir = test->config_subdir; /* Doesn't exist */
gbinder_config_file = test->config_file;
if (prot) {
char* config = g_strdup_printf("[Protocol]\n"
GBINDER_DEFAULT_BINDER " = %s", prot);
GDEBUG("Config file %s", test->config_file);
g_assert(g_file_set_contents(test->config_file, config, -1, NULL));
g_free(config);
}
}
static
void
test_context_deinit(
TestContext* test)
{
remove(test->config_file);
remove(test->config_dir);
g_free(test->config_file);
g_free(test->config_subdir);
g_free(test->config_dir);
gbinder_config_dir = test->default_config_dir;
gbinder_config_file = test->default_config_file;
gbinder_config_exit();
gbinder_rpc_protocol_exit();
}
/*==========================================================================*
* null
@@ -147,7 +221,7 @@ void
test_cleanup(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderWriter writer;
const int value = 42;
const char* str = "foo";
@@ -181,7 +255,7 @@ test_int8(
const char encoded[] = {
TEST_INT8_BYTES_4(0x80)
};
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -208,7 +282,7 @@ test_int16(
const char encoded[] = {
TEST_INT16_BYTES_4(0x80ff)
};
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -233,7 +307,7 @@ test_int32(
void)
{
const guint32 value = 1234567;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -270,7 +344,7 @@ test_int64(
void)
{
const guint64 value = 12345678;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -294,7 +368,7 @@ test_float(
void)
{
const gfloat value = 12345678;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -318,7 +392,7 @@ test_double(
void)
{
const gdouble value = 12345678;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -346,7 +420,7 @@ test_bool(
TEST_INT8_BYTES_4(1),
TEST_INT8_BYTES_4(1)
};
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -373,7 +447,7 @@ test_bytes(
void)
{
const char value[] = { 0x01, 0x02, 0x03 };
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -398,7 +472,7 @@ test_string8(
{
/* The size of the string is aligned at 4-byte boundary */
static const char value[] = { 't', 'e', 's', 't', 0, 0, 0, 0 };
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -412,7 +486,7 @@ test_string8(
gbinder_local_request_unref(req);
/* NULL string writes nothing */
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_string8(&writer, NULL);
data = gbinder_local_request_data(req);
@@ -466,7 +540,7 @@ test_string16(
gconstpointer test_data)
{
const TestString16Data* test = test_data;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -535,7 +609,7 @@ test_utf16(
gconstpointer test_data)
{
const TestUtf16Data* test = test_data;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
@@ -588,7 +662,7 @@ test_hidl_vec(
gconstpointer test_data)
{
const TestHidlVecData* test = test_data;
GBinderLocalRequest* req = gbinder_local_request_new(test->io, NULL);
GBinderLocalRequest* req = test_local_request_new_with_io(test->io);
GBinderOutputData* data;
GBinderWriter writer;
GUtilIntArray* offsets;
@@ -653,7 +727,7 @@ test_hidl_string_xxx(
const TestHidlStringData* test,
void (*append)(GBinderWriter* writer, const char* str))
{
GBinderLocalRequest* req = gbinder_local_request_new(test->io, NULL);
GBinderLocalRequest* req = test_local_request_new_with_io(test->io);
GBinderOutputData* data;
GBinderWriter writer;
GUtilIntArray* offsets;
@@ -693,7 +767,7 @@ void
test_hidl_string2(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
GUtilIntArray* offsets;
@@ -763,7 +837,7 @@ test_hidl_string_vec(
gconstpointer test_data)
{
const TestHidlStringVecData* test = test_data;
GBinderLocalRequest* req = gbinder_local_request_new(test->io, NULL);
GBinderLocalRequest* req = test_local_request_new_with_io(test->io);
GBinderOutputData* data;
GBinderWriter writer;
GUtilIntArray* offsets;
@@ -787,16 +861,12 @@ test_hidl_string_vec(
* buffer
*==========================================================================*/
typedef struct test_data {
guint32 x;
} TestData;
static
void
test_buffer(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
guint32 x1 = 1;
guint32 x2 = 2;
GBinderOutputData* data;
@@ -823,6 +893,10 @@ test_buffer(
* parent
*==========================================================================*/
typedef struct test_data {
guint32 x;
} TestData;
typedef struct test_data_pointer {
TestData* ptr;
} TestDataPointer;
@@ -832,7 +906,7 @@ void
test_parent(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
TestData test_data;
TestDataPointer test;
GBinderOutputData* data;
@@ -886,7 +960,7 @@ test_parcelable(
test_data.x = 10;
/* Non-null */
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_parcelable(&writer, &test_data, sizeof(test_data));
@@ -898,7 +972,7 @@ test_parcelable(
gbinder_local_request_unref(req);
/* Null */
req = gbinder_local_request_new(&gbinder_io_32, NULL);
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_parcelable(&writer, NULL, 0);
@@ -910,6 +984,160 @@ test_parcelable(
gbinder_local_request_unref(req);
}
/*==========================================================================*
* struct
*==========================================================================*/
typedef struct test_struct_data {
int x;
GBinderHidlString str1;
GBinderHidlString str2;
GBinderHidlVec vec; /* vec<TestData> */
} TestStruct;
static
void
test_struct(
void)
{
static const GBinderWriterType test_data_t = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(TestData), NULL
};
static const GBinderWriterField test_data_pointer_f[] = {
GBINDER_WRITER_FIELD_POINTER(TestDataPointer,ptr, &test_data_t),
GBINDER_WRITER_FIELD_END()
};
static const GBinderWriterField test_struct_f[] = {
GBINDER_WRITER_FIELD_HIDL_STRING(TestStruct,str1),
GBINDER_WRITER_FIELD_HIDL_STRING(TestStruct,str2),
GBINDER_WRITER_FIELD_HIDL_VEC(TestStruct, vec, &test_data_t),
GBINDER_WRITER_FIELD_END()
};
static const GBinderWriterType test_struct_t = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(TestStruct), test_struct_f
};
static const GBinderWriterType test_data_pointer_t = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(TestDataPointer),
test_data_pointer_f
};
static const GBinderWriterField test_struct_vec_f[] = {
{
"vec", GBINDER_HIDL_VEC_BUFFER_OFFSET, &test_struct_t,
gbinder_writer_field_hidl_vec_write_buf, NULL
},
GBINDER_WRITER_FIELD_END()
};
static const GBinderWriterType test_struct_vec_t = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(GBinderHidlVec), test_struct_vec_f
};
/* Vector with no type information is handled as empty vector */
static const GBinderWriterField test_struct_vec2_f[] = {
{
"vec", GBINDER_HIDL_VEC_BUFFER_OFFSET, NULL,
gbinder_writer_field_hidl_vec_write_buf, NULL
},
GBINDER_WRITER_FIELD_END()
};
static const GBinderWriterType test_struct_vec2_t = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(GBinderHidlVec), test_struct_vec2_f
};
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GBinderWriter writer;
GUtilIntArray* offsets;
TestData test_data;
TestDataPointer test_data_ptr;
TestStruct test_struct;
GBinderHidlVec vec;
test_data.x = 42;
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_struct(&writer, &test_data, &test_data_t, 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);
/* Buffers are aligned at 8 bytes boundary */
g_assert_cmpuint(gbinder_output_data_buffers_size(data), == ,8);
gbinder_local_request_unref(req);
/* Write TestStruct */
memset(&test_struct, 0, sizeof(test_struct));
test_struct.x = 42;
test_struct.str1.data.str = "test";
test_struct.str1.len = strlen(test_struct.str1.data.str);
test_struct.vec.data.ptr = &test_data;
test_struct.vec.count = 1;
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_struct(&writer, &test_struct, &test_struct_t, NULL);
data = gbinder_local_request_data(req);
offsets = gbinder_output_data_offsets(data);
g_assert(offsets);
g_assert_cmpuint(offsets->count, == ,4);
g_assert_cmpuint(offsets->data[0], == ,0);
gbinder_local_request_unref(req);
/* Write TestDataPointer */
test_data_ptr.ptr = &test_data;
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_struct(&writer, &test_data_ptr,
&test_data_pointer_t, NULL);
data = gbinder_local_request_data(req);
offsets = gbinder_output_data_offsets(data);
g_assert(offsets);
g_assert_cmpuint(offsets->count, == ,2);
gbinder_local_request_unref(req);
/* Write vec<TestStruct> */
memset(&vec, 0, sizeof(vec));
vec.data.ptr = &test_struct;
vec.count = 1;
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_struct(&writer, &vec, &test_struct_vec_t, NULL);
data = gbinder_local_request_data(req);
offsets = gbinder_output_data_offsets(data);
g_assert(offsets);
g_assert_cmpuint(offsets->count, == ,5);
g_assert_cmpuint(offsets->data[0], == ,0);
gbinder_local_request_unref(req);
/* Corner cases */
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_struct(&writer, &vec, NULL, NULL);
/* Without the type information, an empty buffer is written */
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);
gbinder_local_request_unref(req);
/* Vector without type information */
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_struct(&writer, &vec, &test_struct_vec2_t, NULL);
data = gbinder_local_request_data(req);
offsets = gbinder_output_data_offsets(data);
g_assert(offsets);
g_assert_cmpuint(offsets->count, == ,2);
g_assert_cmpuint(offsets->data[0], == ,0);
gbinder_local_request_unref(req);
}
/*==========================================================================*
* fd
* fd_invalid
@@ -920,7 +1148,7 @@ void
test_fd2(
int fd)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderOutputData* data;
GUtilIntArray* offsets;
GBinderWriter writer;
@@ -963,7 +1191,7 @@ test_fd_close_error(
void)
{
const GBinderIo* io = &gbinder_io_32;
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderLocalRequest* req = test_local_request_new_with_io(io);
GBinderOutputData* data;
GBinderWriter writer;
int fd = -1;
@@ -984,26 +1212,44 @@ test_fd_close_error(
* local_object
*==========================================================================*/
typedef struct test_local_object_data {
const char* name;
const char* protocol;
const guint objsize;
} TestLocalObjectData;
static const TestLocalObjectData local_object_tests [] = {
{ "default", NULL, BINDER_OBJECT_SIZE_32 },
{ "aidl", "aidl", BINDER_OBJECT_SIZE_32 },
{ "aidl2", "aidl2", BINDER_OBJECT_SIZE_32 },
{ "aidl3", "aidl3", BINDER_OBJECT_SIZE_32 + 4 }
};
static
void
test_local_object(
void)
gconstpointer test_data)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
const TestLocalObjectData* test = test_data;
GBinderLocalRequest* req;
GBinderOutputData* data;
GUtilIntArray* offsets;
GBinderWriter writer;
TestContext context;
test_context_init(&context, test->protocol);
req = test_local_request_new();
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(offsets->count == 1);
g_assert(offsets->data[0] == 0);
g_assert(!gbinder_output_data_buffers_size(data));
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_32);
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, == ,test->objsize);
gbinder_local_request_unref(req);
test_context_deinit(&context);
}
/*==========================================================================*
@@ -1015,11 +1261,13 @@ void
test_remote_object(
void)
{
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_64, NULL);
GBinderLocalRequest* req = test_local_request_new_64();
GBinderOutputData* data;
GUtilIntArray* offsets;
GBinderWriter writer;
TestContext test;
test_context_init(&test, NULL);
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_remote_object(&writer, NULL);
data = gbinder_local_request_data(req);
@@ -1030,6 +1278,7 @@ test_remote_object(
g_assert(!gbinder_output_data_buffers_size(data));
g_assert(data->bytes->len == BINDER_OBJECT_SIZE_64);
gbinder_local_request_unref(req);
test_context_deinit(&test);
}
/*==========================================================================*
@@ -1050,7 +1299,7 @@ test_byte_array(
gint32 null_len = -1;
/* test for NULL byte array with non-zero len */
req = gbinder_local_request_new(&gbinder_io_64, NULL);
req = test_local_request_new_64();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_byte_array(&writer, NULL, 42);
data = gbinder_local_request_data(req);
@@ -1061,7 +1310,7 @@ test_byte_array(
gbinder_local_request_unref(req);
/* test for valid array with zero len */
req = gbinder_local_request_new(&gbinder_io_64, NULL);
req = test_local_request_new_64();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_byte_array(&writer, in_data, 0);
data = gbinder_local_request_data(req);
@@ -1072,7 +1321,7 @@ test_byte_array(
gbinder_local_request_unref(req);
/* test for valid array with correct len */
req = gbinder_local_request_new(&gbinder_io_64, NULL);
req = test_local_request_new_64();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_byte_array(&writer, in_data, in_len);
data = gbinder_local_request_data(req);
@@ -1084,7 +1333,6 @@ test_byte_array(
gbinder_local_request_unref(req);
}
/*==========================================================================*
* fmq descriptor
*==========================================================================*/
@@ -1109,7 +1357,7 @@ test_fmq_descriptor(
GBINDER_FMQ_FLAG_CONFIGURE_EVENT_FLAG, -1, 0);
g_assert(fmq);
req = gbinder_local_request_new(&gbinder_io_64, NULL);
req = test_local_request_new_64();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_fmq_descriptor(&writer, fmq);
data = gbinder_local_request_data(req);
@@ -1137,7 +1385,7 @@ test_bytes_written(
void)
{
const guint32 value = 1234567;
GBinderLocalRequest* req = gbinder_local_request_new(&gbinder_io_32, NULL);
GBinderLocalRequest* req = test_local_request_new();
GBinderWriter writer;
const void* data;
gsize size = 0;
@@ -1226,10 +1474,19 @@ int main(int argc, char* argv[])
g_test_add_func(TEST_("buffer"), test_buffer);
g_test_add_func(TEST_("parent"), test_parent);
g_test_add_func(TEST_("parcelable"), test_parcelable);
g_test_add_func(TEST_("struct"), test_struct);
g_test_add_func(TEST_("fd"), test_fd);
g_test_add_func(TEST_("fd_invalid"), test_fd_invalid);
g_test_add_func(TEST_("fd_close_error"), test_fd_close_error);
g_test_add_func(TEST_("local_object"), test_local_object);
for (i = 0; i < G_N_ELEMENTS(local_object_tests); i++) {
const TestLocalObjectData* test = local_object_tests + i;
char* path = g_strconcat(TEST_("local_object/"), test->name, NULL);
g_test_add_data_func(path, test, test_local_object);
g_free(path);
}
g_test_add_func(TEST_("remote_object"), test_remote_object);
g_test_add_func(TEST_("byte_array"), test_byte_array);
g_test_add_func(TEST_("bytes_written"), test_bytes_written);