diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2009-06-09 09:27:57 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2009-06-10 14:37:48 +0100 |
commit | f0743304591969845663ebf3ab7ba57fadd5b85e (patch) | |
tree | f1b14f344757b964a94c2e2a2e17b8dcf14be2eb | |
parent | 2e184d2d313e9b30a9f81f4cf9376dbe1e4811c3 (diff) | |
download | telepathy-glib-f0743304591969845663ebf3ab7ba57fadd5b85e.tar.gz |
Add basic proxies for ChannelDispatchOperation, ChannelRequest
-rw-r--r-- | docs/reference/telepathy-glib-docs.sgml | 4 | ||||
-rw-r--r-- | docs/reference/telepathy-glib-sections.txt | 114 | ||||
-rw-r--r-- | docs/reference/telepathy-glib.types | 8 | ||||
-rw-r--r-- | spec/Channel_Dispatch_Operation.xml | 3 | ||||
-rw-r--r-- | spec/Channel_Request.xml | 3 | ||||
-rw-r--r-- | telepathy-glib/Makefile.am | 25 | ||||
-rw-r--r-- | telepathy-glib/channel-dispatch-operation.c | 223 | ||||
-rw-r--r-- | telepathy-glib/channel-dispatch-operation.h | 78 | ||||
-rw-r--r-- | telepathy-glib/channel-dispatch-operation.xml | 9 | ||||
-rw-r--r-- | telepathy-glib/channel-request.c | 250 | ||||
-rw-r--r-- | telepathy-glib/channel-request.h | 74 | ||||
-rw-r--r-- | telepathy-glib/channel-request.xml | 9 | ||||
-rw-r--r-- | telepathy-glib/extra-gtkdoc.h | 45 | ||||
-rw-r--r-- | telepathy-glib/stable-interfaces.xml | 2 | ||||
-rw-r--r-- | telepathy-glib/svc-channel-dispatch-operation.h | 6 | ||||
-rw-r--r-- | telepathy-glib/svc-channel-request.h | 6 | ||||
-rw-r--r-- | tests/dbus/Makefile.am | 6 | ||||
-rw-r--r-- | tests/dbus/channel-dispatch-operation.c | 232 | ||||
-rw-r--r-- | tests/dbus/channel-request.c | 276 |
19 files changed, 1369 insertions, 4 deletions
diff --git a/docs/reference/telepathy-glib-docs.sgml b/docs/reference/telepathy-glib-docs.sgml index 48260d1f1..cdc2e06be 100644 --- a/docs/reference/telepathy-glib-docs.sgml +++ b/docs/reference/telepathy-glib-docs.sgml @@ -49,6 +49,8 @@ <xi:include href="xml/account-manager.xml"/> <xi:include href="xml/account.xml"/> <xi:include href="xml/channel-dispatcher.xml"/> + <xi:include href="xml/channel-dispatch-operation.xml"/> + <xi:include href="xml/channel-request.xml"/> </chapter> <chapter id="ch-service-dbus"> @@ -70,6 +72,8 @@ <xi:include href="xml/svc-account-manager.xml"/> <xi:include href="xml/svc-account.xml"/> <xi:include href="xml/svc-channel-dispatcher.xml"/> + <xi:include href="xml/svc-channel-dispatch-operation.xml"/> + <xi:include href="xml/svc-channel-request.xml"/> </chapter> <chapter id="ch-service-base"> <title>Service-side implementation</title> diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index 11ba90717..ccc40a5f4 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -1940,6 +1940,10 @@ TP_IFACE_CHANNEL_DISPATCHER TP_IFACE_QUARK_CHANNEL_DISPATCHER TP_IFACE_CHANNEL_DISPATCHER_INTERFACE_OPERATION_LIST TP_IFACE_QUARK_CHANNEL_DISPATCHER_INTERFACE_OPERATION_LIST +TP_IFACE_CHANNEL_DISPATCH_OPERATION +TP_IFACE_QUARK_CHANNEL_DISPATCH_OPERATION +TP_IFACE_CHANNEL_REQUEST +TP_IFACE_QUARK_CHANNEL_REQUEST TP_IFACE_MEDIA_SESSION_HANDLER TP_IFACE_QUARK_MEDIA_SESSION_HANDLER TP_IFACE_MEDIA_STREAM_HANDLER @@ -1973,6 +1977,8 @@ tp_iface_quark_channel_type_dbus_tube tp_iface_quark_channel_type_stream_tube tp_iface_quark_channel_dispatcher tp_iface_quark_channel_dispatcher_interface_operation_list +tp_iface_quark_channel_dispatch_operation +tp_iface_quark_channel_request tp_iface_quark_connection tp_iface_quark_connection_interface_aliasing tp_iface_quark_connection_interface_avatars @@ -3007,3 +3013,111 @@ tp_svc_channel_dispatcher_interface_operation_list_get_type TP_SVC_CHANNEL_DISPATCHER_GET_CLASS TP_SVC_CHANNEL_DISPATCHER_INTERFACE_OPERATION_LIST_GET_CLASS </SECTION> + +<SECTION> +<FILE>channel-dispatch-operation</FILE> +<INCLUDE>telepathy-glib/channel-dispatch-operation.h</INCLUDE> +<TITLE>channel-dispatch-operation</TITLE> +TpChannelDispatchOperation +TpChannelDispatchOperationClass +tp_channel_dispatch_operation_new +<SUBSECTION> +tp_cli_channel_dispatch_operation_callback_for_claim +tp_cli_channel_dispatch_operation_call_claim +tp_cli_channel_dispatch_operation_callback_for_handle_with +tp_cli_channel_dispatch_operation_call_handle_with +tp_cli_channel_dispatch_operation_signal_callback_channel_lost +tp_cli_channel_dispatch_operation_connect_to_channel_lost +tp_cli_channel_dispatch_operation_signal_callback_finished +tp_cli_channel_dispatch_operation_connect_to_finished +<SUBSECTION Standard> +TP_CHANNEL_DISPATCH_OPERATION +TP_CHANNEL_DISPATCH_OPERATION_CLASS +TP_CHANNEL_DISPATCH_OPERATION_GET_CLASS +TP_IS_CHANNEL_DISPATCH_OPERATION +TP_IS_CHANNEL_DISPATCH_OPERATION_CLASS +TP_TYPE_CHANNEL_DISPATCH_OPERATION +tp_channel_dispatch_operation_get_type +<SUBSECTION Private> +# leaving these undocumented as a step towards deprecating all _run_ methods +# (these ones have never been documented) +tp_cli_channel_dispatch_operation_run_claim +tp_cli_channel_dispatch_operation_run_handle_with +</SECTION> + +<SECTION> +<FILE>channel-request</FILE> +<INCLUDE>telepathy-glib/channel-request.h</INCLUDE> +<TITLE>channel-request</TITLE> +TpChannelRequest +TpChannelRequestClass +tp_channel_request_new +<SUBSECTION> +tp_cli_channel_request_callback_for_cancel +tp_cli_channel_request_call_cancel +tp_cli_channel_request_callback_for_proceed +tp_cli_channel_request_call_proceed +tp_cli_channel_request_signal_callback_failed +tp_cli_channel_request_connect_to_failed +tp_cli_channel_request_signal_callback_succeeded +tp_cli_channel_request_connect_to_succeeded +<SUBSECTION Standard> +TP_CHANNEL_REQUEST +TP_CHANNEL_REQUEST_CLASS +TP_CHANNEL_REQUEST_GET_CLASS +TP_IS_CHANNEL_REQUEST +TP_IS_CHANNEL_REQUEST_CLASS +TP_TYPE_CHANNEL_REQUEST +TpChannelRequestClassPrivate +TpChannelRequestPrivate +tp_channel_request_get_type +<SUBSECTION Private> +# leaving these undocumented as a step towards deprecating all _run_ methods +# (these ones have never been documented) +tp_cli_channel_request_run_cancel +tp_cli_channel_request_run_proceed +</SECTION> + +<SECTION> +<FILE>svc-channel-dispatch-operation</FILE> +<INCLUDE>telepathy-glib/svc-channel-dispatch-operation.h</INCLUDE> +<TITLE>svc-channel-dispatch-operation</TITLE> +TpSvcChannelDispatchOperation +TpSvcChannelDispatchOperationClass +tp_svc_channel_dispatch_operation_return_from_claim +tp_svc_channel_dispatch_operation_claim_impl +tp_svc_channel_dispatch_operation_implement_claim +tp_svc_channel_dispatch_operation_return_from_handle_with +tp_svc_channel_dispatch_operation_handle_with_impl +tp_svc_channel_dispatch_operation_implement_handle_with +tp_svc_channel_dispatch_operation_emit_channel_lost +tp_svc_channel_dispatch_operation_emit_finished +<SUBSECTION Standard> +tp_svc_channel_dispatch_operation_get_type +TP_IS_SVC_CHANNEL_DISPATCH_OPERATION +TP_SVC_CHANNEL_DISPATCH_OPERATION +TP_SVC_CHANNEL_DISPATCH_OPERATION_GET_CLASS +TP_TYPE_SVC_CHANNEL_DISPATCH_OPERATION +</SECTION> + +<SECTION> +<FILE>svc-channel-request</FILE> +<INCLUDE>telepathy-glib/svc-channel-request.h</INCLUDE> +<TITLE>svc-channel-request</TITLE> +TpSvcChannelRequest +TpSvcChannelRequestClass +tp_svc_channel_request_return_from_proceed +tp_svc_channel_request_proceed_impl +tp_svc_channel_request_implement_proceed +tp_svc_channel_request_return_from_cancel +tp_svc_channel_request_cancel_impl +tp_svc_channel_request_implement_cancel +tp_svc_channel_request_emit_failed +tp_svc_channel_request_emit_succeeded +<SUBSECTION Standard> +tp_svc_channel_request_get_type +TP_IS_SVC_CHANNEL_REQUEST +TP_SVC_CHANNEL_REQUEST +TP_SVC_CHANNEL_REQUEST_GET_CLASS +TP_TYPE_SVC_CHANNEL_REQUEST +</SECTION> diff --git a/docs/reference/telepathy-glib.types b/docs/reference/telepathy-glib.types index 47c532042..1a7171af5 100644 --- a/docs/reference/telepathy-glib.types +++ b/docs/reference/telepathy-glib.types @@ -5,8 +5,10 @@ #include <telepathy-glib/channel-factory-iface.h> #include <telepathy-glib/channel.h> #include <telepathy-glib/channel-dispatcher.h> +#include <telepathy-glib/channel-dispatch-operation.h> #include <telepathy-glib/channel-iface.h> #include <telepathy-glib/channel-manager.h> +#include <telepathy-glib/channel-request.h> #include <telepathy-glib/connection.h> #include <telepathy-glib/connection-manager.h> #include <telepathy-glib/contact.h> @@ -20,6 +22,8 @@ #include <telepathy-glib/svc-account-manager.h> #include <telepathy-glib/svc-channel.h> #include <telepathy-glib/svc-channel-dispatcher.h> +#include <telepathy-glib/svc-channel-dispatch-operation.h> +#include <telepathy-glib/svc-channel-request.h> #include <telepathy-glib/svc-connection.h> #include <telepathy-glib/svc-connection-manager.h> #include <telepathy-glib/svc-generic.h> @@ -33,8 +37,10 @@ tp_base_connection_manager_get_type tp_channel_factory_iface_get_type tp_channel_get_type tp_channel_dispatcher_get_type +tp_channel_dispatch_operation_get_type tp_channel_iface_get_type tp_channel_manager_get_type +tp_channel_request_get_type tp_connection_get_type tp_connection_manager_get_type tp_contact_get_type @@ -52,6 +58,7 @@ tp_svc_account_manager_get_type tp_svc_channel_get_type tp_svc_channel_dispatcher_get_type tp_svc_channel_dispatcher_interface_operation_list_get_type +tp_svc_channel_dispatch_operation_get_type tp_svc_channel_interface_call_state_get_type tp_svc_channel_interface_chat_state_get_type tp_svc_channel_interface_dtmf_get_type @@ -59,6 +66,7 @@ tp_svc_channel_interface_group_get_type tp_svc_channel_interface_hold_get_type tp_svc_channel_interface_media_signalling_get_type tp_svc_channel_interface_password_get_type +tp_svc_channel_request_get_type tp_svc_channel_type_contact_list_get_type tp_svc_channel_type_room_list_get_type tp_svc_channel_type_streamed_media_get_type diff --git a/spec/Channel_Dispatch_Operation.xml b/spec/Channel_Dispatch_Operation.xml index a44712c7a..82d73b5f1 100644 --- a/spec/Channel_Dispatch_Operation.xml +++ b/spec/Channel_Dispatch_Operation.xml @@ -21,8 +21,7 @@ MA 02110-1301, USA.</p> </tp:license> - <interface name="org.freedesktop.Telepathy.ChannelDispatchOperation" - tp:causes-havoc="not yet final"> + <interface name="org.freedesktop.Telepathy.ChannelDispatchOperation"> <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> <p>A channel dispatch operation is an object in the ChannelDispatcher diff --git a/spec/Channel_Request.xml b/spec/Channel_Request.xml index c69266ae7..bd429521f 100644 --- a/spec/Channel_Request.xml +++ b/spec/Channel_Request.xml @@ -21,8 +21,7 @@ MA 02110-1301, USA.</p> </tp:license> - <interface name="org.freedesktop.Telepathy.ChannelRequest" - tp:causes-havoc="not yet final"> + <interface name="org.freedesktop.Telepathy.ChannelRequest"> <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> <p>A channel request is an object in the ChannelDispatcher representing diff --git a/telepathy-glib/Makefile.am b/telepathy-glib/Makefile.am index 29fd8bae2..6f817c324 100644 --- a/telepathy-glib/Makefile.am +++ b/telepathy-glib/Makefile.am @@ -42,6 +42,9 @@ EXTRA_DIST = \ account.xml \ account-manager.xml \ channel.xml \ + channel-dispatcher.xml \ + channel-dispatch-operation.xml \ + channel-request.xml \ connection.xml \ connection-manager.xml \ dbus-daemon.xml \ @@ -123,8 +126,10 @@ tpginclude_HEADERS = \ channel.h \ channel-iface.h \ channel-dispatcher.h \ + channel-dispatch-operation.h \ channel-factory-iface.h \ channel-manager.h \ + channel-request.h \ connection.h \ connection-manager.h \ contact.h \ @@ -175,6 +180,8 @@ nodist_libtelepathy_glib_internal_la_SOURCES = \ _gen/tp-cli-account-manager-body.h \ _gen/tp-cli-channel-body.h \ _gen/tp-cli-channel-dispatcher-body.h \ + _gen/tp-cli-channel-dispatch-operation-body.h \ + _gen/tp-cli-channel-request-body.h \ _gen/tp-cli-connection-body.h \ _gen/tp-cli-connection-manager-body.h \ _gen/tp-cli-dbus-daemon-body.h \ @@ -185,6 +192,8 @@ nodist_libtelepathy_glib_internal_la_SOURCES = \ _gen/tp-svc-account-manager.c \ _gen/tp-svc-channel.c \ _gen/tp-svc-channel-dispatcher.c \ + _gen/tp-svc-channel-dispatch-operation.c \ + _gen/tp-svc-channel-request.c \ _gen/tp-svc-connection.c \ _gen/tp-svc-connection-manager.c \ _gen/tp-svc-generic.c \ @@ -200,6 +209,8 @@ nodist_geninclude_HEADERS = \ _gen/tp-cli-account-manager.h \ _gen/tp-cli-channel.h \ _gen/tp-cli-channel-dispatcher.h \ + _gen/tp-cli-channel-dispatch-operation.h \ + _gen/tp-cli-channel-request.h \ _gen/tp-cli-connection.h \ _gen/tp-cli-connection-manager.h \ _gen/tp-cli-dbus-daemon.h \ @@ -210,6 +221,8 @@ nodist_geninclude_HEADERS = \ _gen/tp-svc-account-manager.h \ _gen/tp-svc-channel.h \ _gen/tp-svc-channel-dispatcher.h \ + _gen/tp-svc-channel-dispatch-operation.h \ + _gen/tp-svc-channel-request.h \ _gen/tp-svc-connection.h \ _gen/tp-svc-connection-manager.h \ _gen/tp-svc-generic.h \ @@ -246,7 +259,9 @@ libtelepathy_glib_internal_la_SOURCES = \ channel-group.c \ channel-internal.h \ channel-dispatcher.c \ + channel-dispatch-operation.c \ channel-manager.c \ + channel-request.c \ connection.c \ connection-internal.h \ connection-handles.c \ @@ -405,6 +420,16 @@ _gen/tp-cli-%-body.h _gen/tp-cli-%.h: _gen/tp-spec-%.xml \ subclass_assert=--subclass-assert=TP_IS_CHANNEL_DISPATCHER; \ maybe_reentrant=--generate-reentrant; \ ;; \ + channel-dispatch-operation) \ + subclass=--subclass=TpChannelDispatchOperation; \ + subclass_assert=--subclass-assert=TP_IS_CHANNEL_DISPATCH_OPERATION; \ + maybe_reentrant=--generate-reentrant; \ + ;; \ + channel-request) \ + subclass=--subclass=TpChannelRequest; \ + subclass_assert=--subclass-assert=TP_IS_CHANNEL_REQUEST; \ + maybe_reentrant=--generate-reentrant; \ + ;; \ connection-manager) \ subclass=--subclass=TpConnectionManager; \ subclass_assert=--subclass-assert=TP_IS_CONNECTION_MANAGER \ diff --git a/telepathy-glib/channel-dispatch-operation.c b/telepathy-glib/channel-dispatch-operation.c new file mode 100644 index 000000000..f47a14c66 --- /dev/null +++ b/telepathy-glib/channel-dispatch-operation.c @@ -0,0 +1,223 @@ +/* + * channel-dispatch-operation.c - proxy for incoming channels seeking approval + * + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * Copyright (C) 2009 Nokia Corporation + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "telepathy-glib/channel-dispatch-operation.h" + +#include <telepathy-glib/defs.h> +#include <telepathy-glib/errors.h> +#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/proxy-subclass.h> + +#define DEBUG_FLAG TP_DEBUG_DISPATCHER +#include "telepathy-glib/dbus-internal.h" +#include "telepathy-glib/debug-internal.h" + +#include "telepathy-glib/_gen/tp-cli-channel-dispatch-operation-body.h" + +/** + * SECTION:channel-dispatch-operation + * @title: TpChannelDispatchOperation + * @short_description: proxy object for a to the Telepathy channel + * dispatcher + * @see_also: #TpChannelDispatcher + * + * One of the channel dispatcher's functions is to offer incoming channels to + * Approver clients for approval. Approvers respond to the channel dispatcher + * via a #TpChannelDispatchOperation object. + */ + +/** + * TpChannelDispatchOperation: + * + * One of the channel dispatcher's functions is to offer incoming channels to + * Approver clients for approval. An approver should generally ask the user + * whether they want to participate in the requested communication channels + * (join the chat or chatroom, answer the call, accept the file transfer, or + * whatever is appropriate). A collection of channels offered in this way + * is represented by a ChannelDispatchOperation object. + * + * If the user wishes to accept the communication channels, the approver + * should call tp_cli_channel_dispatch_operation_call_handle_with() to + * indicate the user's or approver's preferred handler for the channels (the + * empty string indicates no particular preference, and will cause any + * suitable handler to be used). + * + * If the user wishes to reject the communication channels, or if the user + * accepts the channels and the approver will handle them itself, the approver + * should call tp_cli_channel_dispatch_operation_call_claim(). If this method + * succeeds, the approver immediately has control over the channels as their + * primary handler, and may do anything with them (in particular, it may close + * them in whatever way seems most appropriate). + * + * There are various situations in which the channel dispatch operation will + * be closed, causing the #TpProxy::invalidated signal to be emitted. If this + * happens, the approver should stop prompting the user. + * + * Because all approvers are launched simultaneously, the user might respond + * to another approver; if this happens, the invalidated signal will be + * emitted with the domain %TP_DBUS_ERRORS and the error code + * %TP_DBUS_ERROR_OBJECT_REMOVED. + * + * If a channel closes, the D-Bus signal ChannelLost is emitted; this class + * doesn't (yet) have a GObject binding for this signal, but you can use + * tp_cli_channel_dispatch_operation_connect_to_channel_lost(). If all channels + * close, there is nothing more to dispatch, so the invalidated signal will be + * emitted with the domain %TP_DBUS_ERRORS and the error code + * %TP_DBUS_ERROR_OBJECT_REMOVED. + * + * If the channel dispatcher crashes or exits, the invalidated + * signal will be emitted with the domain %TP_DBUS_ERRORS and the error code + * %TP_DBUS_ERROR_NAME_OWNER_LOST. In a high-quality implementation, the + * dispatcher should be restarted, at which point it will create new + * channel dispatch operations for any undispatched channels, and the approver + * will be notified again. + * + * This proxy is usable but incomplete: accessors for the D-Bus properties will + * be added in a later version of telepathy-glib, along with a mechanism + * similar to tp_connection_call_when_ready(). + * + * Since: 0.7.UNRELEASED + */ + +/** + * TpChannelDispatchOperationClass: + * + * The class of a #TpChannelDispatchOperation. + */ + +struct _TpChannelDispatchOperationPrivate { + gpointer dummy; +}; + +G_DEFINE_TYPE (TpChannelDispatchOperation, tp_channel_dispatch_operation, + TP_TYPE_PROXY); + +static void +tp_channel_dispatch_operation_init (TpChannelDispatchOperation *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + TP_TYPE_CHANNEL_DISPATCH_OPERATION, TpChannelDispatchOperationPrivate); +} + +static void +tp_channel_dispatch_operation_finished_cb (TpChannelDispatchOperation *self, + gpointer unused G_GNUC_UNUSED, + GObject *object G_GNUC_UNUSED) +{ + GError e = { TP_DBUS_ERRORS, TP_DBUS_ERROR_OBJECT_REMOVED, + "ChannelDispatchOperation finished and was removed" }; + + tp_proxy_invalidate ((TpProxy *) self, &e); +} + +static void +tp_channel_dispatch_operation_constructed (GObject *object) +{ + TpChannelDispatchOperation *self = TP_CHANNEL_DISPATCH_OPERATION (object); + void (*chain_up) (GObject *) = + ((GObjectClass *) tp_channel_dispatch_operation_parent_class)->constructed; + GError *error = NULL; + TpProxySignalConnection *sc; + + if (chain_up != NULL) + chain_up (object); + + g_return_if_fail (tp_proxy_get_dbus_daemon (self) != NULL); + + sc = tp_cli_channel_dispatch_operation_connect_to_finished (self, + tp_channel_dispatch_operation_finished_cb, NULL, NULL, NULL, &error); + + if (sc == NULL) + { + g_critical ("Couldn't connect to Finished: %s", error->message); + g_error_free (error); + g_assert_not_reached (); + return; + } +} + +static void +tp_channel_dispatch_operation_class_init (TpChannelDispatchOperationClass *klass) +{ + GType tp_type = TP_TYPE_CHANNEL_DISPATCH_OPERATION; + TpProxyClass *proxy_class = (TpProxyClass *) klass; + GObjectClass *object_class = (GObjectClass *) klass; + + g_type_class_add_private (klass, sizeof (TpChannelDispatchOperationPrivate)); + + object_class->constructed = tp_channel_dispatch_operation_constructed; + + proxy_class->interface = TP_IFACE_QUARK_CHANNEL_DISPATCH_OPERATION; + tp_proxy_or_subclass_hook_on_interface_add (tp_type, + tp_cli_channel_dispatch_operation_add_signals); + tp_proxy_subclass_add_error_mapping (tp_type, + TP_ERROR_PREFIX, TP_ERRORS, TP_TYPE_ERROR); + proxy_class->must_have_unique_name = TRUE; +} + +/** + * tp_channel_dispatch_operation_new: + * @bus_daemon: Proxy for the D-Bus daemon + * @object_path: The non-NULL object path of this channel dispatch operation + * @immutable_properties: As many as are known of the immutable D-Bus + * properties of this channel dispatch operation, or %NULL if none are known + * @error: Used to raise an error if %NULL is returned + * + * Convenience function to create a new channel dispatch operation proxy. + * + * The @immutable_properties argument is not yet used. + * + * Returns: a new reference to an channel dispatch operation proxy, or %NULL if + * @object_path is not syntactically valid or the channel dispatcher is not + * running + */ +TpChannelDispatchOperation * +tp_channel_dispatch_operation_new (TpDBusDaemon *bus_daemon, + const gchar *object_path, + GHashTable *immutable_properties G_GNUC_UNUSED, + GError **error) +{ + TpChannelDispatchOperation *self; + gchar *unique_name; + + g_return_val_if_fail (bus_daemon != NULL, NULL); + g_return_val_if_fail (object_path != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!tp_dbus_check_valid_object_path (object_path, error)) + return NULL; + + if (!_tp_dbus_daemon_get_name_owner (bus_daemon, -1, + TP_CHANNEL_DISPATCHER_BUS_NAME, &unique_name, error)) + return NULL; + + self = TP_CHANNEL_DISPATCH_OPERATION (g_object_new ( + TP_TYPE_CHANNEL_DISPATCH_OPERATION, + "dbus-daemon", bus_daemon, + "dbus-connection", ((TpProxy *) bus_daemon)->dbus_connection, + "bus-name", unique_name, + "object-path", object_path, + NULL)); + + g_free (unique_name); + + return self; +} diff --git a/telepathy-glib/channel-dispatch-operation.h b/telepathy-glib/channel-dispatch-operation.h new file mode 100644 index 000000000..aaa5085cb --- /dev/null +++ b/telepathy-glib/channel-dispatch-operation.h @@ -0,0 +1,78 @@ +/* + * channel-dispatch-operation.h - proxy for channels awaiting approval + * + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * Copyright (C) 2009 Nokia Corporation + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef TP_CHANNEL_DISPATCH_OPERATION_H +#define TP_CHANNEL_DISPATCH_OPERATION_H + +#include <telepathy-glib/proxy.h> +#include <telepathy-glib/dbus.h> + +G_BEGIN_DECLS + +typedef struct _TpChannelDispatchOperation + TpChannelDispatchOperation; +typedef struct _TpChannelDispatchOperationClass + TpChannelDispatchOperationClass; +typedef struct _TpChannelDispatchOperationPrivate + TpChannelDispatchOperationPrivate; +typedef struct _TpChannelDispatchOperationClassPrivate + TpChannelDispatchOperationClassPrivate; + +struct _TpChannelDispatchOperation { + /*<private>*/ + TpProxy parent; + TpChannelDispatchOperationPrivate *priv; +}; + +struct _TpChannelDispatchOperationClass { + /*<private>*/ + TpProxyClass parent_class; + GCallback _padding[7]; + TpChannelDispatchOperationClassPrivate *priv; +}; + +GType tp_channel_dispatch_operation_get_type (void); + +#define TP_TYPE_CHANNEL_DISPATCH_OPERATION \ + (tp_channel_dispatch_operation_get_type ()) +#define TP_CHANNEL_DISPATCH_OPERATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TYPE_CHANNEL_DISPATCH_OPERATION, \ + TpChannelDispatchOperation)) +#define TP_CHANNEL_DISPATCH_OPERATION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TYPE_CHANNEL_DISPATCH_OPERATION, \ + TpChannelDispatchOperationClass)) +#define TP_IS_CHANNEL_DISPATCH_OPERATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TYPE_CHANNEL_DISPATCH_OPERATION)) +#define TP_IS_CHANNEL_DISPATCH_OPERATION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TYPE_CHANNEL_DISPATCH_OPERATION)) +#define TP_CHANNEL_DISPATCH_OPERATION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_CHANNEL_DISPATCH_OPERATION, \ + TpChannelDispatchOperationClass)) + +TpChannelDispatchOperation *tp_channel_dispatch_operation_new ( + TpDBusDaemon *bus_daemon, const gchar *object_path, + GHashTable *immutable_properties, GError **error); + +G_END_DECLS + +#include <telepathy-glib/_gen/tp-cli-channel-dispatch-operation.h> + +#endif diff --git a/telepathy-glib/channel-dispatch-operation.xml b/telepathy-glib/channel-dispatch-operation.xml new file mode 100644 index 000000000..a870d4dcd --- /dev/null +++ b/telepathy-glib/channel-dispatch-operation.xml @@ -0,0 +1,9 @@ +<tp:spec + xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" + xmlns:xi="http://www.w3.org/2001/XInclude"> + +<tp:title>CDO interfaces</tp:title> + +<xi:include href="../spec/Channel_Dispatch_Operation.xml"/> + +</tp:spec> diff --git a/telepathy-glib/channel-request.c b/telepathy-glib/channel-request.c new file mode 100644 index 000000000..45ad9694b --- /dev/null +++ b/telepathy-glib/channel-request.c @@ -0,0 +1,250 @@ +/* + * channel-request.c - proxy for a request to the Telepathy channel dispatcher + * + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * Copyright (C) 2009 Nokia Corporation + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "telepathy-glib/channel-request.h" + +#include <telepathy-glib/defs.h> +#include <telepathy-glib/errors.h> +#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/proxy-subclass.h> + +#define DEBUG_FLAG TP_DEBUG_DISPATCHER +#include "telepathy-glib/dbus-internal.h" +#include "telepathy-glib/debug-internal.h" + +#include "telepathy-glib/_gen/tp-cli-channel-request-body.h" + +/** + * SECTION:channel-request + * @title: TpChannelRequest + * @short_description: proxy object for a request to the Telepathy channel + * dispatcher + * @see_also: #TpChannelDispatcher + * + * Requesting a channel from the channel dispatcher can take some time, so an + * object is created in the channel dispatcher to represent each request. + * Objects of the #TpChannelRequest class provide access to one of those + * objects. + */ + +/** + * TpChannelRequest: + * + * Requesting a channel from the channel dispatcher can take some time, so an + * object is created in the channel dispatcher to represent each request. This + * proxy represents one of those objects. + * + * Any client can call tp_cli_channel_request_call_cancel() at any time to + * attempt to cancel the request. + * + * On success, the #TpChannelRequest::succeeded signal will be emitted. + * Immediately after that, the #TpProxy::invalidated signal will be emitted, + * with the domain %TP_DBUS_ERRORS and the error code + * %TP_DBUS_ERROR_OBJECT_REMOVED (this is not an error condition, it merely + * indicates that the channel request no longer exists). + * + * On failure, the #TpProxy::invalidated signal will be emitted with some + * other suitable error, usually from the %TP_ERRORS domain. + * + * If the channel dispatcher crashes or exits, the #TpProxy::invalidated + * signal will be emitted with the domain %TP_DBUS_ERRORS and the error code + * %TP_DBUS_ERROR_NAME_OWNER_LOST. + * + * This proxy is usable but incomplete: accessors for the Account, + * UserActionTime, PreferredHandler, Requests and Interfaces properties will + * be added in a later version of telepathy-glib, along with a mechanism + * similar to tp_connection_call_when_ready(). + * + * Until suitable convenience methods are implemented, the generic + * tp_cli_dbus_properties_call_get_all() method can be used to get those + * properties. + * + * Since: 0.7.UNRELEASED + */ + +/** + * TpChannelRequestClass: + * + * The class of a #TpChannelRequest. + */ + +static guint signal_id_succeeded = 0; + +struct _TpChannelRequestPrivate { + gpointer dummy; +}; + +G_DEFINE_TYPE (TpChannelRequest, tp_channel_request, TP_TYPE_PROXY); + +static void +tp_channel_request_init (TpChannelRequest *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TYPE_CHANNEL_REQUEST, + TpChannelRequestPrivate); +} + +static void +tp_channel_request_failed_cb (TpChannelRequest *self, + const gchar *error_name, + const gchar *message, + gpointer unused G_GNUC_UNUSED, + GObject *object G_GNUC_UNUSED) +{ + GError *error = NULL; + + tp_proxy_dbus_error_to_gerror (self, error_name, message, &error); + tp_proxy_invalidate ((TpProxy *) self, error); + g_error_free (error); +} + +static void +tp_channel_request_succeeded_cb (TpChannelRequest *self, + gpointer unused G_GNUC_UNUSED, + GObject *object G_GNUC_UNUSED) +{ + GError e = { TP_DBUS_ERRORS, TP_DBUS_ERROR_OBJECT_REMOVED, + "ChannelRequest succeeded and was removed" }; + + g_signal_emit (self, signal_id_succeeded, 0); + tp_proxy_invalidate ((TpProxy *) self, &e); +} + +static void +tp_channel_request_constructed (GObject *object) +{ + TpChannelRequest *self = TP_CHANNEL_REQUEST (object); + void (*chain_up) (GObject *) = + ((GObjectClass *) tp_channel_request_parent_class)->constructed; + GError *error = NULL; + TpProxySignalConnection *sc; + + if (chain_up != NULL) + chain_up (object); + + g_return_if_fail (tp_proxy_get_dbus_daemon (self) != NULL); + + sc = tp_cli_channel_request_connect_to_failed (self, + tp_channel_request_failed_cb, NULL, NULL, NULL, &error); + + if (sc == NULL) + { + g_critical ("Couldn't connect to Failed: %s", error->message); + g_error_free (error); + g_assert_not_reached (); + return; + } + + sc = tp_cli_channel_request_connect_to_succeeded (self, + tp_channel_request_succeeded_cb, NULL, NULL, NULL, &error); + + if (sc == NULL) + { + g_critical ("Couldn't connect to Succeeded: %s", error->message); + g_error_free (error); + g_assert_not_reached (); + return; + } +} + +static void +tp_channel_request_class_init (TpChannelRequestClass *klass) +{ + GType tp_type = TP_TYPE_CHANNEL_REQUEST; + TpProxyClass *proxy_class = (TpProxyClass *) klass; + GObjectClass *object_class = (GObjectClass *) klass; + + g_type_class_add_private (klass, sizeof (TpChannelRequestPrivate)); + + object_class->constructed = tp_channel_request_constructed; + + proxy_class->interface = TP_IFACE_QUARK_CHANNEL_REQUEST; + tp_proxy_or_subclass_hook_on_interface_add (tp_type, + tp_cli_channel_request_add_signals); + tp_proxy_subclass_add_error_mapping (tp_type, + TP_ERROR_PREFIX, TP_ERRORS, TP_TYPE_ERROR); + proxy_class->must_have_unique_name = TRUE; + + /** + * TpChannelRequest::succeeded: + * @self: the channel request proxy + * + * Emitted when the channel request succeeds. + */ + signal_id_succeeded = g_signal_new ("succeeded", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/** + * tp_channel_request_new: + * @bus_daemon: Proxy for the D-Bus daemon + * @object_path: The non-NULL object path of this channel request + * @immutable_properties: As many as are known of the immutable D-Bus + * properties of this channel request, or %NULL if none are known + * @error: Used to raise an error if %NULL is returned + * + * Convenience function to create a new channel request proxy. + * + * If the channel request was newly created, the client making the request + * is responsible for calling tp_cli_channel_request_call_proceed() when it + * is ready for the channel request to proceed. + * + * The @immutable_properties argument is not yet used. + * + * Returns: a new reference to an channel request proxy, or %NULL if + * @object_path is not syntactically valid or the channel dispatcher is + * not running + */ +TpChannelRequest * +tp_channel_request_new (TpDBusDaemon *bus_daemon, + const gchar *object_path, + GHashTable *immutable_properties G_GNUC_UNUSED, + GError **error) +{ + TpChannelRequest *self; + gchar *unique_name; + + g_return_val_if_fail (bus_daemon != NULL, NULL); + g_return_val_if_fail (object_path != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!tp_dbus_check_valid_object_path (object_path, error)) + return NULL; + + if (!_tp_dbus_daemon_get_name_owner (bus_daemon, -1, + TP_CHANNEL_DISPATCHER_BUS_NAME, &unique_name, error)) + return NULL; + + self = TP_CHANNEL_REQUEST (g_object_new (TP_TYPE_CHANNEL_REQUEST, + "dbus-daemon", bus_daemon, + "dbus-connection", ((TpProxy *) bus_daemon)->dbus_connection, + "bus-name", unique_name, + "object-path", object_path, + NULL)); + + g_free (unique_name); + + return self; +} diff --git a/telepathy-glib/channel-request.h b/telepathy-glib/channel-request.h new file mode 100644 index 000000000..50c9ce751 --- /dev/null +++ b/telepathy-glib/channel-request.h @@ -0,0 +1,74 @@ +/* + * channel-request.h - proxy for a request to the channel dispatcher + * + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * Copyright (C) 2009 Nokia Corporation + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef TP_CHANNEL_REQUEST_H +#define TP_CHANNEL_REQUEST_H + +#include <telepathy-glib/proxy.h> +#include <telepathy-glib/dbus.h> + +G_BEGIN_DECLS + +typedef struct _TpChannelRequest TpChannelRequest; +typedef struct _TpChannelRequestClass TpChannelRequestClass; +typedef struct _TpChannelRequestPrivate TpChannelRequestPrivate; +typedef struct _TpChannelRequestClassPrivate TpChannelRequestClassPrivate; + +struct _TpChannelRequest { + /*<private>*/ + TpProxy parent; + TpChannelRequestPrivate *priv; +}; + +struct _TpChannelRequestClass { + /*<private>*/ + TpProxyClass parent_class; + GCallback _padding[7]; + TpChannelRequestClassPrivate *priv; +}; + +GType tp_channel_request_get_type (void); + +#define TP_TYPE_CHANNEL_REQUEST \ + (tp_channel_request_get_type ()) +#define TP_CHANNEL_REQUEST(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TYPE_CHANNEL_REQUEST, \ + TpChannelRequest)) +#define TP_CHANNEL_REQUEST_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TYPE_CHANNEL_REQUEST, \ + TpChannelRequestClass)) +#define TP_IS_CHANNEL_REQUEST(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TYPE_CHANNEL_REQUEST)) +#define TP_IS_CHANNEL_REQUEST_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TYPE_CHANNEL_REQUEST)) +#define TP_CHANNEL_REQUEST_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_CHANNEL_REQUEST, \ + TpChannelRequestClass)) + +TpChannelRequest *tp_channel_request_new (TpDBusDaemon *bus_daemon, + const gchar *object_path, GHashTable *immutable_properties, + GError **error); + +G_END_DECLS + +#include <telepathy-glib/_gen/tp-cli-channel-request.h> + +#endif diff --git a/telepathy-glib/channel-request.xml b/telepathy-glib/channel-request.xml new file mode 100644 index 000000000..2b4068c0b --- /dev/null +++ b/telepathy-glib/channel-request.xml @@ -0,0 +1,9 @@ +<tp:spec + xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" + xmlns:xi="http://www.w3.org/2001/XInclude"> + +<tp:title>CR interfaces</tp:title> + +<xi:include href="../spec/Channel_Request.xml"/> + +</tp:spec> diff --git a/telepathy-glib/extra-gtkdoc.h b/telepathy-glib/extra-gtkdoc.h index 26d289c5a..5ecff48ca 100644 --- a/telepathy-glib/extra-gtkdoc.h +++ b/telepathy-glib/extra-gtkdoc.h @@ -244,6 +244,51 @@ */ /** + * SECTION:svc-channel-dispatch-operation + * @title: Service-side Channel Dispatch Operation interface + * @short_description: GInterface for Telepathy ChannelDispatchOperation object + * + * This interface (auto-generated from the Telepathy + * spec) makes it easier to export an object implementing the Telepathy + * ChannelDispatchOperation interface, with the correct method and signal + * signatures, and emit signals from that object in a type-safe way. + * + * You don't need these interfaces unless you're implementing a + * Telepathy ChannelDispatcher, such as Mission Control. + */ + +/** + * SECTION:svc-channel-request + * @title: Service-side Channel Request interface + * @short_description: GInterface for Telepathy ChannelRequest object + * + * This interface (auto-generated from the Telepathy + * spec) makes it easier to export an object implementing the Telepathy + * ChannelRequest interface, with the correct method and signal + * signatures, and emit signals from that object in a type-safe way. + * + * You don't need these interfaces unless you're implementing a + * Telepathy ChannelDispatcher, such as Mission Control. + */ + +/** + * SECTION:svc-channel-dispatcher + * @title: Service-side Channel Dispatcher interface + * @short_description: GInterfaces for Telepathy ChannelDispatcher object + * + * The #TpSvcChannelDispatcher interface (auto-generated from the Telepathy + * spec) makes it easier to export an object implementing the Telepathy + * ChannelDispatcher interface, with the correct method and signal signatures, + * and emit signals from that object in a type-safe way. + * + * Similarly, #TpSvcChannelDispatcherInterfaceOperationList helps to + * implement the optional OperationList interface. + * + * You don't need these interfaces unless you're implementing a + * Telepathy ChannelDispatcher, such as Mission Control. + */ + +/** * SECTION:svc-media-interfaces * @title: Service-side media streaming helper interfaces * @short_description: media session and media stream diff --git a/telepathy-glib/stable-interfaces.xml b/telepathy-glib/stable-interfaces.xml index 1f710ab43..d3a2c16b3 100644 --- a/telepathy-glib/stable-interfaces.xml +++ b/telepathy-glib/stable-interfaces.xml @@ -16,6 +16,8 @@ <xi:include href="account.xml"/> <xi:include href="channel-dispatcher.xml"/> +<xi:include href="channel-dispatch-operation.xml"/> +<xi:include href="channel-request.xml"/> <xi:include href="../spec/generic-types.xml"/> <xi:include href="../spec/errors.xml"/> diff --git a/telepathy-glib/svc-channel-dispatch-operation.h b/telepathy-glib/svc-channel-dispatch-operation.h new file mode 100644 index 000000000..ae74c5435 --- /dev/null +++ b/telepathy-glib/svc-channel-dispatch-operation.h @@ -0,0 +1,6 @@ +#ifndef __TP_META_SVC_CHANNEL_DISPATCH_OPERATION_H__ +#define __TP_META_SVC_CHANNEL_DISPATCH_OPERATION_H__ + +#include <telepathy-glib/_gen/tp-svc-channel-dispatch-operation.h> + +#endif diff --git a/telepathy-glib/svc-channel-request.h b/telepathy-glib/svc-channel-request.h new file mode 100644 index 000000000..f849a8239 --- /dev/null +++ b/telepathy-glib/svc-channel-request.h @@ -0,0 +1,6 @@ +#ifndef __TP_META_SVC_CHANNEL_REQUEST_H__ +#define __TP_META_SVC_CHANNEL_REQUEST_H__ + +#include <telepathy-glib/_gen/tp-svc-channel-request.h> + +#endif diff --git a/tests/dbus/Makefile.am b/tests/dbus/Makefile.am index 7a1b1f898..073ad3554 100644 --- a/tests/dbus/Makefile.am +++ b/tests/dbus/Makefile.am @@ -6,7 +6,9 @@ noinst_PROGRAMS = \ test-call-cancellation \ test-callable-example \ test-channel-dispatcher \ + test-channel-dispatch-operation \ test-channel-introspect \ + test-channel-request \ test-cli-group \ test-cm \ test-connection \ @@ -50,8 +52,12 @@ test_call_cancellation_SOURCES = call-cancellation.c test_channel_dispatcher_SOURCES = channel-dispatcher.c +test_channel_dispatch_operation_SOURCES = channel-dispatch-operation.c + test_channel_introspect_SOURCES = channel-introspect.c +test_channel_request_SOURCES = channel-request.c + test_callable_example_SOURCES = callable-example.c test_callable_example_LDADD = \ $(LDADD) \ diff --git a/tests/dbus/channel-dispatch-operation.c b/tests/dbus/channel-dispatch-operation.c new file mode 100644 index 000000000..84c57f6c3 --- /dev/null +++ b/tests/dbus/channel-dispatch-operation.c @@ -0,0 +1,232 @@ +/* A very basic feature test for TpChannelDispatchOperation + * + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * Copyright (C) 2009 Nokia Corporation + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. + */ + +#include <telepathy-glib/channel-dispatch-operation.h> +#include <telepathy-glib/defs.h> +#include <telepathy-glib/debug.h> +#include <telepathy-glib/svc-channel-dispatch-operation.h> + +#include <dbus/dbus.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include "tests/lib/util.h" + +/* This object implements no methods and no properties - TpChannelRequest + * doesn't actually use them yet */ + +static GType test_simple_cdo_get_type (void); + +typedef struct { + GObject parent; +} TestSimpleCDO; + +typedef struct { + GObjectClass parent; +} TestSimpleCDOClass; + +G_DEFINE_TYPE_WITH_CODE (TestSimpleCDO, test_simple_cdo, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_DISPATCH_OPERATION, NULL)); + +static void +test_simple_cdo_init (TestSimpleCDO *self) +{ +} + +static void +test_simple_cdo_class_init (TestSimpleCDOClass *klass) +{ +} + +typedef struct { + GMainLoop *mainloop; + TpDBusDaemon *dbus; + + DBusGConnection *private_conn; + TpDBusDaemon *private_dbus; + GObject *cdo_service; + + TpChannelDispatchOperation *cdo; + GError *error /* initialized where needed */; +} Test; + +static void +setup (Test *test, + gconstpointer data) +{ + DBusConnection *libdbus; + + g_type_init (); + tp_debug_set_flags ("all"); + + test->mainloop = g_main_loop_new (NULL, FALSE); + test->dbus = tp_dbus_daemon_dup (NULL); + g_assert (test->dbus != NULL); + + libdbus = dbus_bus_get_private (DBUS_BUS_STARTER, NULL); + g_assert (libdbus != NULL); + dbus_connection_setup_with_g_main (libdbus, NULL); + dbus_connection_set_exit_on_disconnect (libdbus, FALSE); + test->private_conn = dbus_connection_get_g_connection (libdbus); + /* transfer ref */ + dbus_g_connection_ref (test->private_conn); + dbus_connection_unref (libdbus); + g_assert (test->private_conn != NULL); + test->private_dbus = tp_dbus_daemon_new (test->private_conn); + g_assert (test->private_dbus != NULL); + + test->cdo = NULL; + + test->cdo_service = g_object_new (test_simple_cdo_get_type (), + NULL); + dbus_g_connection_register_g_object (test->private_conn, "/whatever", + test->cdo_service); +} + +static void +teardown (Test *test, + gconstpointer data) +{ + if (test->cdo != NULL) + { + g_object_unref (test->cdo); + test->cdo = NULL; + } + + tp_dbus_daemon_release_name (test->dbus, TP_CHANNEL_DISPATCHER_BUS_NAME, + NULL); + + if (test->private_dbus != NULL) + { + tp_dbus_daemon_release_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, NULL); + + g_object_unref (test->private_dbus); + test->private_dbus = NULL; + } + +#if 0 + /* not leaking this object would crash dbus-glib (fd.o #5688) */ + g_object_unref (test->cdo_service); + test->cdo_service = NULL; +#endif + + if (test->private_conn != NULL) + { + dbus_connection_close (dbus_g_connection_get_connection ( + test->private_conn)); + + dbus_g_connection_unref (test->private_conn); + test->private_conn = NULL; + } + + g_object_unref (test->dbus); + test->dbus = NULL; + g_main_loop_unref (test->mainloop); + test->mainloop = NULL; +} + +static void +test_new (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + gboolean ok; + + /* CD not running */ + test->cdo = tp_channel_dispatch_operation_new (test->dbus, + "/whatever", NULL, NULL); + g_assert (test->cdo == NULL); + + ok = tp_dbus_daemon_request_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL); + g_assert (ok); + + test->cdo = tp_channel_dispatch_operation_new (test->dbus, + "not even syntactically valid", NULL, NULL); + g_assert (test->cdo == NULL); + + test->cdo = tp_channel_dispatch_operation_new (test->dbus, + "/whatever", NULL, NULL); + g_assert (test->cdo != NULL); +} + +static void +test_crash (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + gboolean ok; + + ok = tp_dbus_daemon_request_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL); + g_assert (ok); + + test->cdo = tp_channel_dispatch_operation_new (test->dbus, "/whatever", + NULL, NULL); + g_assert (test->cdo != NULL); + g_assert (tp_proxy_get_invalidated (test->cdo) == NULL); + + tp_dbus_daemon_release_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, NULL); + + test_proxy_run_until_dbus_queue_processed (test->cdo); + + g_assert (tp_proxy_get_invalidated (test->cdo) == NULL); + + dbus_connection_close (dbus_g_connection_get_connection ( + test->private_conn)); + dbus_g_connection_unref (test->private_conn); + test->private_conn = NULL; + + test_proxy_run_until_dbus_queue_processed (test->cdo); + + g_assert (tp_proxy_get_invalidated (test->cdo) != NULL); + g_assert (tp_proxy_get_invalidated (test->cdo)->domain == TP_DBUS_ERRORS); + g_assert (tp_proxy_get_invalidated (test->cdo)->code == + TP_DBUS_ERROR_NAME_OWNER_LOST); +} + +static void +test_finished (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + gboolean ok; + + ok = tp_dbus_daemon_request_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL); + g_assert (ok); + + test->cdo = tp_channel_dispatch_operation_new (test->dbus, "/whatever", + NULL, NULL); + g_assert (test->cdo != NULL); + g_assert (tp_proxy_get_invalidated (test->cdo) == NULL); + + tp_svc_channel_dispatch_operation_emit_finished (test->cdo_service); + + test_proxy_run_until_dbus_queue_processed (test->cdo); + + g_assert (tp_proxy_get_invalidated (test->cdo) != NULL); + g_assert (tp_proxy_get_invalidated (test->cdo)->domain == TP_DBUS_ERRORS); + g_assert (tp_proxy_get_invalidated (test->cdo)->code == + TP_DBUS_ERROR_OBJECT_REMOVED); +} + +int +main (int argc, + char **argv) +{ + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id="); + + g_test_add ("/cdo/new", Test, NULL, setup, test_new, teardown); + g_test_add ("/cdo/crash", Test, NULL, setup, test_crash, teardown); + g_test_add ("/cdo/finished", Test, NULL, setup, test_finished, teardown); + + return g_test_run (); +} diff --git a/tests/dbus/channel-request.c b/tests/dbus/channel-request.c new file mode 100644 index 000000000..1699997ba --- /dev/null +++ b/tests/dbus/channel-request.c @@ -0,0 +1,276 @@ +/* A very basic feature test for TpChannelRequest + * + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * Copyright (C) 2009 Nokia Corporation + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. + */ + +#include <telepathy-glib/channel-request.h> +#include <telepathy-glib/defs.h> +#include <telepathy-glib/debug.h> +#include <telepathy-glib/svc-channel-request.h> + +#include <dbus/dbus.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include "tests/lib/util.h" + +/* This object implements no methods and no properties - TpChannelRequest + * doesn't actually use them yet */ + +static GType test_simple_cr_get_type (void); + +typedef struct { + GObject parent; +} TestSimpleCR; + +typedef struct { + GObjectClass parent; +} TestSimpleCRClass; + +G_DEFINE_TYPE_WITH_CODE (TestSimpleCR, test_simple_cr, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_REQUEST, NULL)); + +static void +test_simple_cr_init (TestSimpleCR *self) +{ +} + +static void +test_simple_cr_class_init (TestSimpleCRClass *klass) +{ +} + +typedef struct { + GMainLoop *mainloop; + TpDBusDaemon *dbus; + + DBusGConnection *private_conn; + TpDBusDaemon *private_dbus; + GObject *cr_service; + + TpChannelRequest *cr; + GError *error /* initialized where needed */; + + guint succeeded; +} Test; + +static void +setup (Test *test, + gconstpointer data) +{ + DBusConnection *libdbus; + + g_type_init (); + tp_debug_set_flags ("all"); + + test->mainloop = g_main_loop_new (NULL, FALSE); + test->dbus = tp_dbus_daemon_dup (NULL); + g_assert (test->dbus != NULL); + + libdbus = dbus_bus_get_private (DBUS_BUS_STARTER, NULL); + g_assert (libdbus != NULL); + dbus_connection_setup_with_g_main (libdbus, NULL); + dbus_connection_set_exit_on_disconnect (libdbus, FALSE); + test->private_conn = dbus_connection_get_g_connection (libdbus); + /* transfer ref */ + dbus_g_connection_ref (test->private_conn); + dbus_connection_unref (libdbus); + g_assert (test->private_conn != NULL); + test->private_dbus = tp_dbus_daemon_new (test->private_conn); + g_assert (test->private_dbus != NULL); + + test->cr = NULL; + + test->cr_service = g_object_new (test_simple_cr_get_type (), + NULL); + dbus_g_connection_register_g_object (test->private_conn, "/whatever", + test->cr_service); +} + +static void +teardown (Test *test, + gconstpointer data) +{ + if (test->cr != NULL) + { + g_object_unref (test->cr); + test->cr = NULL; + } + + if (test->private_dbus != NULL) + { + tp_dbus_daemon_release_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, NULL); + + g_object_unref (test->private_dbus); + test->private_dbus = NULL; + } + +#if 0 + /* not leaking this object would crash dbus-glib (fd.o #5688) */ + g_object_unref (test->cr_service); + test->cr_service = NULL; +#endif + + if (test->private_conn != NULL) + { + dbus_connection_close (dbus_g_connection_get_connection ( + test->private_conn)); + + dbus_g_connection_unref (test->private_conn); + test->private_conn = NULL; + } + + g_object_unref (test->dbus); + test->dbus = NULL; + + g_main_loop_unref (test->mainloop); + test->mainloop = NULL; +} + +static void +test_new (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + gboolean ok; + + /* CD not running */ + test->cr = tp_channel_request_new (test->dbus, + "/whatever", NULL, NULL); + g_assert (test->cr == NULL); + + ok = tp_dbus_daemon_request_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL); + g_assert (ok); + + test->cr = tp_channel_request_new (test->dbus, + "not even syntactically valid", NULL, NULL); + g_assert (test->cr == NULL); + + test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL); + g_assert (test->cr != NULL); +} + +static void +test_crash (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + gboolean ok; + + ok = tp_dbus_daemon_request_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL); + g_assert (ok); + + test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL); + g_assert (test->cr != NULL); + g_assert (tp_proxy_get_invalidated (test->cr) == NULL); + + tp_dbus_daemon_release_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, NULL); + + test_proxy_run_until_dbus_queue_processed (test->cr); + + g_assert (tp_proxy_get_invalidated (test->cr) == NULL); + + dbus_connection_close (dbus_g_connection_get_connection ( + test->private_conn)); + dbus_g_connection_unref (test->private_conn); + test->private_conn = NULL; + + test_proxy_run_until_dbus_queue_processed (test->cr); + + g_assert (tp_proxy_get_invalidated (test->cr) != NULL); + g_assert (tp_proxy_get_invalidated (test->cr)->domain == TP_DBUS_ERRORS); + g_assert (tp_proxy_get_invalidated (test->cr)->code == + TP_DBUS_ERROR_NAME_OWNER_LOST); +} + +static void +succeeded_cb (Test *test) +{ + test->succeeded++; +} + +static void +test_succeeded (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + gboolean ok; + + ok = tp_dbus_daemon_request_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL); + g_assert (ok); + + test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL); + g_assert (test->cr != NULL); + g_assert (tp_proxy_get_invalidated (test->cr) == NULL); + + g_signal_connect_swapped (test->cr, "succeeded", G_CALLBACK (succeeded_cb), + test); + + tp_svc_channel_request_emit_succeeded (test->cr_service); + + test_proxy_run_until_dbus_queue_processed (test->cr); + + g_assert (tp_proxy_get_invalidated (test->cr) != NULL); + g_assert (tp_proxy_get_invalidated (test->cr)->domain == TP_DBUS_ERRORS); + g_assert (tp_proxy_get_invalidated (test->cr)->code == + TP_DBUS_ERROR_OBJECT_REMOVED); + g_assert_cmpuint (test->succeeded, ==, 1); + + g_signal_handlers_disconnect_by_func (test->cr, G_CALLBACK (succeeded_cb), + test); +} + +static void +test_failed (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + gboolean ok; + + ok = tp_dbus_daemon_request_name (test->private_dbus, + TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL); + g_assert (ok); + + test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL); + g_assert (test->cr != NULL); + g_assert (tp_proxy_get_invalidated (test->cr) == NULL); + + g_signal_connect_swapped (test->cr, "succeeded", G_CALLBACK (succeeded_cb), + test); + + tp_svc_channel_request_emit_failed (test->cr_service, + TP_ERROR_STR_NOT_YOURS, "lalala"); + + test_proxy_run_until_dbus_queue_processed (test->cr); + + g_assert (tp_proxy_get_invalidated (test->cr) != NULL); + g_assert (tp_proxy_get_invalidated (test->cr)->domain == TP_ERRORS); + g_assert (tp_proxy_get_invalidated (test->cr)->code == TP_ERROR_NOT_YOURS); + g_assert_cmpstr (tp_proxy_get_invalidated (test->cr)->message, ==, + "lalala"); + g_assert_cmpuint (test->succeeded, ==, 0); + + g_signal_handlers_disconnect_by_func (test->cr, G_CALLBACK (succeeded_cb), + test); +} + +int +main (int argc, + char **argv) +{ + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id="); + + g_test_add ("/cr/new", Test, NULL, setup, test_new, teardown); + g_test_add ("/cr/crash", Test, NULL, setup, test_crash, teardown); + g_test_add ("/cr/succeeded", Test, NULL, setup, test_succeeded, teardown); + g_test_add ("/cr/failed", Test, NULL, setup, test_failed, teardown); + + return g_test_run (); +} |