Compare commits
	
		
			30 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					29718f921f | ||
| 
						 | 
					99b2dd85c1 | ||
| 
						 | 
					cf5417d5db | ||
| 
						 | 
					03f214eb24 | ||
| 
						 | 
					6508a73dcd | ||
| 
						 | 
					1100d8ede1 | ||
| 
						 | 
					f89469b1a5 | ||
| 
						 | 
					fcf2ef0ea4 | ||
| 
						 | 
					f9202cab37 | ||
| 
						 | 
					49729d95c9 | ||
| 
						 | 
					11765cd80d | ||
| 
						 | 
					4820b2971f | ||
| 
						 | 
					0623fb85db | ||
| 
						 | 
					e655d8992a | ||
| 
						 | 
					44e57ea98d | ||
| 
						 | 
					e3f705c4cc | ||
| 
						 | 
					6f0e8a693d | ||
| 
						 | 
					c7fab6373b | ||
| 
						 | 
					9aded94555 | ||
| 
						 | 
					b5bab2431e | ||
| 
						 | 
					509faccba0 | ||
| 
						 | 
					a89dcd2702 | ||
| 
						 | 
					62b9b30865 | ||
| 
						 | 
					4a913590d9 | ||
| 
						 | 
					1ee872aaf2 | ||
| 
						 | 
					00e9d8ac6f | ||
| 
						 | 
					b032e151a2 | ||
| 
						 | 
					b8edc9221a | ||
| 
						 | 
					05634757d7 | ||
| 
						 | 
					03ef78c9fd | 
							
								
								
									
										6
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								LICENSE
									
									
									
									
									
								
							@@ -1,7 +1,5 @@
 | 
			
		||||
Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
Copyright (C) 2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 | 
			
		||||
You may use this file under the terms of BSD license as follows:
 | 
			
		||||
Copyright (C) 2018-2024 Jolla Ltd.
 | 
			
		||||
Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								Makefile
									
									
									
									
									
								
							@@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
VERSION_MAJOR = 1
 | 
			
		||||
VERSION_MINOR = 1
 | 
			
		||||
VERSION_RELEASE = 32
 | 
			
		||||
VERSION_RELEASE = 38
 | 
			
		||||
 | 
			
		||||
# Version for pkg-config
 | 
			
		||||
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
 | 
			
		||||
@@ -50,10 +50,10 @@ RELEASE_DEPS = libglibutil_release
 | 
			
		||||
.PHONY: libglibutil_debug libglibutil_release
 | 
			
		||||
 | 
			
		||||
libglibutil_debug:
 | 
			
		||||
	make -C $(LIBGLIBUTIL_PATH) debug
 | 
			
		||||
	$(MAKE) -C $(LIBGLIBUTIL_PATH) debug
 | 
			
		||||
 | 
			
		||||
libglibutil_release:
 | 
			
		||||
	make -C $(LIBGLIBUTIL_PATH) release
 | 
			
		||||
	$(MAKE) -C $(LIBGLIBUTIL_PATH) release
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@@ -126,16 +126,19 @@ COVERAGE_BUILD_DIR = $(BUILD_DIR)/coverage
 | 
			
		||||
# Tools and flags
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
PKG_CONFIG ?= pkg-config
 | 
			
		||||
CC ?= $(CROSS_COMPILE)gcc
 | 
			
		||||
STRIP ?= strip
 | 
			
		||||
LD = $(CC)
 | 
			
		||||
WARNINGS = -Wall -Wstrict-aliasing -Wunused-result
 | 
			
		||||
DEFINES += -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32 \
 | 
			
		||||
  -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_MAX_ALLOWED
 | 
			
		||||
INCLUDES += -I$(INCLUDE_DIR)
 | 
			
		||||
BASE_FLAGS = -fPIC
 | 
			
		||||
FULL_CFLAGS = $(BASE_FLAGS) $(CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) \
 | 
			
		||||
  -MMD -MP $(shell pkg-config --cflags $(PKGS))
 | 
			
		||||
  -MMD -MP $(shell $(PKG_CONFIG) --cflags $(PKGS))
 | 
			
		||||
FULL_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS) -shared -Wl,-soname,$(LIB_SONAME) \
 | 
			
		||||
  $(shell pkg-config --libs $(PKGS)) -lpthread
 | 
			
		||||
  $(shell $(PKG_CONFIG) --libs $(PKGS)) -lpthread
 | 
			
		||||
DEBUG_FLAGS = -g
 | 
			
		||||
RELEASE_FLAGS =
 | 
			
		||||
COVERAGE_FLAGS = -g
 | 
			
		||||
@@ -235,8 +238,8 @@ print_release_path:
 | 
			
		||||
	@echo $(RELEASE_BUILD_DIR)
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	make -C test clean
 | 
			
		||||
	make -C unit clean
 | 
			
		||||
	$(MAKE) -C test clean
 | 
			
		||||
	$(MAKE) -C unit clean
 | 
			
		||||
	rm -fr test/coverage/results test/coverage/*.gcov
 | 
			
		||||
	rm -f *~ $(SRC_DIR)/*~ $(INCLUDE_DIR)/*~
 | 
			
		||||
	rm -fr $(BUILD_DIR) RPMS installroot
 | 
			
		||||
@@ -246,7 +249,7 @@ clean:
 | 
			
		||||
	rm -f debian/libgbinder.install debian/libgbinder-dev.install
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	make -C unit test
 | 
			
		||||
	$(MAKE) -C unit test
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR):
 | 
			
		||||
	mkdir -p $@
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,42 @@
 | 
			
		||||
libgbinder (1.1.38) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fixed byte array padding
 | 
			
		||||
 | 
			
		||||
 -- Slava Monich <slava@monich.com>  Sat, 02 Mar 2024 02:11:50 +0200
 | 
			
		||||
 | 
			
		||||
libgbinder (1.1.37) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fixed gbinder_driver_reply_data return value
 | 
			
		||||
 | 
			
		||||
 -- Slava Monich <slava@monich.com>  Mon, 26 Feb 2024 16:22:29 +0200
 | 
			
		||||
 | 
			
		||||
libgbinder (1.1.36) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Support pkg-config cross-compilation
 | 
			
		||||
  * Fixed handling of UTF-16 surrogate pairs
 | 
			
		||||
 | 
			
		||||
 -- Slava Monich <slava@monich.com>  Sat, 10 Feb 2024 05:04:13 +0200
 | 
			
		||||
 | 
			
		||||
libgbinder (1.1.35) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Make unit tests independent on system config
 | 
			
		||||
  * Use MAKE var instead of explicitly calling make
 | 
			
		||||
 | 
			
		||||
 -- Slava Monich <slava@monich.com>  Thu, 23 Nov 2023 01:42:56 +0200
 | 
			
		||||
 | 
			
		||||
libgbinder (1.1.34) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fixed binder-call help message
 | 
			
		||||
  * Require glib 2.32
 | 
			
		||||
 | 
			
		||||
 -- Slava Monich <slava@monich.com>  Sun, 30 Apr 2023 06:04:38 +0300
 | 
			
		||||
 | 
			
		||||
libgbinder (1.1.33) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fixed GBinderWriterType for byte and int32
 | 
			
		||||
 | 
			
		||||
 -- Slava Monich <slava@monich.com>  Sun, 26 Feb 2023 03:13:49 +0200
 | 
			
		||||
 | 
			
		||||
libgbinder (1.1.32) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Improved reliability of unit tests
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							@@ -1,7 +1,5 @@
 | 
			
		||||
Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
Copyright (C) 2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 | 
			
		||||
You may use this file under the terms of BSD license as follows:
 | 
			
		||||
Copyright (C) 2018-2024 Jolla Ltd.
 | 
			
		||||
Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,16 @@
 | 
			
		||||
Name: libgbinder
 | 
			
		||||
 | 
			
		||||
Version: 1.1.32
 | 
			
		||||
Version: 1.1.38
 | 
			
		||||
Release: 0
 | 
			
		||||
Summary: Binder client library
 | 
			
		||||
License: BSD
 | 
			
		||||
URL: https://github.com/mer-hybris/libgbinder
 | 
			
		||||
Source: %{name}-%{version}.tar.bz2
 | 
			
		||||
 | 
			
		||||
%define glib_version 2.32
 | 
			
		||||
%define libglibutil_version 1.0.52
 | 
			
		||||
 | 
			
		||||
BuildRequires: pkgconfig(glib-2.0)
 | 
			
		||||
BuildRequires: pkgconfig(glib-2.0) >= %{glib_version}
 | 
			
		||||
BuildRequires: pkgconfig(libglibutil) >= %{libglibutil_version}
 | 
			
		||||
BuildRequires: pkgconfig
 | 
			
		||||
BuildRequires: bison
 | 
			
		||||
@@ -19,6 +20,7 @@ BuildRequires: flex
 | 
			
		||||
BuildRequires: pkgconfig(rpm)
 | 
			
		||||
%define license_support %(pkg-config --exists 'rpm >= 4.11'; echo $?)
 | 
			
		||||
 | 
			
		||||
Requires: glib2 >= %{glib_version}
 | 
			
		||||
Requires: libglibutil >= %{libglibutil_version}
 | 
			
		||||
Requires(post): /sbin/ldconfig
 | 
			
		||||
Requires(postun): /sbin/ldconfig
 | 
			
		||||
@@ -29,6 +31,7 @@ C interfaces for Android binder
 | 
			
		||||
%package devel
 | 
			
		||||
Summary: Development library for %{name}
 | 
			
		||||
Requires: %{name} = %{version}
 | 
			
		||||
Requires: pkgconfig(glib-2.0) >= %{glib_version}
 | 
			
		||||
 | 
			
		||||
%description devel
 | 
			
		||||
This package contains the development library for %{name}.
 | 
			
		||||
 
 | 
			
		||||
@@ -506,7 +506,7 @@ gbinder_driver_reply_data(
 | 
			
		||||
    write.ptr = (uintptr_t)buf;
 | 
			
		||||
    write.size = len;
 | 
			
		||||
    write.consumed = 0;
 | 
			
		||||
    status = gbinder_driver_write(self, &write) >= 0;
 | 
			
		||||
    status = gbinder_driver_write(self, &write);
 | 
			
		||||
 | 
			
		||||
    g_free(offsets_buf);
 | 
			
		||||
    return status >= 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -30,7 +30,6 @@
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
 | 
			
		||||
#define _GNU_SOURCE  /* pthread_*_np */
 | 
			
		||||
 | 
			
		||||
