Compare commits

...

66 Commits

Author SHA1 Message Date
Slava Monich
5874c88559 Version 1.1.30 2022-12-04 19:51:04 +02:00
Slava Monich
b0c3b6017f Merge pull request #109 from monich/ptr_cookie
Fix return value from binder_ptr_cookie encoder
2022-12-04 19:46:23 +02:00
Slava Monich
4f82e82081 [gbinder] Fix return value from binder_ptr_cookie encoder. JB#42956
It was resulting in broken BC_ACQUIRE_DONE commands being sent to
the driver. That's not nice.
2022-12-04 19:41:24 +02:00
Slava Monich
51eefbf566 Version 1.1.29 2022-11-25 00:03:04 +02:00
Slava Monich
ec76cb3930 Merge pull request #106 from monich/vec
gbinder_writer_append_struct_vec
2022-11-24 23:41:11 +02:00
Slava Monich
9a0d0a7894 [gbinder] Added gbinder_writer_append_struct_vec(). JB#42956
Appends top-level vec<type>. Allocates GBinderHidlVec for that,
but unlike gbinder_writer_append_hidl_vec(), doesn't copy the
contents of the vector.
2022-11-24 19:48:24 +02:00
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
Slava Monich
8419a53f23 Version 1.1.20 2022-06-11 02:50:08 +03:00
Slava Monich
865a29d1dd [unit] Tests should ignore system config 2022-06-11 02:49:02 +03:00
Slava Monich
93fbb5b238 [gbinder] Housekeeping. JB#42254 2022-06-11 02:08:05 +03:00
Slava Monich
1a9408f65c Acknowledge Alessandro's contribution 2022-06-11 02:05:29 +03:00
Slava Monich
14399b112f [gbinder] Make RPC protocol selectable at runtime. JB#42254
Merge pull request #93 from aleasto/master
2022-06-11 02:03:02 +03:00
Alessandro Astone
754fa5bcda Make protocol selectable at runtime 2022-06-10 13:50:01 +02:00
Slava Monich
0b43f88700 Version 1.1.19 2022-02-20 03:29:13 +02:00
Slava Monich
5822a40c39 [unit] Added tests for invalid parcelables. JB#54354 2022-02-20 03:22:09 +02:00
Slava Monich
ca5f3ad0be [gbinder] Better handle invalid parcelables. JB#54354 2022-02-20 03:21:34 +02:00
Slava Monich
3398afd701 [unit] Fixed a memory leak in unit_reader. JB#54354
==642984== HEAP SUMMARY:
==642984==     in use at exit: 1,097,253 bytes in 557 blocks
==642984==   total heap usage: 4,780 allocs, 4,223 frees, 78,991,940 bytes allocated
==642984==
==642984== 1,040,520 (24 direct, 1,040,496 indirect) bytes in 1 blocks are definitely lost in loss record 475 of 475
==642984==    at 0x483B7F3: malloc
==642984==    by 0x4923E98: g_malloc
==642984==    by 0x493C485: g_slice_alloc
==642984==    by 0x493CAAD: g_slice_alloc0
==642984==    by 0x11CA1E: gbinder_buffer_alloc (gbinder_buffer.c:167)
==642984==    by 0x11CAFD: gbinder_buffer_new (gbinder_buffer.c:195)
==642984==    by 0x1192C9: test_parcelable (unit_reader.c:1728)
==642984==    by 0x494658D: ???
==642984==    by 0x4946A79: g_test_run_suite
==642984==    by 0x4946A94: g_test_run
==642984==    by 0x11C719: main (unit_reader.c:2448)
==642984==
2022-02-20 02:40:19 +02:00
Slava Monich
3c828b453a [gbinder] Housekeeping. JB#54354 2022-02-20 02:31:56 +02:00
Slava Monich
9d95a622f4 Acknowledge Eugenio's contribution 2022-02-20 01:54:03 +02:00
Slava Monich
78dd0563e6 Merge pull request #92 from g7/for-upstream/mer-hybris/parcelables
[gbinder] Reader and writer for aidl parcelables. JB#54354
2022-02-20 01:51:04 +02:00
Eugenio Paolantonio (g7)
5fd5b423c1 [gbinder] Added reader for parcelables
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2022-02-19 19:06:12 +01:00
Eugenio Paolantonio (g7)
2acec3f7ce [gbinder] Added writer for parcelables
Parcelables allow to serialize arbitrary objects inside
an AIDL parcel.

The structure is pretty simple, and is as follows:

* (int32) Control integer that signals whether there is content (1),
or not (0)

* (int32) Integer holding the payload size, including itself

* The actual payload

Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2022-02-19 19:06:12 +01:00
Slava Monich
59dee397f0 [gbinder] Fixed gbinder_servicemanager_remove_all_handlers macro. JB#42956 2022-02-11 20:12:52 +02:00
Slava Monich
e196c66264 Version 1.1.18 2022-01-08 15:39:43 +02:00
Slava Monich
8f62f4d65c Merge pull request #89 from monich/nodrop
Disassociate auto-created proxies
2022-01-08 15:28:20 +02:00
Slava Monich
8583a72d11 [gbinder] Disassociate auto-created proxies. JB#56889
They are independent on each other and can be destroyed in any order.
2022-01-07 21:22:32 +02:00
Slava Monich
381446eb4f [gbinder] Expose gbinder_ipc_name as an internal function
To be used by other objects e.g. GBinderProxyObject
2022-01-07 18:26:17 +02:00
Slava Monich
eabf5683f4 [gbinder] Logging improvements
Logging device name is useful for understanding what's going on when
multiple binder devices are involved.
2022-01-07 18:25:25 +02:00
Slava Monich
f4712be3b5 Version 1.1.17 2022-01-07 14:44:53 +02:00
Slava Monich
08f701c96b Merge pull request #88 from monich/late_release
Don't release remote proxy handle too early
2022-01-07 14:38:34 +02:00
Slava Monich
8c5618aaab [gbinder] Don't release remote proxy handle too early. JB#56889
Release it when the local one is finalized.
2022-01-05 05:08:40 +02:00
82 changed files with 2737 additions and 1859 deletions

View File

@@ -7,3 +7,5 @@ Rinigus <rinigus.git@gmail.com>
George Hopkins <george-hopkins@null.net>
Bart Ribbers <bribbers@disroot.org>
Gary Wang <gary.wang@canonical.com>
Eugenio Paolantonio <me@medesimo.eu>
Alessandro Astone <ales.astone@gmail.com>

View File

@@ -16,7 +16,7 @@
VERSION_MAJOR = 1
VERSION_MINOR = 1
VERSION_RELEASE = 16
VERSION_RELEASE = 30
# 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 += \

87
debian/changelog vendored
View File

@@ -1,3 +1,90 @@
libgbinder (1.1.30) unstable; urgency=low
* Fixed BC_ACQUIRE_DONE encoding
-- Slava Monich <slava.monich@jolla.com> Sun, 04 Dec 2022 19:50:10 +0200
libgbinder (1.1.29) unstable; urgency=low
* Added gbinder_writer_append_struct_vec
-- Slava Monich <slava.monich@jolla.com> Fri, 25 Nov 2022 00:01:41 +0200
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
-- Slava Monich <slava.monich@jolla.com> Sat, 11 Jun 2022 02:49:49 +0300
libgbinder (1.1.19) unstable; urgency=low
* Added reader and writer for aidl parcelables
-- Slava Monich <slava.monich@jolla.com> Sun, 20 Feb 2022 03:26:24 +0200
libgbinder (1.1.18) unstable; urgency=low
* Disassociate auto-created proxies to stop them from piling up
-- Slava Monich <slava.monich@jolla.com> Sat, 08 Jan 2022 15:35:56 +0200
libgbinder (1.1.17) unstable; urgency=low
* Don't release remote proxy handle too early (sometimes hever)
-- Slava Monich <slava.monich@jolla.com> Fri, 07 Jan 2022 14:43:51 +0200
libgbinder (1.1.16) unstable; urgency=low
* Make sure stale object pointers don't hang around

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

