mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
gdbus: Allow GDBusObjectManagerClient to work on peer connections
Allow GDBusObjectManagerClient to work on peer to peer DBus connections. Don't require that a unique bus name is available for the object manager, if the owned bus name is NULL. https://bugzilla.gnome.org/show_bug.cgi?id=686920
This commit is contained in:
parent
7db2ac7b88
commit
fb2d3aacb5
@ -263,6 +263,7 @@ g_dbus_object_manager_client_set_property (GObject *_object,
|
|||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);
|
GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@ -287,8 +288,9 @@ g_dbus_object_manager_client_set_property (GObject *_object,
|
|||||||
|
|
||||||
case PROP_NAME:
|
case PROP_NAME:
|
||||||
g_assert (manager->priv->name == NULL);
|
g_assert (manager->priv->name == NULL);
|
||||||
g_assert (g_dbus_is_name (g_value_get_string (value)));
|
name = g_value_get_string (value);
|
||||||
manager->priv->name = g_value_dup_string (value);
|
g_assert (name == NULL || g_dbus_is_name (name));
|
||||||
|
manager->priv->name = g_strdup (name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_FLAGS:
|
case PROP_FLAGS:
|
||||||
@ -585,7 +587,7 @@ g_dbus_object_manager_client_init (GDBusObjectManagerClient *manager)
|
|||||||
* g_dbus_object_manager_client_new_sync:
|
* g_dbus_object_manager_client_new_sync:
|
||||||
* @connection: A #GDBusConnection.
|
* @connection: A #GDBusConnection.
|
||||||
* @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
|
* @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
|
||||||
* @name: The owner of the control object (unique or well-known name).
|
* @name: (allow-none): The owner of the control object (unique or well-known name), or %NULL when not using a message bus connection.
|
||||||
* @object_path: The object path of the control object.
|
* @object_path: The object path of the control object.
|
||||||
* @get_proxy_type_func: (allow-none): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
|
* @get_proxy_type_func: (allow-none): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
|
||||||
* @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
|
* @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
|
||||||
@ -911,7 +913,8 @@ g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager)
|
|||||||
* g_dbus_object_manager_client_get_name:
|
* g_dbus_object_manager_client_get_name:
|
||||||
* @manager: A #GDBusObjectManagerClient
|
* @manager: A #GDBusObjectManagerClient
|
||||||
*
|
*
|
||||||
* Gets the name that @manager is for.
|
* Gets the name that @manager is for, or %NULL if not a message bus
|
||||||
|
* connection.
|
||||||
*
|
*
|
||||||
* Returns: A unique or well-known name. Do not free, the string
|
* Returns: A unique or well-known name. Do not free, the string
|
||||||
* belongs to @manager.
|
* belongs to @manager.
|
||||||
@ -1096,38 +1099,41 @@ static void
|
|||||||
subscribe_signals (GDBusObjectManagerClient *manager,
|
subscribe_signals (GDBusObjectManagerClient *manager,
|
||||||
const gchar *name_owner)
|
const gchar *name_owner)
|
||||||
{
|
{
|
||||||
GError *error;
|
GError *error = NULL;
|
||||||
GVariant *ret;
|
GVariant *ret;
|
||||||
|
|
||||||
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));
|
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));
|
||||||
g_return_if_fail (manager->priv->signal_subscription_id == 0);
|
g_return_if_fail (manager->priv->signal_subscription_id == 0);
|
||||||
g_return_if_fail (g_dbus_is_unique_name (name_owner));
|
g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));
|
||||||
|
|
||||||
/* the bus daemon may not implement path_prefix so gracefully
|
if (name_owner != NULL)
|
||||||
* handle this by using a fallback
|
|
||||||
*/
|
|
||||||
manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s',path_namespace='%s'",
|
|
||||||
name_owner,
|
|
||||||
manager->priv->object_path);
|
|
||||||
|
|
||||||
error = NULL;
|
|
||||||
ret = g_dbus_connection_call_sync (manager->priv->connection,
|
|
||||||
"org.freedesktop.DBus",
|
|
||||||
"/org/freedeskop/DBus",
|
|
||||||
"org.freedesktop.DBus",
|
|
||||||
"AddMatch",
|
|
||||||
g_variant_new ("(s)",
|
|
||||||
manager->priv->match_rule),
|
|
||||||
NULL, /* reply_type */
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
|
||||||
-1, /* default timeout */
|
|
||||||
NULL, /* TODO: Cancellable */
|
|
||||||
&error);
|
|
||||||
if (ret != NULL)
|
|
||||||
{
|
{
|
||||||
/* yay, bus daemon supports path_namespace */
|
/* the bus daemon may not implement path_prefix so gracefully
|
||||||
g_variant_unref (ret);
|
* handle this by using a fallback
|
||||||
|
*/
|
||||||
|
manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s',path_namespace='%s'",
|
||||||
|
name_owner, manager->priv->object_path);
|
||||||
|
|
||||||
|
ret = g_dbus_connection_call_sync (manager->priv->connection,
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
"/org/freedeskop/DBus",
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
"AddMatch",
|
||||||
|
g_variant_new ("(s)",
|
||||||
|
manager->priv->match_rule),
|
||||||
|
NULL, /* reply_type */
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* default timeout */
|
||||||
|
NULL, /* TODO: Cancellable */
|
||||||
|
&error);
|
||||||
|
|
||||||
|
/* yay, bus daemon supports path_namespace */
|
||||||
|
if (ret != NULL)
|
||||||
|
g_variant_unref (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == NULL)
|
||||||
|
{
|
||||||
/* still need to ask GDBusConnection for the callbacks */
|
/* still need to ask GDBusConnection for the callbacks */
|
||||||
manager->priv->signal_subscription_id =
|
manager->priv->signal_subscription_id =
|
||||||
g_dbus_connection_signal_subscribe (manager->priv->connection,
|
g_dbus_connection_signal_subscribe (manager->priv->connection,
|
||||||
@ -1347,7 +1353,7 @@ initable_init (GInitable *initable,
|
|||||||
manager);
|
manager);
|
||||||
|
|
||||||
manager->priv->name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
|
manager->priv->name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
|
||||||
if (manager->priv->name_owner == NULL)
|
if (manager->priv->name_owner == NULL && manager->priv->name != NULL)
|
||||||
{
|
{
|
||||||
/* it's perfectly fine if there's no name owner.. we're just going to
|
/* it's perfectly fine if there's no name owner.. we're just going to
|
||||||
* wait until one is ready
|
* wait until one is ready
|
||||||
@ -1355,7 +1361,7 @@ initable_init (GInitable *initable,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* yay, we have a name owner */
|
/* yay, we can get the objects */
|
||||||
g_signal_connect (manager->priv->control_proxy,
|
g_signal_connect (manager->priv->control_proxy,
|
||||||
"g-signal",
|
"g-signal",
|
||||||
G_CALLBACK (on_control_proxy_g_signal),
|
G_CALLBACK (on_control_proxy_g_signal),
|
||||||
@ -1418,7 +1424,7 @@ add_interfaces (GDBusObjectManagerClient *manager,
|
|||||||
GList *interface_added_signals, *l;
|
GList *interface_added_signals, *l;
|
||||||
GDBusProxy *interface_proxy;
|
GDBusProxy *interface_proxy;
|
||||||
|
|
||||||
g_return_if_fail (g_dbus_is_unique_name (name_owner));
|
g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));
|
||||||
|
|
||||||
g_mutex_lock (&manager->priv->lock);
|
g_mutex_lock (&manager->priv->lock);
|
||||||
|
|
||||||
@ -1615,7 +1621,7 @@ process_get_all_result (GDBusObjectManagerClient *manager,
|
|||||||
GVariant *ifaces_and_properties;
|
GVariant *ifaces_and_properties;
|
||||||
GVariantIter iter;
|
GVariantIter iter;
|
||||||
|
|
||||||
g_return_if_fail (g_dbus_is_unique_name (name_owner));
|
g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));
|
||||||
|
|
||||||
arg0 = g_variant_get_child_value (value, 0);
|
arg0 = g_variant_get_child_value (value, 0);
|
||||||
g_variant_iter_init (&iter, arg0);
|
g_variant_iter_init (&iter, arg0);
|
||||||
|
1
gio/tests/.gitignore
vendored
1
gio/tests/.gitignore
vendored
@ -56,6 +56,7 @@ gdbus-message
|
|||||||
gdbus-names
|
gdbus-names
|
||||||
gdbus-non-socket
|
gdbus-non-socket
|
||||||
gdbus-peer
|
gdbus-peer
|
||||||
|
gdbus-peer-object-manager
|
||||||
gdbus-proxy
|
gdbus-proxy
|
||||||
gdbus-proxy-threads
|
gdbus-proxy-threads
|
||||||
gdbus-proxy-well-known-name
|
gdbus-proxy-well-known-name
|
||||||
|
@ -92,6 +92,7 @@ TEST_PROGS += \
|
|||||||
gdbus-peer \
|
gdbus-peer \
|
||||||
gdbus-exit-on-close \
|
gdbus-exit-on-close \
|
||||||
gdbus-non-socket \
|
gdbus-non-socket \
|
||||||
|
gdbus-peer-object-manager \
|
||||||
appinfo \
|
appinfo \
|
||||||
contenttype \
|
contenttype \
|
||||||
mimeapps \
|
mimeapps \
|
||||||
@ -322,6 +323,8 @@ BUILT_SOURCES += gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h
|
|||||||
gdbus_test_codegen_SOURCES = gdbus-test-codegen.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
|
gdbus_test_codegen_SOURCES = gdbus-test-codegen.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
|
||||||
gdbus_test_codegen_SOURCES += gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h
|
gdbus_test_codegen_SOURCES += gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h
|
||||||
gdbus_test_codegen_LDADD = $(progs_ldadd)
|
gdbus_test_codegen_LDADD = $(progs_ldadd)
|
||||||
|
|
||||||
|
gdbus_peer_object_manager_LDADD = $(progs_ldadd)
|
||||||
endif # OS_UNIX
|
endif # OS_UNIX
|
||||||
|
|
||||||
gdbus_connection_SOURCES = gdbus-connection.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
|
gdbus_connection_SOURCES = gdbus-connection.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
|
||||||
|
364
gio/tests/gdbus-peer-object-manager.c
Normal file
364
gio/tests/gdbus-peer-object-manager.c
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
/* GLib testing framework examples and tests
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General
|
||||||
|
* Public License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Author: Stef Walter <stefw@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDBusInterfaceSkeleton parent;
|
||||||
|
gint number;
|
||||||
|
} MockInterface;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDBusInterfaceSkeletonClass parent_class;
|
||||||
|
} MockInterfaceClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MockInterface, mock_interface, G_TYPE_DBUS_INTERFACE_SKELETON);
|
||||||
|
|
||||||
|
static void
|
||||||
|
mock_interface_init (MockInterface *self)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static GDBusInterfaceInfo *
|
||||||
|
mock_interface_get_info (GDBusInterfaceSkeleton *skeleton)
|
||||||
|
{
|
||||||
|
static GDBusPropertyInfo path_info = {
|
||||||
|
-1,
|
||||||
|
"Path",
|
||||||
|
"o",
|
||||||
|
G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static GDBusPropertyInfo number_info = {
|
||||||
|
-1,
|
||||||
|
"Number",
|
||||||
|
"i",
|
||||||
|
G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static GDBusPropertyInfo *property_info[] = {
|
||||||
|
&path_info,
|
||||||
|
&number_info,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static GDBusInterfaceInfo interface_info = {
|
||||||
|
-1,
|
||||||
|
(gchar *) "org.mock.Interface",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GDBusPropertyInfo **) &property_info,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
return &interface_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
GVariant *
|
||||||
|
mock_interface_get_property (GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *property_name,
|
||||||
|
GError **error,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MockInterface *self = user_data;
|
||||||
|
if (g_str_equal (property_name, "Path"))
|
||||||
|
return g_variant_new_object_path (object_path);
|
||||||
|
else if (g_str_equal (property_name, "Number"))
|
||||||
|
return g_variant_new_int32 (self->number);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GDBusInterfaceVTable *
|
||||||
|
mock_interface_get_vtable (GDBusInterfaceSkeleton *interface)
|
||||||
|
{
|
||||||
|
static GDBusInterfaceVTable vtable = {
|
||||||
|
NULL,
|
||||||
|
mock_interface_get_property,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
return &vtable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
mock_interface_get_properties (GDBusInterfaceSkeleton *interface)
|
||||||
|
{
|
||||||
|
GVariantBuilder builder;
|
||||||
|
GDBusInterfaceInfo *info;
|
||||||
|
GDBusInterfaceVTable *vtable;
|
||||||
|
guint n;
|
||||||
|
|
||||||
|
/* Groan, this is completely generic code and should be in gdbus */
|
||||||
|
|
||||||
|
info = g_dbus_interface_skeleton_get_info (interface);
|
||||||
|
vtable = g_dbus_interface_skeleton_get_vtable (interface);
|
||||||
|
|
||||||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||||
|
for (n = 0; info->properties[n] != NULL; n++)
|
||||||
|
{
|
||||||
|
if (info->properties[n]->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
|
||||||
|
{
|
||||||
|
GVariant *value;
|
||||||
|
g_return_val_if_fail (vtable->get_property != NULL, NULL);
|
||||||
|
value = (vtable->get_property) (g_dbus_interface_skeleton_get_connection (interface), NULL,
|
||||||
|
g_dbus_interface_skeleton_get_object_path (interface),
|
||||||
|
info->name, info->properties[n]->name,
|
||||||
|
NULL, interface);
|
||||||
|
if (value != NULL)
|
||||||
|
{
|
||||||
|
g_variant_take_ref (value);
|
||||||
|
g_variant_builder_add (&builder, "{sv}", info->properties[n]->name, value);
|
||||||
|
g_variant_unref (value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_variant_builder_end (&builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mock_interface_flush (GDBusInterfaceSkeleton *skeleton)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mock_interface_class_init (MockInterfaceClass *klass)
|
||||||
|
{
|
||||||
|
GDBusInterfaceSkeletonClass *skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
|
||||||
|
skeleton_class->get_info = mock_interface_get_info;
|
||||||
|
skeleton_class->get_properties = mock_interface_get_properties;
|
||||||
|
skeleton_class->flush = mock_interface_flush;
|
||||||
|
skeleton_class->get_vtable = mock_interface_get_vtable;
|
||||||
|
}
|
||||||
|
typedef struct {
|
||||||
|
GDBusConnection *server;
|
||||||
|
GDBusConnection *client;
|
||||||
|
GMainLoop *loop;
|
||||||
|
GAsyncResult *result;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_server_connection (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Test *test = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_assert (test->server == NULL);
|
||||||
|
test->server = g_dbus_connection_new_finish (result, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert (test->server != NULL);
|
||||||
|
|
||||||
|
if (test->server && test->client)
|
||||||
|
g_main_loop_quit (test->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_client_connection (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Test *test = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_assert (test->client == NULL);
|
||||||
|
test->client = g_dbus_connection_new_finish (result, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert (test->client != NULL);
|
||||||
|
|
||||||
|
if (test->server && test->client)
|
||||||
|
g_main_loop_quit (test->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup (Test *test,
|
||||||
|
gconstpointer unused)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GSocket *socket;
|
||||||
|
GSocketConnection *stream;
|
||||||
|
gchar *guid;
|
||||||
|
int pair[2];
|
||||||
|
|
||||||
|
test->loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0)
|
||||||
|
{
|
||||||
|
g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (errno),
|
||||||
|
g_strerror (errno));
|
||||||
|
g_assert_no_error (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build up the server stuff */
|
||||||
|
socket = g_socket_new_from_fd (pair[1], &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
stream = g_socket_connection_factory_create_connection (socket);
|
||||||
|
g_assert (stream != NULL);
|
||||||
|
g_object_unref (socket);
|
||||||
|
|
||||||
|
guid = g_dbus_generate_guid ();
|
||||||
|
g_dbus_connection_new (G_IO_STREAM (stream), guid,
|
||||||
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER |
|
||||||
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
|
||||||
|
NULL, NULL, on_server_connection, test);
|
||||||
|
g_object_unref (stream);
|
||||||
|
g_free (guid);
|
||||||
|
|
||||||
|
/* Build up the client stuff */
|
||||||
|
socket = g_socket_new_from_fd (pair[0], &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
stream = g_socket_connection_factory_create_connection (socket);
|
||||||
|
g_assert (stream != NULL);
|
||||||
|
g_object_unref (socket);
|
||||||
|
|
||||||
|
g_dbus_connection_new (G_IO_STREAM (stream), NULL,
|
||||||
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
|
||||||
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
|
||||||
|
NULL, NULL, on_client_connection, test);
|
||||||
|
|
||||||
|
g_main_loop_run (test->loop);
|
||||||
|
|
||||||
|
g_assert (test->server);
|
||||||
|
g_assert (test->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
teardown (Test *test,
|
||||||
|
gconstpointer unused)
|
||||||
|
{
|
||||||
|
g_clear_object (&test->client);
|
||||||
|
g_clear_object (&test->server);
|
||||||
|
g_main_loop_unref (test->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_result (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Test *test = user_data;
|
||||||
|
g_assert (test->result == NULL);
|
||||||
|
test->result = g_object_ref (result);
|
||||||
|
g_main_loop_quit (test->loop);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_manager (Test *test,
|
||||||
|
gconstpointer unused)
|
||||||
|
{
|
||||||
|
GDBusObjectManager *client;
|
||||||
|
GDBusObjectManagerServer *server;
|
||||||
|
MockInterface *mock;
|
||||||
|
GDBusObjectSkeleton *skeleton;
|
||||||
|
const gchar *dbus_name;
|
||||||
|
GError *error = NULL;
|
||||||
|
GDBusInterface *proxy;
|
||||||
|
GVariant *prop;
|
||||||
|
|
||||||
|
server = g_dbus_object_manager_server_new ("/objects");
|
||||||
|
|
||||||
|
mock = g_object_new (mock_interface_get_type (), NULL);
|
||||||
|
mock->number = 1;
|
||||||
|
skeleton = g_dbus_object_skeleton_new ("/objects/number_1");
|
||||||
|
g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock));
|
||||||
|
g_dbus_object_manager_server_export (server, skeleton);
|
||||||
|
|
||||||
|
mock = g_object_new (mock_interface_get_type (), NULL);
|
||||||
|
mock->number = 2;
|
||||||
|
skeleton = g_dbus_object_skeleton_new ("/objects/number_2");
|
||||||
|
g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock));
|
||||||
|
g_dbus_object_manager_server_export (server, skeleton);
|
||||||
|
|
||||||
|
g_dbus_object_manager_server_set_connection (server, test->server);
|
||||||
|
|
||||||
|
dbus_name = NULL;
|
||||||
|
|
||||||
|
g_dbus_object_manager_client_new (test->client, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
|
||||||
|
dbus_name, "/objects", NULL, NULL, NULL, NULL, on_result, test);
|
||||||
|
|
||||||
|
g_main_loop_run (test->loop);
|
||||||
|
client = g_dbus_object_manager_client_new_finish (test->result, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_clear_object (&test->result);
|
||||||
|
|
||||||
|
proxy = g_dbus_object_manager_get_interface (client, "/objects/number_1", "org.mock.Interface");
|
||||||
|
g_assert (proxy != NULL);
|
||||||
|
prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path");
|
||||||
|
g_assert (prop != NULL);
|
||||||
|
g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH);
|
||||||
|
g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, "/objects/number_1");
|
||||||
|
g_variant_unref (prop);
|
||||||
|
prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number");
|
||||||
|
g_assert (prop != NULL);
|
||||||
|
g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_INT32);
|
||||||
|
g_assert_cmpint (g_variant_get_int32 (prop), ==, 1);
|
||||||
|
g_variant_unref (prop);
|
||||||
|
g_object_unref (proxy);
|
||||||
|
|
||||||
|
proxy = g_dbus_object_manager_get_interface (client, "/objects/number_2", "org.mock.Interface");
|
||||||
|
g_assert (proxy != NULL);
|
||||||
|
prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path");
|
||||||
|
g_assert (prop != NULL);
|
||||||
|
g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH);
|
||||||
|
g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, "/objects/number_2");
|
||||||
|
g_variant_unref (prop);
|
||||||
|
prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number");
|
||||||
|
g_assert (prop != NULL);
|
||||||
|
g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_INT32);
|
||||||
|
g_assert_cmpint (g_variant_get_int32 (prop), ==, 2);
|
||||||
|
g_variant_unref (prop);
|
||||||
|
g_object_unref (proxy);
|
||||||
|
|
||||||
|
g_object_unref (server);
|
||||||
|
g_object_unref (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_test_add ("/gdbus/peer-object-manager", Test, NULL, setup, test_object_manager, teardown);
|
||||||
|
|
||||||
|
return g_test_run();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user