#include "gbinder_ipc.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -30,8 +30,6 @@
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
 | 
			
		||||
 | 
			
		||||
#include "gbinder_driver.h"
 | 
			
		||||
#include "gbinder_ipc.h"
 | 
			
		||||
#include "gbinder_buffer_p.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -30,8 +30,6 @@
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
 | 
			
		||||
 | 
			
		||||
#include "gbinder_proxy_object.h"
 | 
			
		||||
#include "gbinder_local_object_p.h"
 | 
			
		||||
#include "gbinder_local_request.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2024 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -770,7 +770,8 @@ gbinder_reader_read_byte_array(
 | 
			
		||||
            *len = (gsize)*ptr;
 | 
			
		||||
            p->ptr += sizeof(*ptr);
 | 
			
		||||
            data = p->ptr;
 | 
			
		||||
            p->ptr += *len;
 | 
			
		||||
            /* Android aligns byte array reads and writes to 4 bytes */
 | 
			
		||||
            p->ptr += G_ALIGN4(*len);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return data;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -30,8 +30,6 @@
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
 | 
			
		||||
 | 
			
		||||
#include "gbinder_driver.h"
 | 
			
		||||
#include "gbinder_ipc.h"
 | 
			
		||||
#include "gbinder_remote_object_p.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -30,8 +30,6 @@
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
 | 
			
		||||
 | 
			
		||||
#include "gbinder_servicemanager_p.h"
 | 
			
		||||
#include "gbinder_client_p.h"
 | 
			
		||||
#include "gbinder_config.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -30,8 +30,6 @@
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
 | 
			
		||||
 | 
			
		||||
#include "gbinder_servicemanager_aidl.h"
 | 
			
		||||
#include "gbinder_servicepoll.h"
 | 
			
		||||
#include "gbinder_eventloop_p.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2024 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
@@ -52,8 +52,8 @@ 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 };
 | 
			
		||||
const GBinderWriterType gbinder_writer_type_byte = { "byte", 1, NULL };
 | 
			
		||||
const GBinderWriterType gbinder_writer_type_int32 = { "int32", 4, NULL };
 | 
			
		||||