@@ -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:
*
@@ -142,6 +142,11 @@ gbinder_reader_read_buffer(
GBinderReader* reader)
G_GNUC_WARN_UNUSED_RESULT;
const void*
gbinder_reader_read_parcelable(
GBinderReader* reader,
gsize* size); /* Since 1.1.19 */
const void*
gbinder_reader_read_hidl_struct1(
GBinderReader* reader,

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:
*
@@ -76,7 +76,15 @@ void
GBinderServiceManager*
gbinder_servicemanager_new(
const char* dev);
const char* dev)
G_GNUC_WARN_UNUSED_RESULT;
GBinderServiceManager*
gbinder_servicemanager_new2(
const char* dev,
const char* sm_protocol,
const char* rpc_protocol) /* Since 1.1.20 */
G_GNUC_WARN_UNUSED_RESULT;
GBinderServiceManager*
gbinder_defaultservicemanager_new(
@@ -193,7 +201,7 @@ gbinder_servicemanager_remove_handlers(
gulong* ids,
guint count); /* Since 1.0.25 */
#define gbinder_servicemanager_remove_all_handlers(r,ids) \
#define gbinder_servicemanager_remove_all_handlers(sm,ids) \
gbinder_servicemanager_remove_handlers(sm, ids, G_N_ELEMENTS(ids))
G_END_DECLS

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:
*
@@ -55,6 +55,109 @@ 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_append_struct_vec(
GBinderWriter* writer,
const void* ptr,
guint count,
const GBinderWriterType* type); /* Since 1.1.29 */
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,
@@ -148,6 +251,12 @@ gbinder_writer_append_buffer_object(
const void* buf,
gsize len);
void
gbinder_writer_append_parcelable(
GBinderWriter* writer,
const void* buf,
gsize len); /* Since 1.1.19 */
void
gbinder_writer_append_hidl_vec(
GBinderWriter* writer,

View File

@@ -1,6 +1,6 @@
Name: libgbinder
Version: 1.1.16
Version: 1.1.30
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

@@ -82,6 +82,7 @@ struct gbinder_driver {
void* vm;
gsize vmsize;
char* dev;
const char* name;
const GBinderIo* io;
const GBinderRpcProtocol* protocol;
};
@@ -565,7 +566,8 @@ gbinder_driver_handle_transaction(
tx.flags, &txstatus);
break;
default:
GWARN("Unhandled transaction %s 0x%08x", iface, tx.code);
GWARN("Unhandled transaction %s 0x%08x from %s", iface, tx.code,
self->name);
break;
}
@@ -895,6 +897,9 @@ gbinder_driver_new(
self->vm = vm;
self->vmsize = vmsize;
self->dev = g_strdup(dev);
self->name = self->dev + /* Shorter version for logging */
(g_str_has_prefix(self->dev, "/dev/") ? 5 : 0);
if (gbinder_system_ioctl(fd, BINDER_SET_MAX_THREADS,
&max_threads) < 0) {
GERR("%s failed to set max threads (%u): %s", dev,
@@ -1319,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
@@ -280,7 +289,7 @@ GBINDER_IO_FN(encode_ptr_cookie)(
/* We never send these cookies and don't expect them back */
dest->ptr = (uintptr_t)obj;
dest->cookie = 0;
return sizeof(dest);
return sizeof(*dest);
}
/* Fills binder_transaction_data for BC_TRANSACTION/REPLY */
@@ -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
@@ -207,9 +210,6 @@ typedef struct gbinder_ipc_tx_custom {
GDestroyNotify fn_custom_destroy;
} GBinderIpcTxCustom;
GBINDER_INLINE_FUNC const char* gbinder_ipc_name(GBinderIpc* self)
{ return self->priv->name; }
static
GBinderIpcLooper*
gbinder_ipc_looper_new(
@@ -266,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
*==========================================================================*/
@@ -1298,10 +1307,10 @@ gbinder_ipc_priv_get_local_object(
if (obj) {
gbinder_local_object_ref(obj);
} else {
GWARN("Unknown local object %p", pointer);
GWARN("Unknown local object %p %s", pointer, priv->name);
}
} else {
GWARN("Unknown local object %p", pointer);
GWARN("Unknown local object %p %s", pointer, priv->name);
}
g_mutex_unlock(&priv->local_objects_mutex);
/* Unlock */
@@ -1345,6 +1354,8 @@ gbinder_ipc_priv_get_remote_object(
}
GVERBOSE_("%p handle %u %s", obj, handle, gbinder_ipc_name(self));
g_hash_table_replace(priv->remote_objects, key, obj);
} else {
GWARN("Unknown handle %u %s", handle, priv->name);
}
g_mutex_unlock(&priv->remote_objects_mutex);
/* Unlock */
@@ -1842,20 +1853,25 @@ const GBinderIpcSyncApi gbinder_ipc_sync_main = {
GBinderIpc*
gbinder_ipc_new(
const char* dev)
const char* dev,
const char* protocol_name)
{
GBinderIpc* self = NULL;
const GBinderRpcProtocol* protocol;
char* key;
const GBinderRpcProtocol* protocol = (protocol_name ?
gbinder_rpc_protocol_by_name(protocol_name) : NULL);
if (!dev || !dev[0]) dev = GBINDER_DEFAULT_BINDER;
protocol = gbinder_rpc_protocol_for_device(dev); /* Never returns NULL */
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);
@@ -1863,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) {
@@ -1874,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);
@@ -1888,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;
@@ -1900,10 +1919,17 @@ gbinder_ipc_unref(
GBinderIpc* self)
{
if (G_LIKELY(self)) {
g_object_unref(GBINDER_IPC(self));
g_object_unref(THIS(self));
}
}
const char*
gbinder_ipc_name(
GBinderIpc* self)
{
return G_LIKELY(self) ? self->priv->name : NULL;
}
GBinderObjectRegistry*
gbinder_ipc_object_registry(
GBinderIpc* self)
@@ -2031,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);
@@ -2082,7 +2108,7 @@ void
gbinder_ipc_dispose(
GObject* object)
{
GBinderIpc* self = GBINDER_IPC(object);
GBinderIpc* self = THIS(object);
GVERBOSE_("%s", self->dev);
/* Lock */
@@ -2106,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
@@ -2114,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);
@@ -2128,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
@@ -2165,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

@@ -100,7 +100,8 @@ extern const GBinderIpcSyncApi gbinder_ipc_sync_worker GBINDER_INTERNAL;
GBinderIpc*
gbinder_ipc_new(
const char* dev)
const char* dev,
const char* protocol)
GBINDER_INTERNAL;
GBinderIpc*
@@ -113,6 +114,11 @@ gbinder_ipc_unref(
GBinderIpc* ipc)
GBINDER_INTERNAL;
const char*
gbinder_ipc_name(
GBinderIpc* ipc)
GBINDER_INTERNAL;
void
gbinder_ipc_looper_check(
GBinderIpc* ipc)

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

@@ -60,11 +60,9 @@ struct gbinder_proxy_tx {
};
struct gbinder_proxy_object_priv {
gulong remote_death_id;
gboolean acquired;
gboolean dropped;
GBinderProxyTx* tx;
GMutex mutex; /* Protects the hashtable below */
GHashTable* subproxies;
};
G_DEFINE_TYPE(GBinderProxyObject, gbinder_proxy_object, \
@@ -76,79 +74,12 @@ G_DEFINE_TYPE(GBinderProxyObject, gbinder_proxy_object, \
#define THIS_TYPE GBINDER_TYPE_PROXY_OBJECT
#define PARENT_CLASS gbinder_proxy_object_parent_class
static
void
gbinder_proxy_object_subproxy_gone(
gpointer proxy,
GObject* subproxy)
{
GBinderProxyObject* self = THIS(proxy);
GBinderProxyObjectPriv* priv = self->priv;
/* Lock */
g_mutex_lock(&priv->mutex);
g_hash_table_remove(priv->subproxies, subproxy);
if (g_hash_table_size(priv->subproxies) == 0) {
g_hash_table_unref(priv->subproxies);
priv->subproxies = NULL;
}
g_mutex_unlock(&priv->mutex);
/* Unlock */
}
static
void
gbinder_proxy_object_drop_subproxies(
GBinderProxyObject* self)
{
GBinderProxyObjectPriv* priv = self->priv;
GSList* list = NULL;
/* Lock */
g_mutex_lock(&priv->mutex);
if (priv->subproxies) {
GHashTableIter it;
gpointer value;
g_hash_table_iter_init(&it, priv->subproxies);
while (g_hash_table_iter_next(&it, NULL, &value)) {
list = g_slist_append(list, gbinder_local_object_ref(value));
g_object_weak_unref(G_OBJECT(value),
gbinder_proxy_object_subproxy_gone, self);
}
g_hash_table_destroy(priv->subproxies);
priv->subproxies = NULL;
}
g_mutex_unlock(&priv->mutex);
/* Unlock */
/* Drop (and possibly destroy) the objects outside of the lock */
g_slist_free_full(list, (GDestroyNotify) gbinder_local_object_drop);
}
static
void
gbinder_proxy_remote_death_proc(
GBinderRemoteObject* obj,
void* proxy)
{
GBinderProxyObject* self = THIS(proxy);
GBinderProxyObjectPriv* priv = self->priv;
GDEBUG("Remote object %u died on %s", obj->handle, obj->ipc->dev);
gbinder_remote_object_remove_handler(obj, priv->remote_death_id);
priv->remote_death_id = 0;
/* Drop the implicit reference */
gbinder_local_object_unref(&self->parent);
}
/*==========================================================================*
* Converter
*==========================================================================*/
typedef struct gbinder_proxy_object_converter {
GBinderObjectConverter pub;
GBinderProxyObject* proxy;
GBinderIpc* remote;
GBinderIpc* local;
} GBinderProxyObjectConverter;
@@ -182,8 +113,6 @@ gbinder_proxy_object_converter_handle_to_local(
guint32 handle)
{
GBinderProxyObjectConverter* c = gbinder_proxy_object_converter_cast(pub);
GBinderProxyObject* proxy = c->proxy;
GBinderProxyObjectPriv* priv = proxy->priv;
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(c->remote);
GBinderRemoteObject* remote = gbinder_object_registry_get_remote(reg,
handle, REMOTE_REGISTRY_CAN_CREATE /* but don't acquire */);
@@ -192,32 +121,7 @@ gbinder_proxy_object_converter_handle_to_local(
if (!local && !remote->dead) {
/* GBinderProxyObject will reference GBinderRemoteObject */
GBinderProxyObject* subp = gbinder_proxy_object_new(c->local, remote);
/*
* Auto-created proxies may get spontaneously destroyed and
* not necessarily on the UI thread.
*/
subp->priv->remote_death_id = gbinder_remote_object_add_death_handler
(remote, gbinder_proxy_remote_death_proc, subp);
/*
* Remote keeps an implicit reference to this auto-created
* proxy. The reference gets released when the remote object
* dies, i.e. by gbinder_proxy_remote_death_proc().
*/
gbinder_local_object_ref(local = GBINDER_LOCAL_OBJECT(subp));
/* Lock */
g_mutex_lock(&priv->mutex);
if (!priv->subproxies) {
priv->subproxies = g_hash_table_new(g_direct_hash, g_direct_equal);
}
g_hash_table_insert(priv->subproxies, subp, subp);
g_object_weak_ref(G_OBJECT(subp),
gbinder_proxy_object_subproxy_gone, proxy);
g_mutex_unlock(&priv->mutex);
/* Unlock */
local = &gbinder_proxy_object_new(c->local, remote)->parent;
}
/* Release the reference returned by gbinder_object_registry_get_remote */
@@ -241,7 +145,6 @@ gbinder_proxy_object_converter_init(
GBinderIpc* dest = proxy->parent.ipc;
memset(convert, 0, sizeof(*convert));
convert->proxy = proxy;
convert->remote = remote;
convert->local = local;
pub->f = &gbinder_converter_fn;
@@ -346,7 +249,7 @@ gbinder_proxy_object_handle_transaction(
GBinderProxyObjectPriv* priv = self->priv;
GBinderRemoteObject* remote = self->remote;
if (!priv->dropped && !gbinder_remote_object_is_dead(remote)) {
if (!priv->dropped && !remote->dead) {
GBinderLocalRequest* fwd;
GBinderProxyTx* tx = g_slice_new0(GBinderProxyTx);
GBinderProxyObjectConverter convert;
@@ -374,6 +277,7 @@ gbinder_proxy_object_handle_transaction(
gbinder_local_request_unref(fwd);
*status = GBINDER_STATUS_OK;
} else {
GVERBOSE_("dropped: %d dead:%d", priv->dropped, remote->dead);
*status = (-EBADMSG);
}
return NULL;
@@ -397,31 +301,16 @@ gbinder_proxy_object_acquire(
{
GBinderProxyObject* self = THIS(object);
GBinderProxyObjectPriv* priv = self->priv;
GBinderRemoteObject* remote = self->remote;
if (priv->remote_death_id && !object->strong_refs) {
GBinderRemoteObject* remote = self->remote;
/* First strong ref, acquire the attached remote object */
if (!remote->dead && !priv->dropped && !priv->acquired) {
/* Not acquired yet */
priv->acquired = TRUE;
gbinder_driver_acquire(remote->ipc->driver, remote->handle);
}
GBINDER_LOCAL_OBJECT_CLASS(PARENT_CLASS)->acquire(object);
}
static
void
gbinder_proxy_object_release(
GBinderLocalObject* object)
{
GBinderProxyObject* self = THIS(object);
GBinderProxyObjectPriv* priv = self->priv;
if (priv->remote_death_id && object->strong_refs == 1) {
/* Last strong ref, release the attached remote object */
gbinder_remote_object_commit_suicide(self->remote);
}
GBINDER_LOCAL_OBJECT_CLASS(PARENT_CLASS)->release(object);
}
static
void
gbinder_proxy_object_drop(
@@ -431,7 +320,6 @@ gbinder_proxy_object_drop(
GBinderProxyObjectPriv* priv = self->priv;
priv->dropped = TRUE;
gbinder_proxy_object_drop_subproxies(self);
GBINDER_LOCAL_OBJECT_CLASS(PARENT_CLASS)->drop(object);
}
@@ -457,6 +345,8 @@ gbinder_proxy_object_new(
if (object) {
GBinderProxyObject* self = THIS(object);
GDEBUG("Proxy %p %s => %u %s created", self, gbinder_ipc_name(src),
remote->handle, gbinder_ipc_name(remote->ipc));
self->remote = gbinder_remote_object_ref(remote);
return self;
}
@@ -475,11 +365,25 @@ gbinder_proxy_object_finalize(
{
GBinderProxyObject* self = THIS(object);
GBinderProxyObjectPriv* priv = self->priv;
GBinderLocalObject* local = &self->parent;
GBinderRemoteObject* remote = self->remote;
gbinder_proxy_object_drop_subproxies(self);
gbinder_remote_object_remove_handler(self->remote, priv->remote_death_id);
gbinder_remote_object_unref(self->remote);
g_mutex_clear(&priv->mutex);
/*
* gbinder_local_object_finalize() will also try to do the same thing
* i.e. invalidate self but proxy objects need to do it before releasing
* the handle, to leave no room for race conditions. That's not very good
* because it grabs ipc-wide mutex but shouldn'd have much of an impact
* on the performance because finalizing a proxy is not supposed to be a
* frequent operation.
*/
gbinder_ipc_invalidate_local_object(local->ipc, local);
if (priv->acquired) {
gbinder_driver_release(remote->ipc->driver, remote->handle);
}
GDEBUG("Proxy %p %s => %u %s gone", self,
gbinder_ipc_name(self->parent.ipc), remote->handle,
gbinder_ipc_name(remote->ipc));
gbinder_remote_object_unref(remote);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}
@@ -492,7 +396,6 @@ gbinder_proxy_object_init(
THIS_TYPE, GBinderProxyObjectPriv);
self->priv = priv;
g_mutex_init(&priv->mutex);
}
static
@@ -507,7 +410,6 @@ gbinder_proxy_object_class_init(
klass->can_handle_transaction = gbinder_proxy_object_can_handle_transaction;
klass->handle_transaction = gbinder_proxy_object_handle_transaction;
klass->acquire = gbinder_proxy_object_acquire;
klass->release = gbinder_proxy_object_release;
klass->drop = gbinder_proxy_object_drop;
}

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:
*
@@ -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;
@@ -420,6 +421,40 @@ gbinder_reader_skip_buffer(
return gbinder_reader_read_buffer_object(reader, NULL);
}
/*
* This is supposed to be used to read aidl parcelables, and is not
* guaranteed to work on any other kind of parcelable.
*/
const void*
gbinder_reader_read_parcelable(
GBinderReader* reader,
gsize* size) /* Since 1.1.19 */
{
guint32 non_null, payload_size = 0;
if (gbinder_reader_read_uint32(reader, &non_null) && non_null &&
gbinder_reader_read_uint32(reader, &payload_size) &&
payload_size >= sizeof(payload_size)) {
GBinderReaderPriv* p = gbinder_reader_cast(reader);
payload_size -= sizeof(payload_size);
if (p->ptr + payload_size <= p->end) {
const void* out = p->ptr;
/* Success */
p->ptr += payload_size;
if (size) {
*size = payload_size;
}
return out;
}
}
if (size) {
*size = 0;
}
return NULL;
}
/* Helper for gbinder_reader_read_hidl_struct() macro */
const void*
gbinder_reader_read_hidl_struct1(

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
};
/*==========================================================================*
@@ -379,6 +390,13 @@ gbinder_rpc_protocol_for_device(
return gbinder_rpc_protocol_default;
}
const GBinderRpcProtocol*
gbinder_rpc_protocol_by_name(
const char* protocol_name)
{
return gbinder_rpc_protocol_find(protocol_name);
}
/*
* Local Variables:
* mode: C

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,8 +47,24 @@ 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*
gbinder_rpc_protocol_by_name(
const char* protocol_name)
GBINDER_INTERNAL;
/* Returns one of the above based on the device name */
const GBinderRpcProtocol*
gbinder_rpc_protocol_for_device(

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:
*
@@ -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;
@@ -519,7 +520,8 @@ gbinder_servicemanager_exit(
GBinderServiceManager*
gbinder_servicemanager_new_with_type(
GType type,
const char* dev)
const char* dev,
const char* rpc_protocol)
{
GBinderServiceManager* self = NULL;
GBinderServiceManagerClass* klass = gbinder_servicemanager_class_ref(type);
@@ -528,7 +530,7 @@ gbinder_servicemanager_new_with_type(
GBinderIpc* ipc;
if (!dev) dev = klass->default_device;
ipc = gbinder_ipc_new(dev);
ipc = gbinder_ipc_new(dev, rpc_protocol);
if (ipc) {
/* Create a (possibly) dead service manager object */
GBinderRemoteObject* object = gbinder_ipc_get_service_manager(ipc);
@@ -620,25 +622,36 @@ GBinderServiceManager*
gbinder_servicemanager_new(
const char* dev)
{
if (dev) {
const GBinderServiceManagerType* type = NULL;
return gbinder_servicemanager_new2(dev, NULL, NULL);
}
GBinderServiceManager*
gbinder_servicemanager_new2(
const char* dev,
const char* sm_protocol,
const char* rpc_protocol) /* Since 1.1.20 */
{
if (!dev) {
return NULL;
} else if (!sm_protocol) {
const GBinderServiceManagerType* type;
/* One-time initialization */
if (!gbinder_servicemanager_map) {
const GBinderServiceManagerType* t;
/* One-time initialization */
gbinder_servicemanager_map = gbinder_servicemanager_load_config();
/* "Default" is a special value stored in a special variable */
t = g_hash_table_lookup(gbinder_servicemanager_map, CONF_DEFAULT);
if (t) {
type = g_hash_table_lookup(gbinder_servicemanager_map,
CONF_DEFAULT);
if (type) {
g_hash_table_remove(gbinder_servicemanager_map, CONF_DEFAULT);
gbinder_servicemanager_default = t;
gbinder_servicemanager_default = type;
} else {
gbinder_servicemanager_default = SERVICEMANAGER_TYPE_DEFAULT;
}
}
/* If no protocol is specified, pick one up based on the device name */
type = g_hash_table_lookup(gbinder_servicemanager_map, dev);
if (type) {
GDEBUG("Using %s service manager for %s", type->name, dev);
@@ -646,9 +659,21 @@ gbinder_servicemanager_new(
type = gbinder_servicemanager_default;
GDEBUG("Using default service manager %s for %s", type->name, dev);
}
return gbinder_servicemanager_new_with_type(type->get_type(), dev);
return gbinder_servicemanager_new_with_type(type->get_type(), dev,
rpc_protocol);
} else {
/* If protocol name is specified, it must be a valid one */
const GBinderServiceManagerType* type =
gbinder_servicemanager_value_map(sm_protocol);
if (type) {
return gbinder_servicemanager_new_with_type(type->get_type(), dev,
rpc_protocol);
} else {
GWARN("Unknown servicemanager protocol %s", sm_protocol);
return NULL;
}
}
return NULL;
}
GBinderLocalObject*
@@ -1016,7 +1041,7 @@ gbinder_defaultservicemanager_new(
const char* dev)
{
return gbinder_servicemanager_new_with_type
(gbinder_servicemanager_aidl_get_type(), dev);
(gbinder_servicemanager_aidl_get_type(), dev, NULL);
}
GBinderServiceManager*
@@ -1024,7 +1049,7 @@ gbinder_hwservicemanager_new(
const char* dev)
{
return gbinder_servicemanager_new_with_type
(gbinder_servicemanager_hidl_get_type(), dev);
(gbinder_servicemanager_hidl_get_type(), dev, 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

@@ -90,7 +90,8 @@ GType gbinder_servicemanager_get_type(void) GBINDER_INTERNAL;
GBinderServiceManager*
gbinder_servicemanager_new_with_type(
GType type,
const char* dev)
const char* dev,
const char* rpc_protocol)
GBINDER_INTERNAL;
void
@@ -111,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

@@ -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:
*
@@ -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,135 @@ 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);
}
}
/*
* Appends top-level vec<type>. Allocates GBinderHidlVec for that, but
* unlike gbinder_writer_append_hidl_vec(), doesn't copy the contents
* of the vector.
*/
void
gbinder_writer_append_struct_vec(
GBinderWriter* writer,
const void* ptr,
guint count,
const GBinderWriterType* type) /* Since 1.1.29 */
{
GBinderHidlVec* vec = gbinder_writer_new0(writer, GBinderHidlVec);
GBinderWriterField vec_f[2];
GBinderWriterType vec_t;
memset(vec_f, 0, sizeof(vec_f));
vec_f->name = "hidl_vec.data.ptr";
vec_f->type = type;
vec_f->write_buf = gbinder_writer_field_hidl_vec_write_buf;
memset(&vec_t, 0, sizeof(vec_t));
vec_t.name = "hidl_vec";
vec_t.size = sizeof(GBinderHidlVec);
vec_t.fields = vec_f;
vec->owns_buffer = TRUE;
vec->data.ptr = ptr;
vec->count = count;
gbinder_writer_append_struct(writer, vec, &vec_t, NULL);
}
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,
@@ -754,6 +899,51 @@ gbinder_writer_data_append_buffer_object(
return index;
}
/*
* This is supposed to be used to write aidl parcelables, and is not
* guaranteed to work on any other kind of parcelable.
*/
void
gbinder_writer_append_parcelable(
GBinderWriter* self,
const void* buf,
gsize len) /* Since 1.1.19 */
{
GBinderWriterData* data = gbinder_writer_data(self);
if (G_LIKELY(data)) {
gbinder_writer_data_append_parcelable(data, buf, len);
}
}
/*
* This is compatible with aidl parcelables, and is not guaranteed to work
* with any other kind of parcelable.
*/
void
gbinder_writer_data_append_parcelable(
GBinderWriterData* data,
const void* ptr,
gsize size)
{
if (ptr) {
/* Non-null */
gbinder_writer_data_append_int32(data, 1);
/*
* Write the parcelable size, taking in account the size of this
* integer as well.
*/
gbinder_writer_data_append_int32(data, size + sizeof(gint32));
/* Append the parcelable data */
g_byte_array_append(data->bytes, ptr, size);
} else {
/* Null */
gbinder_writer_data_append_int32(data, 0);
}
}
void
gbinder_writer_append_hidl_string(
GBinderWriter* self,
@@ -967,7 +1157,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;
@@ -130,6 +131,13 @@ gbinder_writer_data_append_buffer_object(
const GBinderParent* parent)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_parcelable(
GBinderWriterData* data,
const void* ptr,
gsize size)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_hidl_vec(
GBinderWriterData* data,

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

@@ -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:
*
@@ -55,6 +55,7 @@ static GHashTable* test_fd_map = NULL;
static GHashTable* test_node_map = NULL;
static GPrivate test_looper = G_PRIVATE_INIT(NULL);
static GPrivate test_tx_state = G_PRIVATE_INIT(NULL);
static guint32 last_auto_handle = 0;
G_LOCK_DEFINE_STATIC(test_binder);
static GMainLoop* test_binder_exit_loop = NULL;
@@ -68,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
@@ -125,6 +121,7 @@ typedef struct test_binder_node TestBinderNode;
struct test_binder_node {
int fd;
char* path;
const char* name;
TestBinder* binder;
TestBinderNode* other;
TEST_LOOPER looper_enabled;
@@ -146,7 +143,6 @@ typedef struct test_binder {
GHashTable* object_map; /* GBinderLocalObject* => handle */
GHashTable* handle_map; /* handle => GBinderLocalObject* */
TestBinderSubmitThread* submit_thread;
guint32 last_auto_handle;
GMutex mutex;
gboolean passthrough;
TestBinderNode node[2];
@@ -437,13 +433,16 @@ test_binder_register_object_locked(
g_assert(!g_hash_table_contains(binder->object_map, obj));
g_assert(!g_hash_table_contains(binder->handle_map, GINT_TO_POINTER(h)));
if (h == AUTO_HANDLE) {
h = ++(binder->last_auto_handle);
h = ++last_auto_handle;
while (g_hash_table_contains(binder->handle_map, GINT_TO_POINTER(h)) ||
g_hash_table_contains(binder->object_map, GINT_TO_POINTER(h))) {
h = ++(binder->last_auto_handle);
h = ++last_auto_handle;
}
} else if (last_auto_handle < h) {
/* Avoid re-using handles, to make debugging easier */
last_auto_handle = h;
}
GDEBUG("Object %p <=> handle %u", obj, h);
GDEBUG("Object %p <=> handle %u %s", obj, h, binder->node[0].name);
g_hash_table_insert(binder->handle_map, GINT_TO_POINTER(h), obj);
g_hash_table_insert(binder->object_map, obj, GINT_TO_POINTER(h));
g_object_weak_ref(G_OBJECT(obj), test_binder_local_object_gone, binder);
@@ -463,10 +462,10 @@ test_io_passthough_handle_to_object(
gpointer obj = g_hash_table_lookup(binder->handle_map, key);
GDEBUG("Handle %u => object %p %s", (guint) handle, obj,
binder->node[0].path);
binder->node[0].name);
return GPOINTER_TO_SIZE(obj);
}
GDEBUG("Unexpected handle %u %s", (guint) handle, binder->node[0].path);
GDEBUG("Unexpected handle %u %s", (guint) handle, binder->node[0].name);
return 0;
}
@@ -484,13 +483,13 @@ test_io_passthough_object_to_handle(
guint64 handle = GPOINTER_TO_SIZE(value);
GDEBUG("Object %p => handle %u %s", key, (guint) handle,
binder->node[0].path);
binder->node[0].name);
return handle;
} else if (key) {
GDEBUG("Auto-registering object %p %s", key, binder->node[0].path);
GDEBUG("Auto-registering object %p %s", key, binder->node[0].name);
return test_binder_register_object_locked(binder, key, AUTO_HANDLE);
} else {
GDEBUG("Unexpected object %p %s", key, binder->node[0].path);
GDEBUG("Unexpected object %p %s", key, binder->node[0].name);
return 0;
}
}
@@ -565,7 +564,7 @@ test_binder_node_read(
const guint32 cmd = node->next_cmd[0];
const guint total = 4 + _IOC_SIZE(cmd);
/* Alread have one ready */
/* Already have one ready */
if (!(test_binder_cmd_read_flags(cmd) & flags)) {
GDEBUG("Cmd 0x%08x not for %d", cmd, gettid());
*bytes_read = 0;
@@ -667,7 +666,7 @@ test_tx_state_acquire(
while (g_atomic_pointer_get(&node->tx_state) != my_tx_state &&
!g_atomic_pointer_compare_and_exchange(&node->tx_state, NULL,
my_tx_state)) {
GDEBUG("Thread %d is waiting to become a transacton thread",
GDEBUG("Thread %d is waiting to become a transaction thread",
my_tx_state->tid);
test_io_short_wait();
}
@@ -696,7 +695,7 @@ test_tx_state_release(
my_tx_state->depth--;
my_tx_state->stack = g_renew(TEST_TX_STATE, my_tx_state->stack,
my_tx_state->depth);
GDEBUG("Thread %d is still a transacton thread", my_tx_state->tid);
GDEBUG("Thread %d is still a transaction thread", my_tx_state->tid);
}
}
@@ -843,6 +842,8 @@ test_io_passthough_write_64(
buffer->buffer = GPOINTER_TO_SIZE(copy);
g_hash_table_replace(fd->destroy_map, copy, NULL);
}
} else {
GDEBUG("Unexpected object type 0x%08x", *obj_ptr);
}
}
g_hash_table_replace(fd->destroy_map, data_offsets, NULL);
@@ -1594,6 +1595,7 @@ test_binder_fd_new(
binder_fd->node = node;
binder_fd->fd = dup(node->fd);
binder_fd->destroy_map = g_hash_table_new(g_direct_hash, g_direct_equal);
GDEBUG("fd %d => %d", binder_fd->fd, node->fd);
return binder_fd;
}
@@ -1602,11 +1604,12 @@ gbinder_system_open(
const char* path,
int flags)
{
static const char path_prefix[] = "/dev/";
static const char binder_suffix[] = "binder";
static const char binder_private_suffix[] = "binder-private";
static const char private_suffix[] = "-private";
if (path && g_str_has_prefix(path, "/dev/") &&
if (path && g_str_has_prefix(path, path_prefix) &&
(g_str_has_suffix(path, binder_suffix) ||
g_str_has_suffix(path, binder_private_suffix))) {
TestBinderFd* fd;
@@ -1631,7 +1634,7 @@ gbinder_system_open(
node = binder->node + PRIVATE;
node->path = g_strdup(path);
binder->node[PUBLIC].path = g_strndup(path,
strlen(path) - strlen(private_suffix) - 1);
strlen(path) - strlen(private_suffix));
}
if (!test_node_map) {
@@ -1644,6 +1647,7 @@ gbinder_system_open(
this_node->binder = binder;
this_node->fd = fds[i];
this_node->other = binder->node + ((i + 1) % 2);
this_node->name = this_node->path + strlen(path_prefix);
g_hash_table_replace(test_node_map, this_node->path, this_node);
}
binder->object_map = g_hash_table_new
@@ -1651,8 +1655,8 @@ gbinder_system_open(
binder->handle_map = g_hash_table_new
(g_direct_hash, g_direct_equal);
GDEBUG("Created %s (%d) <=> %s (%d) binder",
binder->node[0].path, binder->node[0].fd,
binder->node[1].path, binder->node[1].fd);
binder->node[0].name, binder->node[0].fd,
binder->node[1].name, binder->node[1].fd);
}
fd = test_binder_fd_new(node);
if (!test_fd_map) {

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

@@ -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>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -183,7 +183,7 @@ TestServiceManagerHidl*
test_servicemanager_impl_new(
const char* dev)
{
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
TestServiceManagerHidl* sm = test_servicemanager_hidl_new(ipc);
@@ -357,10 +357,10 @@ test_basic_run(
test.loop = g_main_loop_new(NULL, FALSE);
/* obj (DEST) <=> bridge <=> (SRC) mirror */
src_ipc = gbinder_ipc_new(SRC_DEV);
src_priv_ipc = gbinder_ipc_new(SRC_PRIV_DEV);
dest_ipc = gbinder_ipc_new(DEST_DEV);
dest_priv_ipc = gbinder_ipc_new(DEST_PRIV_DEV);
src_ipc = gbinder_ipc_new(SRC_DEV, NULL);
src_priv_ipc = gbinder_ipc_new(SRC_PRIV_DEV, NULL);
dest_ipc = gbinder_ipc_new(DEST_DEV, NULL);
dest_priv_ipc = gbinder_ipc_new(DEST_PRIV_DEV, NULL);
test.src_impl = test_servicemanager_impl_new(SRC_PRIV_DEV);
dest_impl = test_servicemanager_impl_new(DEST_PRIV_DEV);
src_fd = gbinder_driver_fd(src_ipc->driver);

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:
*
@@ -55,7 +55,7 @@ test_client_new(
guint h,
const char* iface)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteObject* obj = gbinder_object_registry_get_remote(reg, h, TRUE);
GBinderClient* client = gbinder_client_new(obj, iface);
@@ -99,7 +99,7 @@ void
test_basic(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteObject* obj = gbinder_object_registry_get_remote(reg, 0, TRUE);
const char* iface = "foo";
@@ -125,7 +125,7 @@ void
test_interfaces(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteObject* obj = gbinder_object_registry_get_remote(reg, 0, TRUE);
static const GBinderClientIfaceInfo ifaces[] = {
@@ -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

@@ -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:
*
@@ -32,6 +32,7 @@
#include "test_binder.h"
#include "gbinder_config.h"
#include "gbinder_driver.h"
#include "gbinder_handler.h"
#include "gbinder_local_request_p.h"
@@ -140,12 +141,31 @@ test_local_request(
int main(int argc, char* argv[])
{
const char* default_config_dir;
const char* default_config_file;
char* config_dir = g_dir_make_tmp("gbinder-test-driver-XXXXXX", NULL);
char* config_file = g_build_filename(config_dir, "test.conf", NULL);
int result;
/* Point gbinder_config_file to a non-existent file */
default_config_dir = gbinder_config_dir;
default_config_file = gbinder_config_file;
gbinder_config_dir = config_dir;
gbinder_config_file = config_file;
g_test_init(&argc, &argv, NULL);
g_test_add_func(TEST_PREFIX "basic", test_basic);
g_test_add_func(TEST_PREFIX "noop", test_noop);
g_test_add_func(TEST_PREFIX "local_request", test_local_request);
test_init(&test_opt, argc, argv);
return g_test_run();
result = g_test_run();
gbinder_config_dir = default_config_dir;
gbinder_config_file = default_config_file;
remove(config_dir);
g_free(config_dir);
g_free(config_file);
return result;
}
/*

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);
@@ -134,8 +151,8 @@ void
test_basic(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc2 = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderIpc* ipc2 = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderLocalObject* obj;
g_assert(ipc);
@@ -154,14 +171,37 @@ test_basic(
gbinder_local_object_unref(obj);
/* Second gbinder_ipc_new returns the same (default) object */
g_assert(gbinder_ipc_new(NULL) == ipc);
g_assert(gbinder_ipc_new("") == ipc);
g_assert(gbinder_ipc_new(NULL, NULL) == ipc);
g_assert(gbinder_ipc_new("", NULL) == ipc);
gbinder_ipc_unref(ipc);
gbinder_ipc_unref(ipc);
gbinder_ipc_unref(ipc);
/* Invalid path */
g_assert(!gbinder_ipc_new("invalid path"));
g_assert(!gbinder_ipc_new("invalid path", NULL));
gbinder_ipc_exit();
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);
@@ -189,10 +229,9 @@ void
test_async_oneway(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -216,10 +255,9 @@ void
test_sync_oneway(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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);
@@ -238,13 +276,12 @@ void
test_sync_reply_ok_status(
int* status)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
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);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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";
@@ -295,10 +332,9 @@ void
test_sync_reply_error(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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);
@@ -364,14 +400,13 @@ void
test_transact_ok(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
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);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -423,10 +458,9 @@ void
test_transact_dead(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -471,10 +505,9 @@ void
test_transact_failed(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -521,10 +554,9 @@ void
test_transact_status(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -564,7 +596,7 @@ void
test_transact_custom(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id = gbinder_ipc_transact_custom(ipc, NULL,
test_transact_custom_done, NULL, loop);
@@ -596,7 +628,7 @@ void
test_transact_custom2(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id = gbinder_ipc_transact_custom(ipc, NULL, NULL,
test_transact_custom_destroy, loop);
@@ -629,7 +661,7 @@ void
test_transact_custom3(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
/* Reusing test_transact_cancel_done and test_transact_cancel_destroy */
gulong id = gbinder_ipc_transact_custom(ipc, test_transact_custom3_exec,
@@ -679,7 +711,7 @@ void
test_transact_cancel(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gulong id = gbinder_ipc_transact_custom(ipc, test_transact_cancel_exec,
test_transact_cancel_done, test_transact_cancel_destroy, loop);
@@ -725,7 +757,7 @@ void
test_transact_cancel2(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
/* Reusing test_transact_cancel_done and test_transact_cancel_destroy */
gulong id = gbinder_ipc_transact_custom(ipc, test_transact_cancel2_exec,
@@ -775,8 +807,7 @@ void
test_transact_2way_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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 */
@@ -860,7 +891,7 @@ void
test_transact_unhandled_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderDriver* driver = ipc->driver;
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalRequest* req = gbinder_driver_local_request_new_ping(driver);
@@ -921,8 +952,7 @@ void
test_transact_incoming_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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);
@@ -1002,8 +1032,7 @@ void
test_transact_status_reply_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -1119,8 +1148,7 @@ void
test_transact_async_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -1202,8 +1230,7 @@ void
test_transact_async_sync_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
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;
@@ -1266,7 +1293,7 @@ void
test_drop_remote_refs_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, NULL, NULL, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
@@ -1317,9 +1344,8 @@ void
test_cancel_on_exit(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
const GBinderIo* io = gbinder_driver_io(ipc->driver);
GBinderLocalRequest* req = gbinder_local_request_new(io, NULL);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, 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

@@ -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:
*
@@ -33,6 +33,7 @@
#include "test_binder.h"
#include "gbinder_buffer_p.h"
#include "gbinder_config.h"
#include "gbinder_driver.h"
#include "gbinder_ipc.h"
#include "gbinder_local_object_p.h"
@@ -152,7 +153,7 @@ test_basic(
{
const char* const ifaces_foo[] = { "foo", NULL };
const char* const ifaces_bar[] = { "bar", NULL };
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderLocalObject* foo;
GBinderLocalObject* bar;
@@ -201,7 +202,7 @@ test_ping(
int status = INT_MAX;
const char* dev = GBINDER_DEFAULT_HWBINDER;
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteRequest* req = gbinder_remote_request_new(reg, prot, 0, 0);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
@@ -247,7 +248,7 @@ test_interface(
const char* dev = GBINDER_DEFAULT_HWBINDER;
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
const char* const ifaces[] = { "x", NULL };
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteRequest* req = gbinder_remote_request_new(reg, prot, 0, 0);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, ifaces, NULL, NULL);
@@ -296,7 +297,7 @@ test_hidl_ping(
int status = INT_MAX;
const char* dev = GBINDER_DEFAULT_HWBINDER;
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteRequest* req = gbinder_remote_request_new(reg, prot, 0, 0);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
@@ -346,7 +347,7 @@ test_get_descriptor(
int status = INT_MAX;
const char* dev = GBINDER_DEFAULT_HWBINDER;
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteRequest* req = gbinder_remote_request_new(reg, prot, 0, 0);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
@@ -402,7 +403,7 @@ test_descriptor_chain(
const char* dev = GBINDER_DEFAULT_HWBINDER;
const char* const ifaces[] = { "android.hidl.base@1.0::IBase", NULL };
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteRequest* req = gbinder_remote_request_new(reg, prot, 0, 0);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, ifaces, NULL, NULL);
@@ -476,7 +477,7 @@ test_custom_iface(
int count = 0, status = INT_MAX;
const char* dev = GBINDER_DEFAULT_HWBINDER;
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteRequest* req = gbinder_remote_request_new(reg, prot, 0, 0);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, ifaces,
@@ -583,7 +584,7 @@ test_reply_status(
int count = 0, status = 0;
const char* dev = GBINDER_DEFAULT_HWBINDER;
const GBinderRpcProtocol* prot = gbinder_rpc_protocol_for_device(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteRequest* req = gbinder_remote_request_new(reg, prot, 0, 0);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, ifaces,
@@ -624,7 +625,7 @@ void
test_increfs_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, NULL, NULL, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
@@ -675,7 +676,7 @@ void
test_decrefs_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, NULL, NULL, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
@@ -726,7 +727,7 @@ void
test_acquire_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderLocalObject* obj = gbinder_local_object_new
(ipc, NULL, NULL, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
@@ -777,7 +778,7 @@ void
test_release_run(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
int fd = gbinder_driver_fd(ipc->driver);
@@ -815,6 +816,18 @@ test_release(
int main(int argc, char* argv[])
{
const char* default_config_dir;
const char* default_config_file;
char* config_dir = g_dir_make_tmp("gbinder-test-local-object-XXXXXX", NULL);
char* config_file = g_build_filename(config_dir, "test.conf", NULL);
int result;
/* Point gbinder_config_file to a non-existent file */
default_config_dir = gbinder_config_dir;
default_config_file = gbinder_config_file;
gbinder_config_dir = config_dir;
gbinder_config_file = config_file;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
g_type_init();
G_GNUC_END_IGNORE_DEPRECATIONS;
@@ -833,7 +846,14 @@ int main(int argc, char* argv[])
g_test_add_func(TEST_PREFIX "acquire", test_acquire);
g_test_add_func(TEST_PREFIX "release", test_release);
test_init(&test_opt, argc, argv);
return g_test_run();
result = g_test_run();
gbinder_config_dir = default_config_dir;
gbinder_config_file = default_config_file;
remove(config_dir);
g_free(config_dir);
g_free(config_file);
return result;
}
/*

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:
*
@@ -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;
@@ -426,7 +433,7 @@ test_local_object(
GBinderLocalReply* reply;
GBinderOutputData* data;
GUtilIntArray* offsets;
GBinderIpc* ipc = gbinder_ipc_new(NULL);
GBinderIpc* ipc = gbinder_ipc_new(NULL, NULL);
const char* const ifaces[] = { "android.hidl.base@1.0::IBase", NULL };
GBinderLocalObject* obj = gbinder_local_object_new(ipc, ifaces, NULL, NULL);
@@ -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

@@ -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:
*
@@ -184,6 +184,9 @@ test_device(
void)
{
const GBinderRpcProtocol* p;
TestConfig config;
test_config_init(&config, "");
p = gbinder_rpc_protocol_for_device(NULL);
g_assert(p);
@@ -196,6 +199,8 @@ test_device(
p = gbinder_rpc_protocol_for_device(GBINDER_DEFAULT_HWBINDER);
g_assert(p);
g_assert_cmpstr(p->name, == ,"hidl");
test_config_cleanup(&config);
}
/*==========================================================================*
@@ -388,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) 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>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -198,8 +198,8 @@ test_basic_run(
int fd_obj, fd_proxy, n = 0;
test_config_init(&config, NULL);
ipc_proxy = gbinder_ipc_new(DEV);
ipc_obj = gbinder_ipc_new(DEV_PRIV);
ipc_proxy = gbinder_ipc_new(DEV, NULL);
ipc_obj = gbinder_ipc_new(DEV_PRIV, NULL);
fd_proxy = gbinder_driver_fd(ipc_proxy->driver);
fd_obj = gbinder_driver_fd(ipc_obj->driver);
obj = gbinder_local_object_new(ipc_obj, TEST_IFACES, test_basic_cb, &n);
@@ -362,10 +362,10 @@ test_param_run(
int fd_obj, fd_proxy, n = 0;
test_config_init(&config, NULL);
ipc_obj = gbinder_ipc_new(DEV);
ipc_remote_obj = gbinder_ipc_new(DEV_PRIV);
ipc_proxy = gbinder_ipc_new(DEV2);
ipc_remote_proxy = gbinder_ipc_new(DEV2_PRIV);
ipc_obj = gbinder_ipc_new(DEV, NULL);
ipc_remote_obj = gbinder_ipc_new(DEV_PRIV, NULL);
ipc_proxy = gbinder_ipc_new(DEV2, NULL);
ipc_remote_proxy = gbinder_ipc_new(DEV2_PRIV, NULL);
fd_proxy = gbinder_driver_fd(ipc_proxy->driver);
fd_obj = gbinder_driver_fd(ipc_obj->driver);
obj = gbinder_local_object_new(ipc_obj, TEST_IFACES, test_param_cb, &n);
@@ -438,7 +438,7 @@ test_param(
typedef struct test_obj_data {
GMainLoop* loop;
GBinderLocalObject* tmp_proxy;
GBinderLocalObject* obj2;
gboolean obj_call_handled;
gboolean obj_call_finished;
gboolean obj2_call_handled;
@@ -539,9 +539,9 @@ test_obj_cb(
g_assert(gbinder_reader_at_end(&reader));
/* Make sure temporary proxy won't get destroyed too early */
test->tmp_proxy = test_binder_object(gbinder_driver_fd(obj->ipc->driver),
test->obj2 = test_binder_object(gbinder_driver_fd(obj->ipc->driver),
obj2->handle);
g_assert(test->tmp_proxy);
g_assert(test->obj2);
/* Call remote object */
client2 = gbinder_client_new(obj2, TEST_IFACE2);
@@ -599,39 +599,55 @@ test_obj_run(
GBinderRemoteObject* remote_obj;
GBinderRemoteObject* remote_proxy;
GBinderClient* proxy_client;
GBinderIpc* ipc_remote_obj;
GBinderIpc* ipc_obj;
GBinderIpc* ipc_proxy;
GBinderIpc* ipc_remote_proxy;
GBinderLocalRequest* req;
int fd_obj, fd_proxy;
int fd_remote_obj, fd_obj, fd_proxy, fd_remote_proxy;
test_config_init(&config, NULL);
memset(&test, 0, sizeof(test));
test.loop = g_main_loop_new(NULL, FALSE);
ipc_proxy = gbinder_ipc_new(DEV);
ipc_obj = gbinder_ipc_new(DEV_PRIV);
fd_proxy = gbinder_driver_fd(ipc_proxy->driver);
ipc_remote_obj = gbinder_ipc_new(DEV_PRIV, NULL);
ipc_obj = gbinder_ipc_new(DEV, NULL);
ipc_proxy = gbinder_ipc_new(DEV2, NULL);
ipc_remote_proxy = gbinder_ipc_new(DEV2_PRIV, NULL);
fd_remote_obj = gbinder_driver_fd(ipc_remote_obj->driver);
fd_obj = gbinder_driver_fd(ipc_obj->driver);
obj = gbinder_local_object_new(ipc_obj, TEST_IFACES, test_obj_cb, &test);
obj2 = gbinder_local_object_new(ipc_obj, TEST_IFACES2, test_obj2_cb, &test);
remote_obj = gbinder_remote_object_new(ipc_proxy,
fd_proxy = gbinder_driver_fd(ipc_proxy->driver);
fd_remote_proxy = gbinder_driver_fd(ipc_remote_proxy->driver);
obj = gbinder_local_object_new(ipc_remote_obj, TEST_IFACES,
test_obj_cb, &test);
GDEBUG("obj %p", obj);
remote_obj = gbinder_remote_object_new(ipc_obj,
test_binder_register_object(fd_obj, obj, AUTO_HANDLE),
REMOTE_OBJECT_CREATE_ALIVE);
/* remote_proxy(DEV_PRIV) => proxy (DEV) => obj (DEV) => DEV_PRIV */
g_assert(!gbinder_proxy_object_new(NULL, remote_obj));
/* remote_proxy(DEV2_PRIV) => proxy (DEV) => obj(DEV2_PRIV) */
g_assert((proxy = gbinder_proxy_object_new(ipc_proxy, remote_obj)));
remote_proxy = gbinder_remote_object_new(ipc_obj,
GDEBUG("proxy %p", proxy);
remote_proxy = gbinder_remote_object_new(ipc_remote_proxy,
test_binder_register_object(fd_proxy, &proxy->parent, AUTO_HANDLE),
REMOTE_OBJECT_CREATE_ALIVE);
proxy_client = gbinder_client_new(remote_proxy, TEST_IFACE);
test_binder_set_passthrough(fd_remote_obj, TRUE);
test_binder_set_passthrough(fd_obj, TRUE);
test_binder_set_passthrough(fd_proxy, TRUE);
test_binder_set_passthrough(fd_remote_proxy, TRUE);
test_binder_set_looper_enabled(fd_remote_obj, TEST_LOOPER_ENABLE);
test_binder_set_looper_enabled(fd_obj, TEST_LOOPER_ENABLE);
test_binder_set_looper_enabled(fd_proxy, TEST_LOOPER_ENABLE);
test_binder_set_looper_enabled(fd_remote_proxy, TEST_LOOPER_ENABLE);
/* Pass object reference via proxy */
obj2 = gbinder_local_object_new(ipc_remote_proxy, TEST_IFACES2, test_obj2_cb, &test);
GDEBUG("obj2 %p", obj2);
req = gbinder_client_new_request(proxy_client);
gbinder_local_request_append_int32(req, TX_PARAM1);
gbinder_local_request_append_local_object(req, obj2);
@@ -646,19 +662,24 @@ test_obj_run(
g_assert(test.obj_call_finished);
g_assert(test.obj2_call_handled);
g_assert(test.obj2_call_finished);
g_assert(test.tmp_proxy);
gbinder_local_object_unref(test.tmp_proxy);
g_assert(test.obj2);
gbinder_local_object_unref(test.obj2);
test_binder_unregister_objects(fd_remote_obj);
test_binder_unregister_objects(fd_obj);
test_binder_unregister_objects(fd_proxy);
test_binder_unregister_objects(fd_remote_proxy);
gbinder_local_object_drop(obj);
gbinder_local_object_drop(obj2);
gbinder_local_object_drop(&proxy->parent);
gbinder_remote_object_unref(remote_obj);
gbinder_remote_object_unref(remote_proxy);
gbinder_client_unref(proxy_client);
gbinder_ipc_unref(ipc_remote_obj);
gbinder_ipc_unref(ipc_obj);
gbinder_ipc_unref(ipc_proxy);
gbinder_ipc_unref(ipc_remote_proxy);
gbinder_ipc_exit();
test_binder_exit_wait(&test_opt, test.loop);
test_config_deinit(&config);

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,8 @@
#include "gbinder_remote_object_p.h"
#include "gbinder_io.h"
#include <gutil_misc.h>
#include <unistd.h>
#include <fcntl.h>
@@ -65,6 +67,20 @@ typedef struct binder_buffer_object_64 {
#define BUFFER_OBJECT_SIZE_64 (GBINDER_MAX_BUFFER_OBJECT_SIZE)
G_STATIC_ASSERT(sizeof(BinderObject64) == BUFFER_OBJECT_SIZE_64);
static
void
test_init_reader(
GBinderDriver* driver,
GBinderReaderData* data,
GBinderReader* reader,
const void* bytes,
gsize size)
{
data->buffer = gbinder_buffer_new(driver, gutil_memdup(bytes, size),
size, NULL);
gbinder_reader_init(reader, data, 0, size);
}
/*==========================================================================*
* null
*==========================================================================*/
@@ -119,6 +135,7 @@ test_empty(
g_assert(!gbinder_reader_read_object(&reader));
g_assert(!gbinder_reader_read_nullable_object(&reader, NULL));
g_assert(!gbinder_reader_read_buffer(&reader));
g_assert(!gbinder_reader_read_parcelable(&reader, NULL));
g_assert(!gbinder_reader_read_hidl_struct1(&reader, 1));
g_assert(!gbinder_reader_read_hidl_vec(&reader, NULL, NULL));
g_assert(!gbinder_reader_read_hidl_vec(&reader, &count, &elemsize));
@@ -752,7 +769,7 @@ test_hidl_struct(
gconstpointer test_data)
{
const TestHidlStruct* test = test_data;
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(test->in, test->in_size), test->in_size, NULL);
GBinderReaderData data;
@@ -956,7 +973,7 @@ test_hidl_vec(
gconstpointer test_data)
{
const TestHidlVec* test = test_data;
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(test->in, test->in_size), test->in_size, NULL);
GBinderReaderData data;
@@ -1062,7 +1079,7 @@ test_hidl_string_err(
gconstpointer test_data)
{
const TestHidlStringErr* test = test_data;
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(test->in, test->in_size), test->in_size, NULL);
GBinderReaderData data;
@@ -1096,7 +1113,7 @@ test_hidl_string_err_skip(
gconstpointer test_data)
{
const TestHidlStringErr* test = test_data;
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(test->in, test->in_size), test->in_size, NULL);
GBinderReaderData data;
@@ -1141,7 +1158,7 @@ test_fd_ok(
TEST_INT32_BYTES(fd), TEST_INT32_BYTES(0),
TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderReaderData data;
@@ -1181,7 +1198,7 @@ test_fd_shortbuf(
TEST_INT32_BYTES(BINDER_TYPE_FD),
TEST_INT32_BYTES(0x7f | BINDER_FLAG_ACCEPTS_FDS)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderReaderData data;
@@ -1215,7 +1232,7 @@ test_fd_badtype(
TEST_INT32_BYTES(fd), TEST_INT32_BYTES(0),
TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderReaderData data;
@@ -1258,7 +1275,7 @@ test_dupfd_ok(
TEST_INT32_BYTES(fd), TEST_INT32_BYTES(0),
TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderReaderData data;
@@ -1305,7 +1322,7 @@ test_dupfd_badtype(
TEST_INT32_BYTES(fd), TEST_INT32_BYTES(0),
TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderReaderData data;
@@ -1348,7 +1365,7 @@ test_dupfd_badfd(
TEST_INT32_BYTES(fd), TEST_INT32_BYTES(0),
TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderReaderData data;
@@ -1387,7 +1404,7 @@ test_hidl_string(
guint bufcount,
const char* result)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver, g_memdup(input, size),
size, NULL);
GBinderRemoteObject* obj = NULL;
@@ -1658,7 +1675,7 @@ test_buffer(
TEST_INT64_BYTES(0), TEST_INT64_BYTES(0),
TEST_INT64_BYTES(0), TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderRemoteObject* obj = NULL;
@@ -1692,6 +1709,98 @@ test_buffer(
gbinder_ipc_unref(ipc);
}
/*==========================================================================*
* parcelable
*==========================================================================*/
static
void
test_parcelable(
void)
{
const guint8 input_null_header[] = {
TEST_INT32_BYTES(0)
};
const guint8 input_broken_header[] = {
TEST_INT32_BYTES(1),
TEST_INT32_BYTES(1)
};
const guint8 input_non_null_header[] = {
TEST_INT32_BYTES(1),
/* Size must be size of itself + payload */
TEST_INT32_BYTES(sizeof(gint32) * 3)
};
const guint8 input_non_null_payload[] = {
TEST_INT32_BYTES(10),
TEST_INT32_BYTES(20)
};
gpointer in;
gsize in_size, out_size;
const void* out = 0;
GBinderDriver* driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderReader reader;
GBinderReaderData data;
g_assert(driver);
memset(&data, 0, sizeof(data));
/* Missing payload */
test_init_reader(driver, &data, &reader,
TEST_ARRAY_AND_SIZE(input_non_null_header));
out = gbinder_reader_read_parcelable(&reader, &out_size);
g_assert(!out);
g_assert_cmpuint(out_size, == ,0);
gbinder_buffer_free(data.buffer);
/* Broken headers */
test_init_reader(driver, &data, &reader, input_broken_header, 4);
out = gbinder_reader_read_parcelable(&reader, &out_size);
g_assert(!out);
g_assert_cmpuint(out_size, == ,0);
gbinder_buffer_free(data.buffer);
test_init_reader(driver, &data, &reader,
TEST_ARRAY_AND_SIZE(input_broken_header));
out = gbinder_reader_read_parcelable(&reader, &out_size);
g_assert(!out);
g_assert_cmpuint(out_size, == ,0);
gbinder_buffer_free(data.buffer);
/* Null */
test_init_reader(driver, &data, &reader,
TEST_ARRAY_AND_SIZE(input_null_header));
gbinder_reader_init(&reader, &data, 0, sizeof(input_null_header));
out = gbinder_reader_read_parcelable(&reader, &out_size);
g_assert(!out);
g_assert_cmpuint(out_size, == ,0);
g_assert(gbinder_reader_at_end(&reader));
gbinder_buffer_free(data.buffer);
/* Non-null */
in_size = sizeof(input_non_null_header) + sizeof(input_non_null_payload);
in = g_malloc(in_size);
memcpy(in, &input_non_null_header, sizeof(input_non_null_header));
memcpy(in + sizeof(input_non_null_header), &input_non_null_payload,
sizeof(input_non_null_payload));
data.buffer = gbinder_buffer_new(driver, in, in_size, NULL);
gbinder_reader_init(&reader, &data, 0, in_size);
out = gbinder_reader_read_parcelable(&reader, &out_size);
g_assert(memcmp(&input_non_null_payload, out,
sizeof(input_non_null_payload)) == 0);
g_assert_cmpuint(out_size, == ,sizeof(input_non_null_payload));
g_assert(gbinder_reader_at_end(&reader));
/* And verify NULL tolerance for the size parameter */
gbinder_reader_init(&reader, &data, 0, in_size);
out = gbinder_reader_read_parcelable(&reader, NULL);
g_assert(memcmp(&input_non_null_payload, out,
sizeof(input_non_null_payload)) == 0);
gbinder_buffer_free(data.buffer);
gbinder_driver_unref(driver);
}
/*==========================================================================*
* object
*==========================================================================*/
@@ -1706,7 +1815,7 @@ test_object(
TEST_INT32_BYTES(BINDER_TYPE_HANDLE), TEST_INT32_BYTES(0),
TEST_INT64_BYTES(1 /* handle*/), TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderRemoteObject* obj = NULL;
@@ -1764,7 +1873,7 @@ test_object_invalid(
TEST_INT32_BYTES(42 /* invalid type */), TEST_INT32_BYTES(0),
TEST_INT64_BYTES(1 /* handle*/), TEST_INT64_BYTES(0)
};
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver,
g_memdup(input, sizeof(input)), sizeof(input), NULL);
GBinderRemoteObject* obj = NULL;
@@ -1798,7 +1907,7 @@ test_vec(
void)
{
/* Using 64-bit I/O */
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderReaderData data;
GBinderReader reader;
BinderObject64 obj;
@@ -1851,7 +1960,7 @@ test_hidl_string_vec(
gsize size,
const char* const* result)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
GBinderBuffer* buf = gbinder_buffer_new(ipc->driver, g_memdup(input, size),
size, NULL);
GBinderRemoteObject* obj = NULL;
@@ -2373,6 +2482,7 @@ int main(int argc, char* argv[])
g_test_add_func(TEST_("hidl_string/6"), test_hidl_string6);
g_test_add_func(TEST_("hidl_string/7"), test_hidl_string7);
g_test_add_func(TEST_("buffer"), test_buffer);
g_test_add_func(TEST_("parcelable"), test_parcelable);
g_test_add_func(TEST_("object/valid"), test_object);
g_test_add_func(TEST_("object/invalid"), test_object_invalid);
g_test_add_func(TEST_("object/no_reg"), test_object_no_reg);

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:
*
@@ -68,7 +68,7 @@ void
test_basic(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteObject* obj1 = gbinder_object_registry_get_remote(reg,1,TRUE);
GBinderRemoteObject* obj2 = gbinder_object_registry_get_remote(reg,2,TRUE);
@@ -112,7 +112,7 @@ test_dead_run(
{
const guint h = 1;
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderRemoteObject* obj = gbinder_object_registry_get_remote(reg, h, TRUE);

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

@@ -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,8 +31,10 @@
*/
#include "test_common.h"
#include "test_binder.h"
#include "gbinder_buffer_p.h"
#include "gbinder_config.h"
#include "gbinder_driver.h"
#include "gbinder_reader.h"
#include "gbinder_remote_request_p.h"
@@ -58,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
*==========================================================================*/
@@ -369,6 +368,18 @@ test_to_local(
int main(int argc, char* argv[])
{
const char* default_config_dir;
const char* default_config_file;
char* conf_dir = g_dir_make_tmp("gbinder-test-remote-request-XXXXXX", NULL);
char* conf_file = g_build_filename(conf_dir, "test.conf", NULL);
int result;
/* Point gbinder_config_file to a non-existent file */
default_config_dir = gbinder_config_dir;
default_config_file = gbinder_config_file;
gbinder_config_dir = conf_dir;
gbinder_config_file = conf_file;
g_test_init(&argc, &argv, NULL);
g_test_add_func(TEST_PREFIX "null", test_null);
g_test_add_func(TEST_PREFIX "basic", test_basic);
@@ -378,7 +389,14 @@ int main(int argc, char* argv[])
g_test_add_func(TEST_PREFIX "string16", test_string16);
g_test_add_func(TEST_PREFIX "to_local", test_to_local);
test_init(&test_opt, argc, argv);
return g_test_run();
result = g_test_run();
gbinder_config_dir = default_config_dir;
gbinder_config_file = default_config_file;
remove(conf_dir);
g_free(conf_dir);
g_free(conf_file);
return result;
}
/*

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:
*
@@ -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
*==========================================================================*/
@@ -409,7 +417,7 @@ test_null(
void)
{
g_assert(!gbinder_servicemanager_new(NULL));
g_assert(!gbinder_servicemanager_new_with_type(0, NULL));
g_assert(!gbinder_servicemanager_new_with_type(0, NULL, NULL));
g_assert(!gbinder_servicemanager_new_local_object(NULL, NULL, NULL, NULL));
g_assert(!gbinder_servicemanager_ref(NULL));
g_assert(!gbinder_servicemanager_device(NULL));
@@ -442,14 +450,15 @@ test_invalid(
{
int status = 0;
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderServiceManager* sm;
gulong id = 0;
test_setup_ping(ipc);
g_assert(!gbinder_servicemanager_new2(GBINDER_DEFAULT_HWBINDER, "a", NULL));
sm = gbinder_servicemanager_new(dev);
g_assert(!gbinder_servicemanager_new_with_type(GBINDER_TYPE_LOCAL_OBJECT,
NULL));
NULL, NULL));
g_assert(TEST_IS_HWSERVICEMANAGER(sm));
g_assert(!gbinder_servicemanager_list(sm, NULL, NULL));
g_assert(!gbinder_servicemanager_get_service(sm, "foo", NULL, NULL));
@@ -487,7 +496,7 @@ test_basic(
void)
{
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderServiceManager* sm;
GBinderLocalObject* obj;
@@ -518,7 +527,7 @@ test_legacy(
{
const char* otherdev = "/dev/otherbinder";
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderServiceManager* sm;
/* Reset the state */
@@ -539,7 +548,7 @@ test_legacy(
gbinder_ipc_unref(ipc);
/* Legacy default */
ipc = gbinder_ipc_new(otherdev);
ipc = gbinder_ipc_new(otherdev, NULL);
test_setup_ping(ipc);
sm = gbinder_servicemanager_new(otherdev);
g_assert(TEST_IS_DEFSERVICEMANAGER(sm));
@@ -582,7 +591,7 @@ test_config(
gbinder_config_file = file;
/* Unknown device instantiates the default */
ipc = gbinder_ipc_new(strange_name);
ipc = gbinder_ipc_new(strange_name, NULL);
test_setup_ping(ipc);
sm = gbinder_servicemanager_new(strange_name);
g_assert(TEST_IS_HWSERVICEMANAGER(sm));
@@ -590,7 +599,7 @@ test_config(
gbinder_ipc_unref(ipc);
/* This one was redefined */
ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER);
ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
test_setup_ping(ipc);
sm = gbinder_servicemanager_new(GBINDER_DEFAULT_BINDER);
g_assert(TEST_IS_HWSERVICEMANAGER(sm));
@@ -598,7 +607,7 @@ test_config(
gbinder_ipc_unref(ipc);
/* This one was not (since name was invalid) */
ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER);
ipc = gbinder_ipc_new(GBINDER_DEFAULT_HWBINDER, NULL);
test_setup_ping(ipc);
sm = gbinder_servicemanager_new(GBINDER_DEFAULT_HWBINDER);
g_assert(TEST_IS_HWSERVICEMANAGER(sm));
@@ -606,13 +615,21 @@ test_config(
gbinder_ipc_unref(ipc);
/* This one points to legacy manager */
ipc = gbinder_ipc_new(legacy_name);
ipc = gbinder_ipc_new(legacy_name, NULL);
test_setup_ping(ipc);
sm = gbinder_servicemanager_new(legacy_name);
g_assert(TEST_IS_DEFSERVICEMANAGER(sm));
gbinder_servicemanager_unref(sm);
gbinder_ipc_unref(ipc);
/* Overwrite the legacy manager with "hidl" */
ipc = gbinder_ipc_new(legacy_name, "hidl");
test_setup_ping(ipc);
sm = gbinder_servicemanager_new2(legacy_name, "hidl", "hidl");
g_assert(TEST_IS_HWSERVICEMANAGER(sm));
gbinder_servicemanager_unref(sm);
gbinder_ipc_unref(ipc);
/* Clear the state */
gbinder_servicemanager_exit();
gbinder_config_exit();
@@ -634,7 +651,7 @@ test_not_present(
void)
{
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderServiceManager* sm;
@@ -659,7 +676,7 @@ test_wait(
void)
{
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
const glong forever = (test_opt.flags & TEST_FLAG_DEBUG) ?
(TEST_TIMEOUT_SEC * 1000) : -1;
@@ -710,7 +727,7 @@ test_wait_long(
void)
{
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GBinderServiceManager* sm;
gulong id;
@@ -756,7 +773,7 @@ test_wait_async(
void)
{
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServiceManager* sm;
@@ -800,7 +817,7 @@ void
test_death_run()
{
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServiceManager* sm;
@@ -877,7 +894,7 @@ test_reanimate(
void)
{
const char* dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServiceManager* sm;
@@ -932,9 +949,9 @@ test_reuse(
const char* binder_dev = GBINDER_DEFAULT_BINDER;
const char* vndbinder_dev = "/dev/vpnbinder";
const char* hwbinder_dev = GBINDER_DEFAULT_HWBINDER;
GBinderIpc* binder_ipc = gbinder_ipc_new(binder_dev);
GBinderIpc* vndbinder_ipc = gbinder_ipc_new(vndbinder_dev);
GBinderIpc* hwbinder_ipc = gbinder_ipc_new(hwbinder_dev);
GBinderIpc* binder_ipc = gbinder_ipc_new(binder_dev, NULL);
GBinderIpc* vndbinder_ipc = gbinder_ipc_new(vndbinder_dev, NULL);
GBinderIpc* hwbinder_ipc = gbinder_ipc_new(hwbinder_dev, NULL);
GBinderServiceManager* m1;
GBinderServiceManager* m2;
GBinderServiceManager* vnd1;
@@ -987,7 +1004,7 @@ test_notify_type(
GType t,
const char* dev)
{
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderServiceManager* sm;
TestHwServiceManager* test;
const char* name = "foo";
@@ -995,7 +1012,7 @@ test_notify_type(
gulong id1, id2;
test_setup_ping(ipc);
sm = gbinder_servicemanager_new_with_type(t, NULL);
sm = gbinder_servicemanager_new_with_type(t, NULL, NULL);
test = TEST_SERVICEMANAGER2(sm, t);
id1 = gbinder_servicemanager_add_registration_handler(sm, name,
test_registration_func_inc, &count);
@@ -1055,7 +1072,7 @@ test_list(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServiceManager* sm;
TestHwServiceManager* test;
@@ -1104,7 +1121,7 @@ test_get(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServiceManager* sm;
TestHwServiceManager* test;
@@ -1166,7 +1183,7 @@ test_add(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServiceManager* sm;
TestHwServiceManager* test;

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2020-2021 Jolla Ltd.
* Copyright (C) 2020-2021 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:
*
@@ -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
*==========================================================================*/
@@ -182,7 +190,7 @@ servicemanager_aidl_new(
{
ServiceManagerAidl* self = g_object_new(SERVICE_MANAGER_AIDL_TYPE, NULL);
GBinderLocalObject* obj = GBINDER_LOCAL_OBJECT(self);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
self->handle_on_looper_thread = handle_on_looper_thread;
@@ -322,7 +330,7 @@ test_get_run()
{
const char* dev = GBINDER_DEFAULT_BINDER;
const char* other_dev = GBINDER_DEFAULT_BINDER "-private";
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
ServiceManagerAidl* smsvc = servicemanager_aidl_new(other_dev, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
@@ -404,7 +412,7 @@ test_list_run()
{
const char* dev = GBINDER_DEFAULT_BINDER;
const char* other_dev = GBINDER_DEFAULT_BINDER "-private";
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
ServiceManagerAidl* smsvc = servicemanager_aidl_new(other_dev, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
@@ -483,7 +491,7 @@ test_notify_run()
{
const char* dev = GBINDER_DEFAULT_BINDER;
const char* other_dev = GBINDER_DEFAULT_BINDER "-private";
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
ServiceManagerAidl* svc = servicemanager_aidl_new(other_dev, FALSE);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
@@ -540,7 +548,7 @@ test_notify2_run()
{
const char* dev = GBINDER_DEFAULT_BINDER;
const char* other_dev = GBINDER_DEFAULT_BINDER "-private";
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
ServiceManagerAidl* smsvc = servicemanager_aidl_new(other_dev, TRUE);
GBinderLocalObject* obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
const int fd = gbinder_driver_fd(ipc->driver);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2020-2021 Jolla Ltd.
* Copyright (C) 2020-2021 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:
*
@@ -175,7 +175,7 @@ servicemanager_aidl2_new(
{
ServiceManagerAidl2* self = g_object_new(SERVICE_MANAGER_AIDL2_TYPE, NULL);
GBinderLocalObject* obj = GBINDER_LOCAL_OBJECT(self);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
self->handle_on_looper_thread = handle_on_looper_thread;
@@ -305,7 +305,7 @@ test_context_init(
gbinder_config_dir = test->config_subdir; /* Doesn't exist */
gbinder_config_file = test->config_file;
ipc = gbinder_ipc_new(dev);
ipc = gbinder_ipc_new(dev, NULL);
test->fd = gbinder_driver_fd(ipc->driver);
test->object = gbinder_local_object_new(ipc, NULL, NULL, NULL);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2020-2021 Jolla Ltd.
* Copyright (C) 2020-2021 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,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);
@@ -193,7 +184,7 @@ servicemanager_aidl3_new(
{
ServiceManagerAidl3* self = g_object_new(SERVICE_MANAGER_AIDL3_TYPE, NULL);
GBinderLocalObject* obj = GBINDER_LOCAL_OBJECT(self);
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
self->handle_on_looper_thread = handle_on_looper_thread;
@@ -323,7 +314,7 @@ test_context_init(
gbinder_config_dir = test->config_subdir; /* Doesn't exist */
gbinder_config_file = test->config_file;
ipc = gbinder_ipc_new(dev);
ipc = gbinder_ipc_new(dev, NULL);
test->fd = gbinder_driver_fd(ipc->driver);
test->object = gbinder_local_object_new(ipc, NULL, NULL, NULL);

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

@@ -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>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -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
*==========================================================================*/
@@ -122,7 +130,7 @@ TestServiceManagerHidl*
test_servicemanager_impl_new(
const char* dev)
{
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
TestServiceManagerHidl* sm = test_servicemanager_hidl_new(ipc);
@@ -191,7 +199,7 @@ test_get_run()
const char* name = "android.hidl.base@1.0::IBase/test";
test_config_init(&config, NULL);
ipc = gbinder_ipc_new(MAIN_DEV);
ipc = gbinder_ipc_new(MAIN_DEV, NULL);
smsvc = test_servicemanager_impl_new(OTHER_DEV);
obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
fd = gbinder_driver_fd(ipc->driver);
@@ -286,7 +294,7 @@ test_list_run()
test.loop = g_main_loop_new(NULL, FALSE);
test_config_init(&config, NULL);
ipc = gbinder_ipc_new(MAIN_DEV);
ipc = gbinder_ipc_new(MAIN_DEV, NULL);
smsvc = test_servicemanager_impl_new(OTHER_DEV);
obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
fd = gbinder_driver_fd(ipc->driver);
@@ -414,7 +422,7 @@ test_notify_run()
test.loop = g_main_loop_new(NULL, FALSE);
test_config_init(&config, NULL);
ipc = gbinder_ipc_new(MAIN_DEV);
ipc = gbinder_ipc_new(MAIN_DEV, NULL);
test.smsvc = test_servicemanager_impl_new(OTHER_DEV);
obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
fd = gbinder_driver_fd(ipc->driver);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2019-2021 Jolla Ltd.
* Copyright (C) 2019-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2019-2022 Jolla Ltd.
* Copyright (C) 2019-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -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()
{
@@ -256,7 +262,7 @@ test_null(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderServiceManager* sm;
test_setup_ping(ipc);
@@ -283,7 +289,7 @@ test_basic(
const char* obj_name = "test";
const char* dev = GBINDER_DEFAULT_BINDER;
const char* const ifaces[] = { "interface", NULL };
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj;
GBinderServiceManager* sm;
@@ -321,7 +327,7 @@ test_present(
const char* obj_name = "test";
const char* const ifaces[] = { "interface", NULL };
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj;
@@ -382,7 +388,7 @@ test_not_present(
const char* obj_name = "test";
const char* const ifaces[] = { "interface", NULL };
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj;
@@ -427,7 +433,7 @@ test_retry(
const char* obj_name = "test";
const char* const ifaces[] = { "interface", NULL };
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj;
@@ -470,7 +476,7 @@ test_cancel(
const char* obj_name = "test";
const char* const ifaces[] = { "interface", NULL };
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
const int fd = gbinder_driver_fd(ipc->driver);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderLocalObject* obj;

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:
*
@@ -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()
{
@@ -239,7 +245,7 @@ test_basic(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GBinderServicePoll* weakptr = NULL;
GBinderServiceManager* manager;
GBinderServicePoll* poll;
@@ -315,7 +321,7 @@ test_notify1(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServicePoll* weakptr = NULL;
GBinderServiceManager* manager;
@@ -389,7 +395,7 @@ test_notify2(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServicePoll* weakptr = NULL;
GBinderServiceManager* manager;
@@ -448,7 +454,7 @@ test_already_there(
void)
{
const char* dev = GBINDER_DEFAULT_BINDER;
GBinderIpc* ipc = gbinder_ipc_new(dev);
GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderServicePoll* weakptr = NULL;
GBinderServiceManager* manager;

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
@@ -100,6 +174,7 @@ test_null(
gbinder_writer_append_buffer_object(&writer, NULL, 0);
gbinder_writer_append_buffer_object_with_parent(NULL, NULL, 0, NULL);
gbinder_writer_append_buffer_object_with_parent(&writer, NULL, 0, NULL);
gbinder_writer_append_parcelable(NULL, NULL, 0);
gbinder_writer_append_local_object(NULL, NULL);
gbinder_writer_append_local_object(&writer, NULL);
gbinder_writer_append_remote_object(NULL, NULL);
@@ -146,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";
@@ -180,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;
@@ -207,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;
@@ -232,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;
@@ -269,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;
@@ -293,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;
@@ -317,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;
@@ -345,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;
@@ -372,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;
@@ -397,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;
@@ -411,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);
@@ -465,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;
@@ -534,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;
@@ -587,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;
@@ -652,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;
@@ -692,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;
@@ -762,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;
@@ -786,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;
@@ -822,6 +893,10 @@ test_buffer(
* parent
*==========================================================================*/
typedef struct test_data {
guint32 x;
} TestData;
typedef struct test_data_pointer {
TestData* ptr;
} TestDataPointer;
@@ -831,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;
@@ -862,6 +937,219 @@ test_parent(
gbinder_local_request_unref(req);
}
/*==========================================================================*
* parcelable
*==========================================================================*/
static
void
test_parcelable(
void)
{
const guint8 encoded_non_null[] = {
TEST_INT32_BYTES(1),
TEST_INT32_BYTES(sizeof(TestData) + sizeof(gint32)),
TEST_INT32_BYTES(10)
};
const gint32 test_null_value = 0;
GBinderLocalRequest* req;
GBinderOutputData* data;
GBinderWriter writer;
TestData test_data;
test_data.x = 10;
/* Non-null */
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_parcelable(&writer, &test_data, sizeof(test_data));
data = gbinder_local_request_data(req);
g_assert(!gbinder_output_data_buffers_size(data));
g_assert(data->bytes->len == sizeof(encoded_non_null));
g_assert(!memcmp(data->bytes->data, &encoded_non_null, data->bytes->len));
gbinder_local_request_unref(req);
/* Null */
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_parcelable(&writer, NULL, 0);
data = gbinder_local_request_data(req);
g_assert(!gbinder_output_data_buffers_size(data));
g_assert(data->bytes->len == sizeof(test_null_value));
g_assert(!memcmp(data->bytes->data, &test_null_value, data->bytes->len));
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);
/* Write vec<TestStruct> in a different way */
req = test_local_request_new();
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_struct_vec(&writer, &test_struct, 1, &test_struct_t);
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
@@ -872,7 +1160,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;
@@ -915,7 +1203,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;
@@ -936,26 +1224,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);
}
/*==========================================================================*
@@ -967,11 +1273,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);
@@ -982,6 +1290,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);
}
/*==========================================================================*
@@ -1002,7 +1311,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);
@@ -1013,7 +1322,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);
@@ -1024,7 +1333,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);
@@ -1036,7 +1345,6 @@ test_byte_array(
gbinder_local_request_unref(req);
}
/*==========================================================================*
* fmq descriptor
*==========================================================================*/
@@ -1061,7 +1369,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);
@@ -1089,7 +1397,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;
@@ -1177,10 +1485,20 @@ 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);