static const GBinderWriterField gbinder_writer_type_hidl_string_f[] = {
 | 
			
		||||
    {
 | 
			
		||||
        "hidl_string.data.str", 0, NULL,
 | 
			
		||||
@@ -523,37 +523,37 @@ gbinder_writer_data_append_string16_len(
 | 
			
		||||
        gsize padded_len = G_ALIGN4((len+1)*2);
 | 
			
		||||
        guint32* len_ptr;
 | 
			
		||||
        gunichar2* utf16_ptr;
 | 
			
		||||
        gunichar2* utf16 = NULL;
 | 
			
		||||
 | 
			
		||||
        /* Create utf-16 string to make sure of its size */
 | 
			
		||||
        if (len > 0) {
 | 
			
		||||
            glong utf16_len = 0;
 | 
			
		||||
 | 
			
		||||
            utf16 = g_utf8_to_utf16(utf8, num_bytes, NULL, &utf16_len, NULL);
 | 
			
		||||
            if (utf16) {
 | 
			
		||||
                len = utf16_len;
 | 
			
		||||
                padded_len = G_ALIGN4((len+1)*2);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Preallocate space */
 | 
			
		||||
        g_byte_array_set_size(buf, old_size + padded_len + 4);
 | 
			
		||||
        len_ptr = (guint32*)(buf->data + old_size);
 | 
			
		||||
        utf16_ptr = (gunichar2*)(len_ptr + 1);
 | 
			
		||||
 | 
			
		||||
        /* TODO: this could be optimized for ASCII strings, i.e. if
 | 
			
		||||
         * len equals num_bytes */
 | 
			
		||||
        if (len > 0) {
 | 
			
		||||
            glong utf16_len = 0;
 | 
			
		||||
            gunichar2* utf16 = g_utf8_to_utf16(utf8, num_bytes, NULL,
 | 
			
		||||
                &utf16_len, NULL);
 | 
			
		||||
 | 
			
		||||
            if (utf16) {
 | 
			
		||||
                len = utf16_len;
 | 
			
		||||
                padded_len = G_ALIGN4((len+1)*2);
 | 
			
		||||
                memcpy(utf16_ptr, utf16, (len+1)*2);
 | 
			
		||||
                g_free(utf16);
 | 
			
		||||
            }
 | 
			
		||||
        /* Copy string */
 | 
			
		||||
        if (utf16) {
 | 
			
		||||
            memcpy(utf16_ptr, utf16, len*2);
 | 
			
		||||
            g_free(utf16);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Actual length */
 | 
			
		||||
        *len_ptr = len;
 | 
			
		||||
 | 
			
		||||
        /* Zero padding */
 | 
			
		||||
        if (padded_len - (len + 1)*2) {
 | 
			
		||||
            memset(utf16_ptr + (len + 1), 0, padded_len - (len + 1)*2);
 | 
			
		||||
        if (padded_len > len*2) {
 | 
			
		||||
            memset(utf16_ptr + len, 0, padded_len - len*2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Correct the packet size if necessaary */
 | 
			
		||||
        g_byte_array_set_size(buf, old_size + padded_len + 4);
 | 
			
		||||
    } else if (utf8) {
 | 
			
		||||
        /* Empty string */
 | 
			
		||||
        gbinder_writer_data_append_string16_empty(data);
 | 
			
		||||
@@ -1203,19 +1203,29 @@ gbinder_writer_append_byte_array(
 | 
			
		||||
    GASSERT(len >= 0);
 | 
			
		||||
    if (G_LIKELY(data)) {
 | 
			
		||||
        GByteArray* buf = data->bytes;
 | 
			
		||||
        void* ptr;
 | 
			
		||||
        gsize padded_len;
 | 
			
		||||
        guint8* ptr;
 | 
			
		||||
 | 
			
		||||
        if (!byte_array) {
 | 
			
		||||
            len = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_byte_array_set_size(buf, buf->len + sizeof(len) + len);
 | 
			
		||||
        ptr = buf->data + (buf->len - sizeof(len) - len);
 | 
			
		||||
        /*
 | 
			
		||||
         * Android aligns byte array reads and writes to 4 bytes and
 | 
			
		||||
         * pads with 0xFF.
 | 
			
		||||
         */
 | 
			
		||||
        padded_len = G_ALIGN4(len);
 | 
			
		||||
        g_byte_array_set_size(buf, buf->len + sizeof(len) + padded_len);
 | 
			
		||||
        ptr = buf->data + (buf->len - sizeof(len) - padded_len);
 | 
			
		||||
 | 
			
		||||
        if (len > 0) {
 | 
			
		||||
            *((gint32*)ptr) = len;
 | 
			
		||||
            ptr += sizeof(len);
 | 
			
		||||
            memcpy(ptr, byte_array, len);
 | 
			
		||||
            /* FF padding */
 | 
			
		||||
            if (padded_len > len) {
 | 
			
		||||
                memset(ptr + len, 0xff, padded_len - len);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            *((gint32*)ptr) = -1;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -45,14 +45,17 @@ RELEASE_BUILD_DIR = $(BUILD_DIR)/release
 | 
			
		||||
# Tools and flags
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
PKG_CONFIG ?= pkg-config
 | 
			
		||||
CC ?= $(CROSS_COMPILE)gcc
 | 
			
		||||
LD = $(CC)
 | 
			
		||||
WARNINGS = -Wall
 | 
			
		||||
DEFINES += -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32 \
 | 
			
		||||
  -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_MAX_ALLOWED
 | 
			
		||||
INCLUDES = -I$(LIB_DIR)/include -I$(GEN_DIR) -I$(SRC_DIR)
 | 
			
		||||
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
 | 
			
		||||
  $(shell $(PKG_CONFIG) --cflags $(PKGS))
 | 
			
		||||
LDFLAGS += -pie $(shell $(PKG_CONFIG) --libs $(PKGS))
 | 
			
		||||
QUIET_MAKE = $(MAKE) --no-print-directory
 | 
			
		||||
DEBUG_FLAGS = -g
 | 
			
		||||
RELEASE_FLAGS =
 | 
			
		||||
 | 
			
		||||
@@ -118,7 +121,7 @@ clean:
 | 
			
		||||
	rm -fr $(BUILD_DIR)
 | 
			
		||||
 | 
			
		||||
cleaner: clean
 | 
			
		||||
	@make -C $(LIB_DIR) clean
 | 
			
		||||
	@$(MAKE) -C $(LIB_DIR) clean
 | 
			
		||||
 | 
			
		||||
$(DEBUG_BUILD_DIR):
 | 
			
		||||
	mkdir -p $@
 | 
			
		||||
 
 | 
			
		||||
@@ -742,7 +742,7 @@ app_init(
 | 
			
		||||
    "\t[0-9]*.[0-9]* for a 32-bit float\n"
 | 
			
		||||
    "\t[0-9]*.[0-9]*L for a 64-bit double\n"
 | 
			
		||||
    "\t\"[.*]\" for an 8-bit aidl string\n"
 | 
			
		||||
    "\t\"[.*]\"L for an utf16 aidl string\n"
 | 
			
		||||
    "\t\"[.*]\"u for an utf16 aidl string\n"
 | 
			
		||||
    "\t\"[.*]\"h for an 8-bit hidl string\n"
 | 
			
		||||
    "\t{ VALUE1 VALUE2 ... VALUEN } for a struct containing VALUE1, VALUE2, etc., where\n"
 | 
			
		||||
    "\t all of these values can be any of the possible values described here.\n"
 | 
			
		||||
 
 | 
			
		||||
@@ -43,14 +43,17 @@ RELEASE_BUILD_DIR = $(BUILD_DIR)/release
 | 
			
		||||
# Tools and flags
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
PKG_CONFIG ?= pkg-config
 | 
			
		||||
CC ?= $(CROSS_COMPILE)gcc
 | 
			
		||||
LD = $(CC)
 | 
			
		||||
WARNINGS = -Wall
 | 
			
		||||
DEFINES += -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32 \
 | 
			
		||||
  -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_MAX_ALLOWED
 | 
			
		||||
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
 | 
			
		||||
  $(shell $(PKG_CONFIG) --cflags $(PKGS))
 | 
			
		||||
LDFLAGS += -pie $(shell $(PKG_CONFIG) --libs $(PKGS))
 | 
			
		||||
QUIET_MAKE = $(MAKE) --no-print-directory
 | 
			
		||||
DEBUG_FLAGS = -g
 | 
			
		||||
RELEASE_FLAGS =
 | 
			
		||||
 | 
			
		||||
@@ -108,7 +111,7 @@ clean:
 | 
			
		||||
	rm -fr $(BUILD_DIR)
 | 
			
		||||
 | 
			
		||||
cleaner: clean
 | 
			
		||||
	@make -C $(LIB_DIR) clean
 | 
			
		||||
	@$(MAKE) -C $(LIB_DIR) clean
 | 
			
		||||
 | 
			
		||||
$(DEBUG_BUILD_DIR):
 | 
			
		||||
	mkdir -p $@
 | 
			
		||||
 
 | 
			
		||||
@@ -37,10 +37,10 @@ RELEASE_DEPS = libglibutil_release
 | 
			
		||||
.PHONY: libglibutil_debug libglibutil_release
 | 
			
		||||
 | 
			
		||||
libglibutil_debug:
 | 
			
		||||
	make -C $(LIBGLIBUTIL_PATH) debug
 | 
			
		||||
	$(MAKE) -C $(LIBGLIBUTIL_PATH) debug
 | 
			
		||||
 | 
			
		||||
libglibutil_release:
 | 
			
		||||
	make -C $(LIBGLIBUTIL_PATH) release
 | 
			
		||||
	$(MAKE) -C $(LIBGLIBUTIL_PATH) release
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@@ -66,18 +66,21 @@ COVERAGE_BUILD_DIR = $(BUILD_DIR)/coverage
 | 
			
		||||
# Tools and flags
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
PKG_CONFIG ?= pkg-config
 | 
			
		||||
CC ?= $(CROSS_COMPILE)gcc
 | 
			
		||||
LD = $(CC)
 | 
			
		||||
WARNINGS += -Wall -Wno-deprecated-declarations
 | 
			
		||||
DEFINES += -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32 \
 | 
			
		||||
  -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_MAX_ALLOWED
 | 
			
		||||
INCLUDES += -I$(COMMON_DIR) -I$(LIB_DIR)/src -I$(LIB_DIR)/include
 | 
			
		||||
BASE_FLAGS = -fPIC
 | 
			
		||||
BASE_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS)
 | 
			
		||||
BASE_CFLAGS = $(BASE_FLAGS) $(CFLAGS)
 | 
			
		||||
FULL_CFLAGS = $(BASE_CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
 | 
			
		||||
  $(shell pkg-config --cflags $(PKGS))
 | 
			
		||||
  $(shell $(PKG_CONFIG) --cflags $(PKGS))
 | 
			
		||||
FULL_LDFLAGS = $(BASE_LDFLAGS)
 | 
			
		||||
LIBS = $(shell pkg-config --libs $(PKGS)) -lpthread
 | 
			
		||||
QUIET_MAKE = make --no-print-directory
 | 
			
		||||
LIBS = $(shell $(PKG_CONFIG) --libs $(PKGS)) -lpthread
 | 
			
		||||
QUIET_MAKE = $(MAKE) --no-print-directory
 | 
			
		||||
DEBUG_FLAGS = -g
 | 
			
		||||
RELEASE_FLAGS =
 | 
			
		||||
COVERAGE_FLAGS = -g
 | 
			
		||||
@@ -156,7 +159,7 @@ unitclean:
 | 
			
		||||
clean: unitclean
 | 
			
		||||
 | 
			
		||||
cleaner: unitclean
 | 
			
		||||
	@make -C $(LIB_DIR) clean
 | 
			
		||||
	@$(MAKE) -C $(LIB_DIR) clean
 | 
			
		||||
 | 
			
		||||
test_banner:
 | 
			
		||||
	@echo "===========" $(EXE) "=========== "
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -40,6 +40,13 @@ typedef struct test_opt {
 | 
			
		||||
    int flags;
 | 
			
		||||
} TestOpt;
 | 
			
		||||
 | 
			
		||||
typedef struct test_config {
 | 
			
		||||
    const char* default_config_dir;
 | 
			
		||||
    const char* default_config_file;
 | 
			
		||||
    char* config_dir;
 | 
			
		||||
    char* non_existent_config_file;
 | 
			
		||||
} TestConfig;
 | 
			
		||||
 | 
			
		||||
/* Should be invoked after g_test_init */
 | 
			
		||||
void
 | 
			
		||||
test_init(
 | 
			
		||||
@@ -47,6 +54,16 @@ test_init(
 | 
			
		||||
    int argc,
 | 
			
		||||
    char* argv[]);
 | 
			
		||||
 | 
			
		||||
/* Creates empty test config dir */
 | 
			
		||||
void
 | 
			
		||||
test_config_init(
 | 
			
		||||
    TestConfig* config,
 | 
			
		||||
    const char* template);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
test_config_cleanup(
 | 
			
		||||
    TestConfig* config);
 | 
			
		||||
 | 
			
		||||
/* Run loop with a timeout */
 | 
			
		||||
void
 | 
			
		||||
test_run(
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2020 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -32,6 +32,9 @@
 | 
			
		||||
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
 | 
			
		||||
#include "gbinder_config.h"
 | 
			
		||||
#include "gbinder_rpc_protocol.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_log.h>
 | 
			
		||||
 | 
			
		||||
typedef struct test_quit_later_data{
 | 
			
		||||
@@ -191,6 +194,49 @@ test_init(
 | 
			
		||||
    gutil_log_timestamp = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Unit tests shouldn't depend on the system gbinder config. This is
 | 
			
		||||
 * achieved by pointing gbinder_config_file to a non-existent file
 | 
			
		||||
 * and gbinder_config_dir to an empty directory (where individual
 | 
			
		||||
 * tests may create their own config files when they need it)
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
test_config_init(
 | 
			
		||||
    TestConfig* config,
 | 
			
		||||
    const char* template)
 | 
			
		||||
{
 | 
			
		||||
    config->config_dir = g_dir_make_tmp("gbinder-test-driver-XXXXXX", NULL);
 | 
			
		||||
    g_assert(config->config_dir);
 | 
			
		||||
    config->non_existent_config_file = g_build_filename(config->config_dir,
 | 
			
		||||
        "non-existent.conf", NULL);
 | 
			
		||||
 | 
			
		||||
    /* Point gbinder_config_file to a non-existent file */
 | 
			
		||||
    config->default_config_dir = gbinder_config_dir;
 | 
			
		||||
    config->default_config_file = gbinder_config_file;
 | 
			
		||||
    gbinder_config_dir = config->config_dir;
 | 
			
		||||
    gbinder_config_file = config->non_existent_config_file;
 | 
			
		||||
 | 
			
		||||
    /* Reset the state */
 | 
			
		||||
    gbinder_rpc_protocol_exit();
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
test_config_cleanup(
 | 
			
		||||
    TestConfig* config)
 | 
			
		||||
{
 | 
			
		||||
    gbinder_config_dir = config->default_config_dir;
 | 
			
		||||
    gbinder_config_file = config->default_config_file;
 | 
			
		||||
    remove(config->config_dir);
 | 
			
		||||
    g_free(config->config_dir);
 | 
			
		||||
    g_free(config->non_existent_config_file);
 | 
			
		||||
    memset(config, 0, sizeof(*config));
 | 
			
		||||
 | 
			
		||||
    /* Reset the state */
 | 
			
		||||
    gbinder_rpc_protocol_exit();
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021-2023 Slava Monich <slava@monich.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:
 | 
			
		||||
 *
 | 
			
		||||
@@ -67,46 +67,10 @@ static const char DEFAULT_CONFIG_DATA[] =
 | 
			
		||||
    "[ServiceManager]\n"
 | 
			
		||||
    "Default = hidl\n";
 | 
			
		||||
 | 
			
		||||
typedef struct test_config {
 | 
			
		||||
    char* dir;
 | 
			
		||||
    char* file;
 | 
			
		||||
} TestConfig;
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Common
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_init(
 | 
			
		||||
    TestConfig* config,
 | 
			
		||||
    char* config_data)
 | 
			
		||||
{
 | 
			
		||||
    config->dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
 | 
			
		||||
    config->file = g_build_filename(config->dir, "test.conf", NULL);
 | 
			
		||||
    g_assert(g_file_set_contents(config->file, config_data ? config_data :
 | 
			
		||||
        DEFAULT_CONFIG_DATA, -1, NULL));
 | 
			
		||||
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    gbinder_config_dir = config->dir;
 | 
			
		||||
    gbinder_config_file = config->file;
 | 
			
		||||
    GDEBUG("Wrote config to %s", config->file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_deinit(
 | 
			
		||||
    TestConfig* config)
 | 
			
		||||
{
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
 | 
			
		||||
    remove(config->file);
 | 
			
		||||
    g_free(config->file);
 | 
			
		||||
 | 
			
		||||
    remove(config->dir);
 | 
			
		||||
    g_free(config->dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
TestServiceManagerHidl*
 | 
			
		||||
test_servicemanager_impl_new(
 | 
			
		||||
@@ -261,7 +225,6 @@ test_basic_run(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestBasic test;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestServiceManagerHidl* dest_impl;
 | 
			
		||||
    GBinderServiceManager* src;
 | 
			
		||||
    GBinderServiceManager* dest;
 | 
			
		||||
@@ -277,7 +240,6 @@ test_basic_run(
 | 
			
		||||
    int src_fd, dest_fd, n = 0;
 | 
			
		||||
    gulong id;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, NULL);
 | 
			
		||||
    memset(&test, 0, sizeof(test));
 | 
			
		||||
    test.loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
@@ -365,7 +327,6 @@ test_basic_run(
 | 
			
		||||
    gbinder_ipc_unref(dest_ipc);
 | 
			
		||||
 | 
			
		||||
    test_binder_exit_wait(&test_opt, test.loop);
 | 
			
		||||
    test_config_deinit(&config);
 | 
			
		||||
    g_main_loop_unref(test.loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -385,14 +346,31 @@ test_basic(
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    TestConfig test_config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
    int result;
 | 
			
		||||
 | 
			
		||||
    G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
 | 
			
		||||
    g_type_init();
 | 
			
		||||
    G_GNUC_END_IGNORE_DEPRECATIONS;
 | 
			
		||||
    g_test_init(&argc, &argv, NULL);
 | 
			
		||||
    g_test_add_func(TEST_("null"), test_null);
 | 
			
		||||
    g_test_add_func(TEST_("basic"), test_basic);
 | 
			
		||||
 | 
			
		||||
    test_init(&test_opt, argc, argv);
 | 
			
		||||
    return g_test_run();
 | 
			
		||||
    test_config_init(&test_config, TMP_DIR_TEMPLATE);
 | 
			
		||||
 | 
			
		||||
    config_file = g_build_filename(test_config.config_dir, "test.conf", NULL);
 | 
			
		||||
    g_assert(g_file_set_contents(config_file, DEFAULT_CONFIG_DATA, -1, NULL));
 | 
			
		||||
    GDEBUG("Config file %s", config_file);
 | 
			
		||||
    gbinder_config_file = config_file;
 | 
			
		||||
 | 
			
		||||
    result = g_test_run();
 | 
			
		||||
 | 
			
		||||
    remove(config_file);
 | 
			
		||||
    g_free(config_file);
 | 
			
		||||
    test_config_cleanup(&test_config);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -32,7 +32,6 @@
 | 
			
		||||
 | 
			
		||||
#include "test_binder.h"
 | 
			
		||||
 | 
			
		||||
#include "gbinder_config.h"
 | 
			
		||||
#include "gbinder_driver.h"
 | 
			
		||||
#include "gbinder_handler.h"
 | 
			
		||||
#include "gbinder_local_request_p.h"
 | 
			
		||||
@@ -42,6 +41,7 @@
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-driver-XXXXXX";
 | 
			
		||||
 | 
			
		||||
#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
 | 
			
		||||
#define BINDER_RPC_FLAGS (STRICT_MODE_PENALTY_GATHER)
 | 
			
		||||
@@ -144,30 +144,17 @@ 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);
 | 
			
		||||
    TestConfig test_config;
 | 
			
		||||
    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);
 | 
			
		||||
    test_config_init(&test_config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    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);
 | 
			
		||||
    test_config_cleanup(&test_config);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -33,7 +33,6 @@
 | 
			
		||||
#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"
 | 
			
		||||
@@ -51,6 +50,7 @@
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-local-object-XXXXXX";
 | 
			
		||||
 | 
			
		||||
/* android.hidl.base@1.0::IBase */
 | 
			
		||||
#define TEST_BASE_INTERFACE_BYTES \
 | 
			
		||||
@@ -820,18 +820,9 @@ 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);
 | 
			
		||||
    TestConfig test_config;
 | 
			
		||||
    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;
 | 
			
		||||
@@ -850,13 +841,9 @@ 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);
 | 
			
		||||
    test_config_init(&test_config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    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);
 | 
			
		||||
    test_config_cleanup(&test_config);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -43,6 +43,8 @@
 | 
			
		||||
#include "gbinder_rpc_protocol.h"
 | 
			
		||||
#include "gbinder_writer.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_log.h>
 | 
			
		||||
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-protocol-XXXXXX";
 | 
			
		||||
 | 
			
		||||
@@ -121,57 +123,49 @@ static const TestHeaderData test_header_tests[] = {
 | 
			
		||||
      test_header_hidl, 1 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct test_config {
 | 
			
		||||
    char* dir;
 | 
			
		||||
    char* file;
 | 
			
		||||
} TestConfig;
 | 
			
		||||
typedef struct test_context {
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
} TestContext;
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_init(
 | 
			
		||||
    TestConfig* test,
 | 
			
		||||
test_context_init(
 | 
			
		||||
    TestContext* test,
 | 
			
		||||
    const char* config)
 | 
			
		||||
{
 | 
			
		||||
    test->dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
 | 
			
		||||
    test->file = g_build_filename(test->dir, "test.conf", NULL);
 | 
			
		||||
 | 
			
		||||
    /* Reset the state */
 | 
			
		||||
    gbinder_rpc_protocol_exit();
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    memset(test, 0, sizeof(*test));
 | 
			
		||||
    test_config_init(&test->config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test->config_file = g_build_filename(test->config.config_dir,
 | 
			
		||||
        "test.conf", NULL);
 | 
			
		||||
 | 
			
		||||
    /* Write the config */
 | 
			
		||||
    g_assert(g_file_set_contents(test->file, config, -1, NULL));
 | 
			
		||||
    gbinder_config_file = test->file;
 | 
			
		||||
    g_assert(g_file_set_contents(test->config_file, config, -1, NULL));
 | 
			
		||||
    GDEBUG("Config file %s", test->config_file);
 | 
			
		||||
    gbinder_config_file = test->config_file;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_init2(
 | 
			
		||||
    TestConfig* test,
 | 
			
		||||
test_context_init2(
 | 
			
		||||
    TestContext* test,
 | 
			
		||||
    const char* dev,
 | 
			
		||||
    const char* prot)
 | 
			
		||||
{
 | 
			
		||||
    char* config = g_strconcat("[Protocol]\n", dev, " = ", prot, "\n", NULL);
 | 
			
		||||
 | 
			
		||||
    test_config_init(test, config);
 | 
			
		||||
    test_context_init(test, config);
 | 
			
		||||
    g_free(config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_cleanup(
 | 
			
		||||
    TestConfig* test)
 | 
			
		||||
test_context_cleanup(
 | 
			
		||||
    TestContext* test)
 | 
			
		||||
{
 | 
			
		||||
    /* Undo the damage */
 | 
			
		||||
    gbinder_rpc_protocol_exit();
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    gbinder_config_file = NULL;
 | 
			
		||||
 | 
			
		||||
    remove(test->file);
 | 
			
		||||
    g_free(test->file);
 | 
			
		||||
 | 
			
		||||
    remove(test->dir);
 | 
			
		||||
    g_free(test->dir);
 | 
			
		||||
    remove(test->config_file);
 | 
			
		||||
    g_free(test->config_file);
 | 
			
		||||
    test_config_cleanup(&test->config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -184,9 +178,9 @@ test_device(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    const GBinderRpcProtocol* p;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, "");
 | 
			
		||||
    test_context_init(&context, "");
 | 
			
		||||
 | 
			
		||||
    p = gbinder_rpc_protocol_for_device(NULL);
 | 
			
		||||
    g_assert(p);
 | 
			
		||||
@@ -200,7 +194,7 @@ test_device(
 | 
			
		||||
    g_assert(p);
 | 
			
		||||
    g_assert_cmpstr(p->name, == ,"hidl");
 | 
			
		||||
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -213,9 +207,9 @@ test_config1(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    const GBinderRpcProtocol* p;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config,
 | 
			
		||||
    test_context_init(&context,
 | 
			
		||||
        "[Protocol]\n"
 | 
			
		||||
        "/dev/binder = hidl\n" /* Redefined name for /dev/binder */
 | 
			
		||||
        "/dev/hwbinder = foo\n"); /* Invalid protocol name */
 | 
			
		||||
@@ -236,7 +230,7 @@ test_config1(
 | 
			
		||||
    g_assert(p);
 | 
			
		||||
    g_assert_cmpstr(p->name, == ,"aidl");
 | 
			
		||||
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -249,9 +243,9 @@ test_config2(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    const GBinderRpcProtocol* p;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config,
 | 
			
		||||
    test_context_init(&context,
 | 
			
		||||
        "[Protocol]\n"
 | 
			
		||||
        "Default = hidl\n"
 | 
			
		||||
        "/dev/vndbinder = hidl\n"
 | 
			
		||||
@@ -278,7 +272,7 @@ test_config2(
 | 
			
		||||
    g_assert(p);
 | 
			
		||||
    g_assert_cmpstr(p->name, == ,"hidl");
 | 
			
		||||
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -291,9 +285,9 @@ test_config3(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    const GBinderRpcProtocol* p;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config,
 | 
			
		||||
    test_context_init(&context,
 | 
			
		||||
        "[Whatever]\n"
 | 
			
		||||
        "/dev/hwbinder = aidl\n"); /* Ignored, wrong section */
 | 
			
		||||
 | 
			
		||||
@@ -310,7 +304,7 @@ test_config3(
 | 
			
		||||
    g_assert(p);
 | 
			
		||||
    g_assert_cmpstr(p->name, == ,"aidl");
 | 
			
		||||
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -324,9 +318,9 @@ test_no_header1(
 | 
			
		||||
{
 | 
			
		||||
    const TestData* test = test_data;
 | 
			
		||||
    GBinderRemoteRequest* req;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init2(&config, test->dev, test->prot);
 | 
			
		||||
    test_context_init2(&context, test->dev, test->prot);
 | 
			
		||||
 | 
			
		||||
    req = gbinder_remote_request_new(NULL, gbinder_rpc_protocol_for_device
 | 
			
		||||
        (GBINDER_DEFAULT_BINDER), 0, 0);
 | 
			
		||||
@@ -334,7 +328,7 @@ test_no_header1(
 | 
			
		||||
    g_assert(!gbinder_remote_request_interface(req));
 | 
			
		||||
    gbinder_remote_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -350,9 +344,9 @@ test_no_header2(
 | 
			
		||||
    const GBinderRpcProtocol* p;
 | 
			
		||||
    GBinderDriver* driver;
 | 
			
		||||
    GBinderRemoteRequest* req;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init2(&config, test->dev, test->prot);
 | 
			
		||||
    test_context_init2(&context, test->dev, test->prot);
 | 
			
		||||
 | 
			
		||||
    p = gbinder_rpc_protocol_for_device(test->dev);
 | 
			
		||||
    driver = gbinder_driver_new(GBINDER_DEFAULT_BINDER, p);
 | 
			
		||||
@@ -365,7 +359,7 @@ test_no_header2(
 | 
			
		||||
    g_assert(!gbinder_remote_request_interface(req));
 | 
			
		||||
    gbinder_remote_request_unref(req);
 | 
			
		||||
    gbinder_driver_unref(driver);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TestData test_no_header_data[] = {
 | 
			
		||||
@@ -388,9 +382,9 @@ test_write_header(
 | 
			
		||||
    GBinderLocalRequest* req;
 | 
			
		||||
    GBinderOutputData* data;
 | 
			
		||||
    GBinderWriter writer;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init2(&config, test->dev, test->prot);
 | 
			
		||||
    test_context_init2(&context, test->dev, test->prot);
 | 
			
		||||
 | 
			
		||||
    prot = gbinder_rpc_protocol_for_device(test->dev);
 | 
			
		||||
    req = gbinder_local_request_new(&gbinder_io_32,
 | 
			
		||||
@@ -402,7 +396,7 @@ test_write_header(
 | 
			
		||||
    g_assert(!memcmp(data->bytes->data, test->header, test->header_size));
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -417,9 +411,9 @@ test_read_header(
 | 
			
		||||
    const TestHeaderData* test = test_data;
 | 
			
		||||
    GBinderDriver* driver;
 | 
			
		||||
    GBinderRemoteRequest* req;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestContext context;
 | 
			
		||||
 | 
			
		||||
    test_config_init2(&config, test->dev, test->prot);
 | 
			
		||||
    test_context_init2(&context, test->dev, test->prot);
 | 
			
		||||
 | 
			
		||||
    driver = gbinder_driver_new(test->dev, NULL);
 | 
			
		||||
    req = gbinder_remote_request_new(NULL, gbinder_rpc_protocol_for_device
 | 
			
		||||
@@ -431,7 +425,7 @@ test_read_header(
 | 
			
		||||
    gbinder_remote_request_unref(req);
 | 
			
		||||
    gbinder_driver_unref(driver);
 | 
			
		||||
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    test_context_cleanup(&context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 
 | 
			
		||||
@@ -66,9 +66,9 @@ enum test_tx_codes {
 | 
			
		||||
#define TX_PARAM_DONT_REPLY 0x22220000
 | 
			
		||||
#define TX_RESULT 0x03030303
 | 
			
		||||
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-proxy-XXXXXX";
 | 
			
		||||
const char TEST_IFACE[] = "test@1.0::ITest";
 | 
			
		||||
const char TEST_IFACE2[] = "test@1.0::ITest2";
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-proxy_object-XXXXXX";
 | 
			
		||||
static const char TEST_IFACE[] = "test@1.0::ITest";
 | 
			
		||||
static const char TEST_IFACE2[] = "test@1.0::ITest2";
 | 
			
		||||
static const char* TEST_IFACES[] =  { TEST_IFACE, NULL };
 | 
			
		||||
static const char* TEST_IFACES2[] =  { TEST_IFACE2, NULL };
 | 
			
		||||
static const char DEFAULT_CONFIG_DATA[] =
 | 
			
		||||
@@ -77,46 +77,6 @@ static const char DEFAULT_CONFIG_DATA[] =
 | 
			
		||||
    "[ServiceManager]\n"
 | 
			
		||||
    "Default = hidl\n";
 | 
			
		||||
 | 
			
		||||
typedef struct test_config {
 | 
			
		||||
    char* dir;
 | 
			
		||||
    char* file;
 | 
			
		||||
} TestConfig;
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Common
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_init(
 | 
			
		||||
    TestConfig* config,
 | 
			
		||||
    char* config_data)
 | 
			
		||||
{
 | 
			
		||||
    config->dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
 | 
			
		||||
    config->file = g_build_filename(config->dir, "test.conf", NULL);
 | 
			
		||||
    g_assert(g_file_set_contents(config->file, config_data ? config_data :
 | 
			
		||||
        DEFAULT_CONFIG_DATA, -1, NULL));
 | 
			
		||||
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    gbinder_config_dir = config->dir;
 | 
			
		||||
    gbinder_config_file = config->file;
 | 
			
		||||
    GDEBUG("Wrote config to %s", config->file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_deinit(
 | 
			
		||||
    TestConfig* config)
 | 
			
		||||
{
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
 | 
			
		||||
    remove(config->file);
 | 
			
		||||
    g_free(config->file);
 | 
			
		||||
 | 
			
		||||
    remove(config->dir);
 | 
			
		||||
    g_free(config->dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * null
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
@@ -184,7 +144,6 @@ void
 | 
			
		||||
test_basic_run(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    GBinderProxyObject* proxy;
 | 
			
		||||
    GBinderRemoteObject* remote_obj;
 | 
			
		||||
@@ -194,7 +153,6 @@ test_basic_run(
 | 
			
		||||
    GMainLoop* loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
    int fd_obj, fd_proxy, n = 0;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, NULL);
 | 
			
		||||
    ipc_proxy = gbinder_ipc_new(DEV, NULL);
 | 
			
		||||
    ipc_obj = gbinder_ipc_new(DEV2, NULL);
 | 
			
		||||
    fd_proxy = gbinder_driver_fd(ipc_proxy->driver);
 | 
			
		||||
@@ -224,7 +182,6 @@ test_basic_run(
 | 
			
		||||
    gbinder_ipc_unref(ipc_obj);
 | 
			
		||||
    gbinder_ipc_unref(ipc_proxy);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_deinit(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -332,7 +289,6 @@ void
 | 
			
		||||
test_param_run(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    GBinderProxyObject* proxy;
 | 
			
		||||
    GBinderRemoteObject* remote_obj;
 | 
			
		||||
@@ -344,7 +300,6 @@ test_param_run(
 | 
			
		||||
    GMainLoop* loop2 = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
    int fd_obj, fd_proxy, n = 0;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, NULL);
 | 
			
		||||
    ipc_proxy = gbinder_ipc_new(DEV2, NULL);
 | 
			
		||||
    ipc_obj = gbinder_ipc_new(DEV, NULL);
 | 
			
		||||
    fd_proxy = gbinder_driver_fd(ipc_proxy->driver);
 | 
			
		||||
@@ -387,7 +342,6 @@ test_param_run(
 | 
			
		||||
    gbinder_ipc_unref(ipc_obj);
 | 
			
		||||
    gbinder_ipc_unref(ipc_proxy);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_deinit(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
    g_main_loop_unref(loop2);
 | 
			
		||||
}
 | 
			
		||||
@@ -559,7 +513,6 @@ void
 | 
			
		||||
test_obj_run(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    TestObj test;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    GBinderLocalObject* obj2;
 | 
			
		||||
@@ -571,7 +524,6 @@ test_obj_run(
 | 
			
		||||
    GBinderLocalRequest* req;
 | 
			
		||||
    int fd_obj, fd_proxy;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, NULL);
 | 
			
		||||
    memset(&test, 0, sizeof(test));
 | 
			
		||||
    test.loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
@@ -621,7 +573,6 @@ test_obj_run(
 | 
			
		||||
    gbinder_ipc_unref(ipc_obj);
 | 
			
		||||
    gbinder_ipc_unref(ipc_proxy);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, test.loop);
 | 
			
		||||
    test_config_deinit(&config);
 | 
			
		||||
    g_main_loop_unref(test.loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -641,6 +592,10 @@ test_obj(
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    TestConfig test_config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
    int result;
 | 
			
		||||
 | 
			
		||||
    G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
 | 
			
		||||
    g_type_init();
 | 
			
		||||
    G_GNUC_END_IGNORE_DEPRECATIONS;
 | 
			
		||||
@@ -649,8 +604,20 @@ int main(int argc, char* argv[])
 | 
			
		||||
    g_test_add_func(TEST_("basic"), test_basic);
 | 
			
		||||
    g_test_add_func(TEST_("param"), test_param);
 | 
			
		||||
    g_test_add_func(TEST_("obj"), test_obj);
 | 
			
		||||
 | 
			
		||||
    test_init(&test_opt, argc, argv);
 | 
			
		||||
    return g_test_run();
 | 
			
		||||
    test_config_init(&test_config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    config_file = g_build_filename(test_config.config_dir, "test.conf", NULL);
 | 
			
		||||
    g_assert(g_file_set_contents(config_file, DEFAULT_CONFIG_DATA, -1, NULL));
 | 
			
		||||
    GDEBUG("Config file %s", config_file);
 | 
			
		||||
    gbinder_config_file = config_file;
 | 
			
		||||
 | 
			
		||||
    result = g_test_run();
 | 
			
		||||
 | 
			
		||||
    remove(config_file);
 | 
			
		||||
    g_free(config_file);
 | 
			
		||||
    test_config_cleanup(&test_config);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -47,6 +47,7 @@
 | 
			
		||||
#include <gutil_intarray.h>
 | 
			
		||||
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] = "gbinder-test-remote-request-XXXXXX";
 | 
			
		||||
 | 
			
		||||
#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
 | 
			
		||||
#define BINDER_RPC_FLAGS (STRICT_MODE_PENALTY_GATHER)
 | 
			
		||||
@@ -368,18 +369,9 @@ 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);
 | 
			
		||||
    TestConfig test_config;
 | 
			
		||||
    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);
 | 
			
		||||
@@ -389,13 +381,9 @@ 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);
 | 
			
		||||
    test_config_init(&test_config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    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);
 | 
			
		||||
    test_config_cleanup(&test_config);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -40,7 +40,6 @@
 | 
			
		||||
#include "gbinder_local_object_p.h"
 | 
			
		||||
#include "gbinder_servicemanager_p.h"
 | 
			
		||||
#include "gbinder_object_registry.h"
 | 
			
		||||
#include "gbinder_rpc_protocol.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_strv.h>
 | 
			
		||||
#include <gutil_macros.h>
 | 
			
		||||
@@ -500,7 +499,9 @@ test_basic(
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_servicemanager_new(dev);
 | 
			
		||||
    g_assert(sm);
 | 
			
		||||
@@ -515,6 +516,7 @@ test_basic(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -530,12 +532,9 @@ test_legacy(
 | 
			
		||||
    const char* dev = GBINDER_DEFAULT_HWBINDER;
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    /* Reset the state */
 | 
			
		||||
    gbinder_servicemanager_exit();
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    gbinder_config_file = NULL;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_hwservicemanager_new(dev);
 | 
			
		||||
    g_assert(TEST_IS_HWSERVICEMANAGER(sm));
 | 
			
		||||
@@ -558,6 +557,7 @@ test_legacy(
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    gbinder_servicemanager_exit();
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -573,8 +573,8 @@ test_config(
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    const char* strange_name = "/dev/notbinder";
 | 
			
		||||
    const char* legacy_name = "/dev/legacybinder";
 | 
			
		||||
    char* dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
 | 
			
		||||
    char* file = g_build_filename(dir, "test.conf", NULL);
 | 
			
		||||
    TestConfig test;
 | 
			
		||||
    char* file;
 | 
			
		||||
 | 
			
		||||
    static const char config[] =
 | 
			
		||||
        "[ServiceManager]\n"
 | 
			
		||||
@@ -583,12 +583,12 @@ test_config(
 | 
			
		||||
        "/dev/hwbinder = foo\n" /* Invalid name */
 | 
			
		||||
        "/dev/legacybinder = aidl\n";
 | 
			
		||||
 | 
			
		||||
    /* Reset the state */
 | 
			
		||||
    gbinder_servicemanager_exit();
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    test_config_init(&test, TMP_DIR_TEMPLATE);
 | 
			
		||||
    file = g_build_filename(test.config_dir, "test.conf", NULL);
 | 
			
		||||
 | 
			
		||||
    /* Write the config file */
 | 
			
		||||
    g_assert(g_file_set_contents(file, config, -1, NULL));
 | 
			
		||||
    GDEBUG("Config file %s", file);
 | 
			
		||||
    gbinder_config_file = file;
 | 
			
		||||
 | 
			
		||||
    /* Unknown device instantiates the default */
 | 
			
		||||
@@ -633,14 +633,10 @@ test_config(
 | 
			
		||||
 | 
			
		||||
    /* Clear the state */
 | 
			
		||||
    gbinder_servicemanager_exit();
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    gbinder_config_file = NULL;
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
 | 
			
		||||
    remove(file);
 | 
			
		||||
    remove(dir);
 | 
			
		||||
    g_free(file);
 | 
			
		||||
    g_free(dir);
 | 
			
		||||
    test_config_cleanup(&test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -656,6 +652,9 @@ test_not_present(
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(dev, NULL);
 | 
			
		||||
    const int fd = gbinder_driver_fd(ipc->driver);
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
 | 
			
		||||
    /* This makes presence detection PING fail */
 | 
			
		||||
    test_binder_br_reply_status(fd, THIS_THREAD, -1);
 | 
			
		||||
@@ -667,6 +666,7 @@ test_not_present(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -686,6 +686,9 @@ test_wait(
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    gulong id;
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
 | 
			
		||||
    /* This makes presence detection PING fail */
 | 
			
		||||
    test_binder_br_reply_status(fd, THIS_THREAD, -1);
 | 
			
		||||
@@ -718,6 +721,7 @@ test_wait(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -735,6 +739,9 @@ test_wait_long(
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    gulong id;
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
 | 
			
		||||
    /* This makes presence detection PING fail */
 | 
			
		||||
    test_binder_br_reply_status(fd, THIS_THREAD, -1);
 | 
			
		||||
@@ -764,6 +771,7 @@ test_wait_long(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -782,6 +790,9 @@ test_wait_async(
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    gulong id[2];
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
 | 
			
		||||
    /* This makes presence detection PING fail */
 | 
			
		||||
    test_binder_br_reply_status(fd, THIS_THREAD, -1);
 | 
			
		||||
@@ -808,6 +819,7 @@ test_wait_async(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -826,7 +838,9 @@ test_death_run()
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    gulong id[3];
 | 
			
		||||
    int count = 0, reg_count = 0;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_servicemanager_new(dev);
 | 
			
		||||
    g_assert(sm);
 | 
			
		||||
@@ -855,6 +869,7 @@ test_death_run()
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -900,8 +915,10 @@ test_reanimate(
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    gulong id[3];
 | 
			
		||||
    int count = 0, reg_count = 0;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    /* Create live service manager */
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_servicemanager_new(dev);
 | 
			
		||||
    g_assert(sm);
 | 
			
		||||
@@ -932,6 +949,7 @@ test_reanimate(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -956,7 +974,9 @@ test_reuse(
 | 
			
		||||
    GBinderServiceManager* vnd2;
 | 
			
		||||
    GBinderServiceManager* hw1;
 | 
			
		||||
    GBinderServiceManager* hw2;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(binder_ipc);
 | 
			
		||||
    test_setup_ping(vndbinder_ipc);
 | 
			
		||||
    test_setup_ping(hwbinder_ipc);
 | 
			
		||||
@@ -990,6 +1010,7 @@ test_reuse(
 | 
			
		||||
    gbinder_ipc_unref(vndbinder_ipc);
 | 
			
		||||
    gbinder_ipc_unref(hwbinder_ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -1008,7 +1029,9 @@ test_notify_type(
 | 
			
		||||
    const char* name = "foo";
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    gulong id1, id2;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_servicemanager_new_with_type(t, NULL, NULL);
 | 
			
		||||
    test = TEST_SERVICEMANAGER2(sm, t);
 | 
			
		||||
@@ -1035,6 +1058,7 @@ test_notify_type(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
@@ -1076,7 +1100,9 @@ test_list(
 | 
			
		||||
    TestHwServiceManager* test;
 | 
			
		||||
    char** list;
 | 
			
		||||
    gulong id;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_servicemanager_new(dev);
 | 
			
		||||
    test = TEST_SERVICEMANAGER(sm);
 | 
			
		||||
@@ -1093,6 +1119,7 @@ test_list(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1126,7 +1153,9 @@ test_get(
 | 
			
		||||
    int status = -1;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    gulong id;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_servicemanager_new(dev);
 | 
			
		||||
    test = TEST_SERVICEMANAGER(sm);
 | 
			
		||||
@@ -1157,6 +1186,7 @@ test_get(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1187,7 +1217,9 @@ test_add(
 | 
			
		||||
    TestHwServiceManager* test;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    gulong id;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test_setup_ping(ipc);
 | 
			
		||||
    sm = gbinder_servicemanager_new(dev);
 | 
			
		||||
    test = TEST_SERVICEMANAGER(sm);
 | 
			
		||||
@@ -1205,6 +1237,7 @@ test_add(
 | 
			
		||||
    gbinder_servicemanager_unref(sm);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,6 @@
 | 
			
		||||
#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"
 | 
			
		||||
@@ -46,6 +45,8 @@
 | 
			
		||||
#include <gutil_log.h>
 | 
			
		||||
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
static const char TMP_DIR_TEMPLATE[] =
 | 
			
		||||
    "gbinder-test-servicemanager_aidl-XXXXXX";
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
gbinder_servicemanager_hidl_get_type()
 | 
			
		||||
@@ -586,6 +587,9 @@ test_notify2()
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    int result;
 | 
			
		||||
 | 
			
		||||
    G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
 | 
			
		||||
    g_type_init();
 | 
			
		||||
    G_GNUC_END_IGNORE_DEPRECATIONS;
 | 
			
		||||
@@ -595,7 +599,10 @@ int main(int argc, char* argv[])
 | 
			
		||||
    g_test_add_func(TEST_("notify"), test_notify);
 | 
			
		||||
    g_test_add_func(TEST_("notify2"), test_notify2);
 | 
			
		||||
    test_init(&test_opt, argc, argv);
 | 
			
		||||
    return g_test_run();
 | 
			
		||||
    test_config_init(&config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    result = g_test_run();
 | 
			
		||||
    test_config_cleanup(&config);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@
 | 
			
		||||
#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"
 | 
			
		||||
@@ -271,10 +270,7 @@ servicemanager_aidl2_new(
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_context {
 | 
			
		||||
    const char* default_config_dir;
 | 
			
		||||
    const char* default_config_file;
 | 
			
		||||
    char* config_dir;
 | 
			
		||||
    char* config_subdir;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
    GBinderLocalObject* object;
 | 
			
		||||
    ServiceManagerAidl2* service;
 | 
			
		||||
@@ -299,14 +295,11 @@ test_context_init(
 | 
			
		||||
    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);
 | 
			
		||||
    test_config_init(&test->config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test->config_file = g_build_filename(test->config.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);
 | 
			
		||||
@@ -330,14 +323,9 @@ test_context_deinit(
 | 
			
		||||
    gbinder_servicemanager_unref(test->client);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, test->loop);
 | 
			
		||||
    remove(test->config_file);
 | 
			
		||||
    remove(test->config_dir);
 | 
			
		||||
    g_free(test->config_file);
 | 
			
		||||
    g_free(test->config_subdir);
 | 
			
		||||
    g_free(test->config_dir);
 | 
			
		||||
    g_main_loop_unref(test->loop);
 | 
			
		||||
    gbinder_config_dir = test->default_config_dir;
 | 
			
		||||
    gbinder_config_file = test->default_config_file;
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    test_config_cleanup(&test->config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@
 | 
			
		||||
#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"
 | 
			
		||||
@@ -280,10 +279,7 @@ servicemanager_aidl3_new(
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_context {
 | 
			
		||||
    const char* default_config_dir;
 | 
			
		||||
    const char* default_config_file;
 | 
			
		||||
    char* config_dir;
 | 
			
		||||
    char* config_subdir;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
    GBinderLocalObject* object;
 | 
			
		||||
    ServiceManagerAidl3* service;
 | 
			
		||||
@@ -308,14 +304,11 @@ test_context_init(
 | 
			
		||||
    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);
 | 
			
		||||
    test_config_init(&test->config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test->config_file = g_build_filename(test->config.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);
 | 
			
		||||
@@ -339,14 +332,9 @@ test_context_deinit(
 | 
			
		||||
    gbinder_servicemanager_unref(test->client);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, test->loop);
 | 
			
		||||
    remove(test->config_file);
 | 
			
		||||
    remove(test->config_dir);
 | 
			
		||||
    g_free(test->config_file);
 | 
			
		||||
    g_free(test->config_subdir);
 | 
			
		||||
    g_free(test->config_dir);
 | 
			
		||||
    g_main_loop_unref(test->loop);
 | 
			
		||||
    gbinder_config_dir = test->default_config_dir;
 | 
			
		||||
    gbinder_config_file = test->default_config_file;
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    test_config_cleanup(&test->config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@
 | 
			
		||||
#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"
 | 
			
		||||
@@ -121,24 +120,20 @@ servicemanager_aidl4_handler(
 | 
			
		||||
        gbinder_remote_request_init_reader(req, &reader);
 | 
			
		||||
        str = gbinder_reader_read_string16(&reader);
 | 
			
		||||
        if (str) {
 | 
			
		||||
            reply = gbinder_local_object_new_reply(obj);
 | 
			
		||||
            GBinderWriter writer;
 | 
			
		||||
 | 
			
		||||
            remote_obj = g_hash_table_lookup(self->objects, str);
 | 
			
		||||
            if (str) {
 | 
			
		||||
                GBinderWriter writer;
 | 
			
		||||
            reply = gbinder_local_object_new_reply(obj);
 | 
			
		||||
 | 
			
		||||
                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);
 | 
			
		||||
            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:
 | 
			
		||||
@@ -278,10 +273,7 @@ servicemanager_aidl4_new(
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_context {
 | 
			
		||||
    const char* default_config_dir;
 | 
			
		||||
    const char* default_config_file;
 | 
			
		||||
    char* config_dir;
 | 
			
		||||
    char* config_subdir;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
    GBinderLocalObject* object;
 | 
			
		||||
    ServiceManagerAidl4* service;
 | 
			
		||||
@@ -306,14 +298,11 @@ test_context_init(
 | 
			
		||||
    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);
 | 
			
		||||
    test_config_init(&test->config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    test->config_file = g_build_filename(test->config.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);
 | 
			
		||||
@@ -337,14 +326,9 @@ test_context_deinit(
 | 
			
		||||
    gbinder_servicemanager_unref(test->client);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, test->loop);
 | 
			
		||||
    remove(test->config_file);
 | 
			
		||||
    remove(test->config_dir);
 | 
			
		||||
    g_free(test->config_file);
 | 
			
		||||
    g_free(test->config_subdir);
 | 
			
		||||
    g_free(test->config_dir);
 | 
			
		||||
    g_main_loop_unref(test->loop);
 | 
			
		||||
    gbinder_config_dir = test->default_config_dir;
 | 
			
		||||
    gbinder_config_file = test->default_config_file;
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    test_config_cleanup(&test->config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021-2023 Slava Monich <slava@monich.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:
 | 
			
		||||
 *
 | 
			
		||||
@@ -51,11 +51,6 @@ static const char DEFAULT_CONFIG_DATA[] =
 | 
			
		||||
    "[ServiceManager]\n"
 | 
			
		||||
    DEV " = hidl\n";
 | 
			
		||||
 | 
			
		||||
typedef struct test_config {
 | 
			
		||||
    char* dir;
 | 
			
		||||
    char* file;
 | 
			
		||||
} TestConfig;
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
gbinder_servicemanager_aidl_get_type()
 | 
			
		||||
{
 | 
			
		||||
@@ -92,37 +87,6 @@ gbinder_servicemanager_aidl4_get_type()
 | 
			
		||||
 * Common
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_init(
 | 
			
		||||
    TestConfig* config,
 | 
			
		||||
    char* config_data)
 | 
			
		||||
{
 | 
			
		||||
    config->dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
 | 
			
		||||
    config->file = g_build_filename(config->dir, "test.conf", NULL);
 | 
			
		||||
    g_assert(g_file_set_contents(config->file, config_data ? config_data :
 | 
			
		||||
        DEFAULT_CONFIG_DATA, -1, NULL));
 | 
			
		||||
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
    gbinder_config_dir = config->dir;
 | 
			
		||||
    gbinder_config_file = config->file;
 | 
			
		||||
    GDEBUG("Wrote config to %s", config->file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_deinit(
 | 
			
		||||
    TestConfig* config)
 | 
			
		||||
{
 | 
			
		||||
    gbinder_config_exit();
 | 
			
		||||
 | 
			
		||||
    remove(config->file);
 | 
			
		||||
    g_free(config->file);
 | 
			
		||||
 | 
			
		||||
    remove(config->dir);
 | 
			
		||||
    g_free(config->dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
TestServiceManagerHidl*
 | 
			
		||||
test_servicemanager_impl_new(
 | 
			
		||||
@@ -186,7 +150,6 @@ static
 | 
			
		||||
void
 | 
			
		||||
test_get_run()
 | 
			
		||||
{
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    GBinderIpc* ipc;
 | 
			
		||||
    TestServiceManagerHidl* smsvc;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
@@ -195,7 +158,6 @@ test_get_run()
 | 
			
		||||
    GMainLoop* loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
    const char* name = "android.hidl.base@1.0::IBase/test";
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, NULL);
 | 
			
		||||
    ipc = gbinder_ipc_new(DEV, NULL);
 | 
			
		||||
    smsvc = test_servicemanager_impl_new(DEV);
 | 
			
		||||
    obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
 | 
			
		||||
@@ -234,7 +196,6 @@ test_get_run()
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
 | 
			
		||||
    test_binder_exit_wait(&test_opt, loop);
 | 
			
		||||
    test_config_deinit(&config);
 | 
			
		||||
    g_main_loop_unref(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -275,7 +236,6 @@ void
 | 
			
		||||
test_list_run()
 | 
			
		||||
{
 | 
			
		||||
    TestList test;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    GBinderIpc* ipc;
 | 
			
		||||
    TestServiceManagerHidl* smsvc;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
@@ -286,7 +246,6 @@ test_list_run()
 | 
			
		||||
    memset(&test, 0, sizeof(test));
 | 
			
		||||
    test.loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, NULL);
 | 
			
		||||
    ipc = gbinder_ipc_new(DEV, NULL);
 | 
			
		||||
    smsvc = test_servicemanager_impl_new(DEV);
 | 
			
		||||
    obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
 | 
			
		||||
@@ -323,7 +282,6 @@ test_list_run()
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
 | 
			
		||||
    test_binder_exit_wait(&test_opt, test.loop);
 | 
			
		||||
    test_config_deinit(&config);
 | 
			
		||||
 | 
			
		||||
    g_strfreev(test.list);
 | 
			
		||||
    g_main_loop_unref(test.loop);
 | 
			
		||||
@@ -399,7 +357,6 @@ void
 | 
			
		||||
test_notify_run()
 | 
			
		||||
{
 | 
			
		||||
    TestNotify test;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    GBinderIpc* ipc;
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    int fd;
 | 
			
		||||
@@ -410,7 +367,6 @@ test_notify_run()
 | 
			
		||||
    memset(&test, 0, sizeof(test));
 | 
			
		||||
    test.loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
    test_config_init(&config, NULL);
 | 
			
		||||
    ipc = gbinder_ipc_new(DEV, NULL);
 | 
			
		||||
    test.smsvc = test_servicemanager_impl_new(DEV);
 | 
			
		||||
    obj = gbinder_local_object_new(ipc, NULL, NULL, NULL);
 | 
			
		||||
@@ -448,7 +404,6 @@ test_notify_run()
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
 | 
			
		||||
    test_binder_exit_wait(&test_opt, test.loop);
 | 
			
		||||
    test_config_deinit(&config);
 | 
			
		||||
    g_main_loop_unref(test.loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -467,6 +422,10 @@ test_notify()
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    TestConfig test_config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
    int result;
 | 
			
		||||
 | 
			
		||||
    G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
 | 
			
		||||
    g_type_init();
 | 
			
		||||
    G_GNUC_END_IGNORE_DEPRECATIONS;
 | 
			
		||||
@@ -474,8 +433,20 @@ int main(int argc, char* argv[])
 | 
			
		||||
    g_test_add_func(TEST_("get"), test_get);
 | 
			
		||||
    g_test_add_func(TEST_("list"), test_list);
 | 
			
		||||
    g_test_add_func(TEST_("notify"), test_notify);
 | 
			
		||||
 | 
			
		||||
    test_init(&test_opt, argc, argv);
 | 
			
		||||
    return g_test_run();
 | 
			
		||||
    test_config_init(&test_config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    config_file = g_build_filename(test_config.config_dir, "test.conf", NULL);
 | 
			
		||||
    g_assert(g_file_set_contents(config_file, DEFAULT_CONFIG_DATA, -1, NULL));
 | 
			
		||||
    GDEBUG("Config file %s", config_file);
 | 
			
		||||
    gbinder_config_file = config_file;
 | 
			
		||||
 | 
			
		||||
    result = g_test_run();
 | 
			
		||||
 | 
			
		||||
    remove(config_file);
 | 
			
		||||
    g_free(config_file);
 | 
			
		||||
    test_config_cleanup(&test_config);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2024 Slava Monich <slava@monich.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2023 Slava Monich <slava@monich.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
@@ -34,15 +33,20 @@
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
#include "test_binder.h"
 | 
			
		||||
 | 
			
		||||
#include "gbinder_buffer_p.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_reader_p.h"
 | 
			
		||||
#include "gbinder_writer_p.h"
 | 
			
		||||
#include "gbinder_ipc.h"
 | 
			
		||||
#include "gbinder_io.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_intarray.h>
 | 
			
		||||
#include <gutil_macros.h>
 | 
			
		||||
#include <gutil_misc.h>
 | 
			
		||||
#include <gutil_log.h>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@@ -79,10 +83,7 @@ test_local_request_new_64()
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_context {
 | 
			
		||||
    const char* default_config_dir;
 | 
			
		||||
    const char* default_config_file;
 | 
			
		||||
    char* config_dir;
 | 
			
		||||
    char* config_subdir;
 | 
			
		||||
    TestConfig config;
 | 
			
		||||
    char* config_file;
 | 
			
		||||
} TestContext;
 | 
			
		||||
 | 
			
		||||
@@ -93,20 +94,17 @@ test_context_init(
 | 
			
		||||
    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;
 | 
			
		||||
    test_config_init(&test->config, TMP_DIR_TEMPLATE);
 | 
			
		||||
    if (prot) {
 | 
			
		||||
        char* config = g_strdup_printf("[Protocol]\n"
 | 
			
		||||
            GBINDER_DEFAULT_BINDER " = %s", prot);
 | 
			
		||||
 | 
			
		||||
        test->config_file = g_build_filename(test->config.config_dir,
 | 
			
		||||
            "test.conf", NULL);
 | 
			
		||||
        GDEBUG("Config file %s", test->config_file);
 | 
			
		||||
        g_assert(g_file_set_contents(test->config_file, config, -1, NULL));
 | 
			
		||||
        g_free(config);
 | 
			
		||||
        gbinder_config_file = test->config_file;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -115,15 +113,11 @@ 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();
 | 
			
		||||
    if (test->config_file) {
 | 
			
		||||
        remove(test->config_file);
 | 
			
		||||
        g_free(test->config_file);
 | 
			
		||||
    }
 | 
			
		||||
    test_config_cleanup(&test->config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
@@ -524,11 +518,23 @@ static const guint8 string16_tests_data_xy[] = {
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const guint8 string16_tests_data_surrogates[] = {
 | 
			
		||||
    TEST_INT32_BYTES(8),
 | 
			
		||||
    TEST_INT16_BYTES(0xd83d), TEST_INT16_BYTES(0xde00),
 | 
			
		||||
    TEST_INT16_BYTES(0xd83d), TEST_INT16_BYTES(0xde01),
 | 
			
		||||
    TEST_INT16_BYTES(0xd83d), TEST_INT16_BYTES(0xde02),
 | 
			
		||||
    TEST_INT16_BYTES(0xd83d), TEST_INT16_BYTES(0xde03),
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const TestString16Data test_string16_tests[] = {
 | 
			
		||||
    { "null", NULL, TEST_ARRAY_AND_SIZE(string16_tests_data_null) },
 | 
			
		||||
    { "empty", "", TEST_ARRAY_AND_SIZE(string16_tests_data_empty) },
 | 
			
		||||
    { "1", "x", TEST_ARRAY_AND_SIZE(string16_tests_data_x) },
 | 
			
		||||
    { "2", "xy", TEST_ARRAY_AND_SIZE(string16_tests_data_xy) }
 | 
			
		||||
    { "2", "xy", TEST_ARRAY_AND_SIZE(string16_tests_data_xy) },
 | 
			
		||||
    { "surrogates", "\xF0\x9F\x98\x80" "\xF0\x9F\x98\x81"
 | 
			
		||||
      "\xF0\x9F\x98\x82" "\xF0\x9F\x98\x83",
 | 
			
		||||
      TEST_ARRAY_AND_SIZE(string16_tests_data_surrogates) }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
@@ -546,7 +552,7 @@ test_string16(
 | 
			
		||||
    data = gbinder_local_request_data(req);
 | 
			
		||||
    g_assert(!gbinder_output_data_offsets(data));
 | 
			
		||||
    g_assert(!gbinder_output_data_buffers_size(data));
 | 
			
		||||
    g_assert(data->bytes->len == test->output_len);
 | 
			
		||||
    g_assert_cmpuint(data->bytes->len, == ,test->output_len);
 | 
			
		||||
    g_assert(!memcmp(data->bytes->data, test->output, test->output_len));
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
}
 | 
			
		||||
@@ -1147,6 +1153,108 @@ test_struct(
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * struct_vec
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_struct_vec(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    /* vec<byte> */
 | 
			
		||||
    static const GBinderWriterField vec_byte_ptr_f[] = {
 | 
			
		||||
        {
 | 
			
		||||
            "ptr", GBINDER_HIDL_VEC_BUFFER_OFFSET, &gbinder_writer_type_byte,
 | 
			
		||||
            gbinder_writer_field_hidl_vec_write_buf, NULL
 | 
			
		||||
        },
 | 
			
		||||
        GBINDER_WRITER_FIELD_END()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static const GBinderWriterType vec_byte_t = {
 | 
			
		||||
        GBINDER_WRITER_STRUCT_NAME_AND_SIZE(GBinderHidlVec), vec_byte_ptr_f
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* vec<int32> */
 | 
			
		||||
    static const GBinderWriterField vec_int32_ptr_f[] = {
 | 
			
		||||
        {
 | 
			
		||||
            "ptr", GBINDER_HIDL_VEC_BUFFER_OFFSET, &gbinder_writer_type_int32,
 | 
			
		||||
            gbinder_writer_field_hidl_vec_write_buf, NULL
 | 
			
		||||
        },
 | 
			
		||||
        GBINDER_WRITER_FIELD_END()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static const GBinderWriterType vec_int32_t = {
 | 
			
		||||
        GBINDER_WRITER_STRUCT_NAME_AND_SIZE(GBinderHidlVec), vec_int32_ptr_f
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
 | 
			
		||||
    GBinderLocalRequest* req =  gbinder_local_request_new(gbinder_ipc_io(ipc),
 | 
			
		||||
          gbinder_ipc_protocol(ipc), NULL);
 | 
			
		||||
    GBinderOutputData* writer_data;
 | 
			
		||||
    GBinderReaderData reader_data;
 | 
			
		||||
    GBinderWriter writer;
 | 
			
		||||
    GBinderReader reader;
 | 
			
		||||
    GUtilIntArray* offsets;
 | 
			
		||||
    GBinderHidlVec vec_byte, vec_int32;
 | 
			
		||||
    gsize count, elemsize;
 | 
			
		||||
    const void* vec_data;
 | 
			
		||||
    guint i;
 | 
			
		||||
 | 
			
		||||
    static const guint8 vec_byte_data[] = { 0x01, 0x02 };
 | 
			
		||||
    static const guint32 vec_int32_data[] = { 42 };
 | 
			
		||||
 | 
			
		||||
    memset(&vec_byte, 0, sizeof(vec_byte));
 | 
			
		||||
    vec_byte.data.ptr = vec_byte_data;
 | 
			
		||||
    vec_byte.count = G_N_ELEMENTS(vec_byte_data);
 | 
			
		||||
 | 
			
		||||
    memset(&vec_int32, 0, sizeof(vec_int32));
 | 
			
		||||
    vec_int32.data.ptr = vec_int32_data;
 | 
			
		||||
    vec_int32.count = G_N_ELEMENTS(vec_int32_data);
 | 
			
		||||
 | 
			
		||||
    gbinder_local_request_init_writer(req, &writer);
 | 
			
		||||
    gbinder_writer_append_struct(&writer, &vec_byte, &vec_byte_t, NULL);
 | 
			
		||||
    gbinder_writer_append_struct(&writer, &vec_int32, &vec_int32_t, NULL);
 | 
			
		||||
 | 
			
		||||
    writer_data = gbinder_local_request_data(req);
 | 
			
		||||
    offsets = gbinder_output_data_offsets(writer_data);
 | 
			
		||||
    g_assert(offsets);
 | 
			
		||||
    g_assert_cmpuint(offsets->count, == ,4);
 | 
			
		||||
 | 
			
		||||
    /* Set up the reader */
 | 
			
		||||
    memset(&reader_data, 0, sizeof(reader_data));
 | 
			
		||||
    reader_data.reg = gbinder_ipc_object_registry(ipc);
 | 
			
		||||
    reader_data.objects = g_new0(void*, offsets->count + 1);
 | 
			
		||||
    reader_data.buffer = gbinder_buffer_new(ipc->driver,
 | 
			
		||||
        gutil_memdup(writer_data->bytes->data, writer_data->bytes->len),
 | 
			
		||||
        writer_data->bytes->len, reader_data.objects);
 | 
			
		||||
    for (i = 0; i < offsets->count; i++) {
 | 
			
		||||
        reader_data.objects[i] =  reader_data.buffer->data + offsets->data[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Read those vectors back */
 | 
			
		||||
    gbinder_reader_init(&reader, &reader_data, 0, writer_data->bytes->len);
 | 
			
		||||
 | 
			
		||||
    /* vec<byte> */
 | 
			
		||||
    vec_data = gbinder_reader_read_hidl_vec(&reader, &count, &elemsize);
 | 
			
		||||
    g_assert(vec_data);
 | 
			
		||||
    g_assert_cmpuint(count, == ,G_N_ELEMENTS(vec_byte_data));
 | 
			
		||||
    g_assert_cmpuint(elemsize, == ,sizeof(vec_byte_data[0]));
 | 
			
		||||
    g_assert(!memcmp(vec_data, vec_byte_data, sizeof(vec_byte_data)));
 | 
			
		||||
 | 
			
		||||
    /* vec<int32> */
 | 
			
		||||
    vec_data = gbinder_reader_read_hidl_vec(&reader, &count, &elemsize);
 | 
			
		||||
    g_assert(vec_data);
 | 
			
		||||
    g_assert_cmpuint(count, == ,G_N_ELEMENTS(vec_int32_data));
 | 
			
		||||
    g_assert_cmpuint(elemsize, == ,sizeof(vec_int32_data[0]));
 | 
			
		||||
    g_assert(!memcmp(vec_data, vec_int32_data, sizeof(vec_int32_data)));
 | 
			
		||||
 | 
			
		||||
    gbinder_buffer_free(reader_data.buffer);
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
    gbinder_ipc_unref(ipc);
 | 
			
		||||
    test_binder_exit_wait(&test_opt, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * fd
 | 
			
		||||
 * fd_invalid
 | 
			
		||||
@@ -1303,7 +1411,7 @@ test_byte_array(
 | 
			
		||||
    GBinderOutputData* data;
 | 
			
		||||
    GBinderWriter writer;
 | 
			
		||||
 | 
			
		||||
    const char in_data[] = "abcd1234";
 | 
			
		||||
    const char in_data[] = "abcd12";
 | 
			
		||||
    gint32 in_len = sizeof(in_data) - 1;
 | 
			
		||||
    gint32 null_len = -1;
 | 
			
		||||
 | 
			
		||||
@@ -1336,7 +1444,7 @@ test_byte_array(
 | 
			
		||||
    data = gbinder_local_request_data(req);
 | 
			
		||||
    g_assert(!gbinder_output_data_offsets(data));
 | 
			
		||||
    g_assert(!gbinder_output_data_buffers_size(data));
 | 
			
		||||
    g_assert(data->bytes->len == sizeof(in_len) + in_len);
 | 
			
		||||
    g_assert(data->bytes->len == sizeof(in_len) + G_ALIGN4(in_len));
 | 
			
		||||
    g_assert(!memcmp(data->bytes->data, &in_len, sizeof(in_len)));
 | 
			
		||||
    g_assert(!memcmp(data->bytes->data + sizeof(in_len), in_data, in_len));
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
@@ -1484,6 +1592,7 @@ int main(int argc, char* argv[])
 | 
			
		||||
    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_("struct_vec"), test_struct_vec);
 | 
			
		||||
    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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user