summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@gmail.com>2011-11-18 10:13:01 +0100
committerXavier Claessens <xavier.claessens@collabora.co.uk>2012-01-10 09:52:44 +0100
commitcdd6f92b95dc9e94b1827c45fdf08da2fff75147 (patch)
tree77adfbc2152882ed75d0b0bf2a0c5b23e04c6e57 /examples
parent7195abaa3a49bd679f8898523fc9e653e24b6a45 (diff)
downloadtelepathy-glib-cdd6f92b95dc9e94b1827c45fdf08da2fff75147.tar.gz
Port example call CM to TpBaseCall*
Diffstat (limited to 'examples')
-rw-r--r--examples/future/call-cm/call-channel.c891
-rw-r--r--examples/future/call-cm/call-channel.h6
-rw-r--r--examples/future/call-cm/call-content.c324
-rw-r--r--examples/future/call-cm/call-content.h7
-rw-r--r--examples/future/call-cm/call-manager.c3
-rw-r--r--examples/future/call-cm/call-stream.c624
-rw-r--r--examples/future/call-cm/call-stream.h5
7 files changed, 310 insertions, 1550 deletions
diff --git a/examples/future/call-cm/call-channel.c b/examples/future/call-cm/call-channel.c
index ccfd4869a..8962140f3 100644
--- a/examples/future/call-cm/call-channel.c
+++ b/examples/future/call-cm/call-channel.c
@@ -49,64 +49,31 @@
#include "call-content.h"
#include "call-stream.h"
-static void call_iface_init (gpointer iface, gpointer data);
static void hold_iface_init (gpointer iface, gpointer data);
G_DEFINE_TYPE_WITH_CODE (ExampleCallChannel,
example_call_channel,
- TP_TYPE_BASE_CHANNEL,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_CALL,
- call_iface_init);
+ TP_TYPE_BASE_CALL_CHANNEL,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_HOLD,
hold_iface_init))
enum
{
PROP_SIMULATION_DELAY = 1,
- PROP_INITIAL_AUDIO,
- PROP_INITIAL_VIDEO,
- PROP_INITIAL_AUDIO_NAME,
- PROP_INITIAL_VIDEO_NAME,
- PROP_CONTENT_PATHS,
- PROP_CALL_STATE,
- PROP_CALL_FLAGS,
- PROP_CALL_STATE_REASON,
- PROP_CALL_STATE_DETAILS,
- PROP_HARDWARE_STREAMING,
- PROP_CALL_MEMBERS,
- PROP_MEMBER_IDENTIFIERS,
- PROP_INITIAL_TRANSPORT,
- PROP_MUTABLE_CONTENTS,
N_PROPS
};
struct _ExampleCallChannelPrivate
{
+ guint simulation_delay;
TpBaseConnection *conn;
- gchar *object_path;
TpHandle handle;
- TpHandle initiator;
-
- TpCallState call_state;
- TpCallFlags call_flags;
- GValueArray *call_state_reason;
- GHashTable *call_state_details;
- TpCallMemberFlags peer_flags;
-
- guint simulation_delay;
-
- guint next_stream_id;
-
- /* strdup'd name => referenced ExampleCallContent */
- GHashTable *contents;
+ gboolean locally_requested;
guint hold_state;
guint hold_state_reason;
- gboolean locally_requested;
- gboolean initial_audio;
- gboolean initial_video;
- gboolean disposed;
+ guint next_stream_id;
gboolean closed;
};
@@ -130,62 +97,9 @@ example_call_channel_set_state (ExampleCallChannel *self,
const gchar *error,
...)
{
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles
- (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpHandle old_actor;
- const gchar *key;
- va_list va;
-
- self->priv->call_state = state;
- self->priv->call_flags = flags;
-
- old_actor = g_value_get_uint (self->priv->call_state_reason->values + 0);
-
- if (actor != 0)
- tp_handle_ref (contact_handles, actor);
-
- if (old_actor != 0)
- tp_handle_unref (contact_handles, old_actor);
-
- g_value_set_uint (self->priv->call_state_reason->values + 0, actor);
- g_value_set_uint (self->priv->call_state_reason->values + 1, reason);
- g_value_set_string (self->priv->call_state_reason->values + 2, error);
-
- g_hash_table_remove_all (self->priv->call_state_details);
-
- va_start (va, error);
-
- /* This is basically tp_asv_new_va(), but that doesn't exist yet
- * (and when it does, we still won't want to use it in this example
- * just yet, because examples shouldn't use unreleased API) */
- for (key = va_arg (va, const gchar *);
- key != NULL;
- key = va_arg (va, const gchar *))
- {
- GType type = va_arg (va, GType);
- GValue *value = tp_g_value_slice_new (type);
- gchar *collect_error = NULL;
-
- G_VALUE_COLLECT (value, va, 0, &collect_error);
-
- if (collect_error != NULL)
- {
- g_critical ("key %s: %s", key, collect_error);
- g_free (collect_error);
- collect_error = NULL;
- tp_g_value_slice_free (value);
- continue;
- }
-
- g_hash_table_insert (self->priv->call_state_details,
- (gchar *) key, value);
- }
-
- va_end (va);
-
- tp_svc_channel_type_call_emit_call_state_changed (self,
- self->priv->call_state, self->priv->call_flags,
- self->priv->call_state_reason, self->priv->call_state_details);
+ /* FIXME: TpBaseCallChannel is not that flexible */
+ tp_base_call_channel_set_state ((TpBaseCallChannel *) self,
+ state, actor, reason, error, "");
}
static void
@@ -196,19 +110,6 @@ example_call_channel_init (ExampleCallChannel *self)
ExampleCallChannelPrivate);
self->priv->next_stream_id = 1;
- self->priv->contents = g_hash_table_new_full (g_str_hash,
- g_str_equal, g_free, g_object_unref);
-
- self->priv->call_state = TP_CALL_STATE_UNKNOWN; /* set in constructed */
- self->priv->call_flags = 0;
- self->priv->call_state_reason = tp_value_array_build (4,
- G_TYPE_UINT, 0, /* actor */
- G_TYPE_UINT, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
- G_TYPE_STRING, "",
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
- self->priv->call_state_details = tp_asv_new (
- NULL, NULL);
self->priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
self->priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
@@ -227,27 +128,18 @@ constructed (GObject *object)
void (*chain_up) (GObject *) =
((GObjectClass *) example_call_channel_parent_class)->constructed;
ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (object);
- TpHandleRepoIface *contact_repo;
TpBaseChannel *base = (TpBaseChannel *) self;
+ TpBaseCallChannel *call = (TpBaseCallChannel *) self;
if (chain_up != NULL)
chain_up (object);
- self->priv->object_path = g_strdup (tp_base_channel_get_object_path (base));
self->priv->handle = tp_base_channel_get_target_handle (base);
- self->priv->initiator = tp_base_channel_get_initiator (base);
self->priv->locally_requested = tp_base_channel_is_requested (base);
self->priv->conn = tp_base_channel_get_connection (base);
- contact_repo = tp_base_connection_get_handles (self->priv->conn,
- TP_HANDLE_TYPE_CONTACT);
-
- tp_handle_ref (contact_repo, self->priv->handle);
- tp_handle_ref (contact_repo, self->priv->initiator);
-
- tp_dbus_daemon_register_object (
- tp_base_connection_get_dbus_daemon (self->priv->conn),
- self->priv->object_path, self);
+ tp_base_call_channel_update_member_flags (call, self->priv->handle, 0,
+ 0, TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
if (self->priv->locally_requested)
{
@@ -269,41 +161,22 @@ constructed (GObject *object)
NULL);
}
- if (self->priv->locally_requested)
+ /* FIXME: should respect initial names */
+ if (tp_base_call_channel_has_initial_audio (call, NULL))
{
- if (self->priv->initial_audio)
- {
- g_message ("Channel initially has an audio stream");
- example_call_channel_add_content (self,
- TP_MEDIA_STREAM_TYPE_AUDIO, TRUE, TRUE, NULL, NULL);
- }
-
- if (self->priv->initial_video)
- {
- g_message ("Channel initially has a video stream");
- example_call_channel_add_content (self,
- TP_MEDIA_STREAM_TYPE_VIDEO, TRUE, TRUE, NULL, NULL);
- }
+ g_message ("Channel initially has an audio stream");
+ example_call_channel_add_content (self, TP_MEDIA_STREAM_TYPE_AUDIO,
+ self->priv->locally_requested, TRUE, NULL, NULL);
}
- else
- {
- /* the caller has almost certainly asked us for some streams - there's
- * not much point in having a call otherwise */
- if (self->priv->initial_audio)
- {
- g_message ("Channel initially has an audio stream");
- example_call_channel_add_content (self,
- TP_MEDIA_STREAM_TYPE_AUDIO, FALSE, TRUE, NULL, NULL);
- }
-
- if (self->priv->initial_video)
- {
- g_message ("Channel initially has a video stream");
- example_call_channel_add_content (self,
- TP_MEDIA_STREAM_TYPE_VIDEO, FALSE, TRUE, NULL, NULL);
- }
+ if (tp_base_call_channel_has_initial_video (call, NULL))
+ {
+ g_message ("Channel initially has a video stream");
+ example_call_channel_add_content (self, TP_MEDIA_STREAM_TYPE_VIDEO,
+ self->priv->locally_requested, TRUE, NULL, NULL);
}
+
+ tp_base_channel_register (base);
}
static void
@@ -320,102 +193,6 @@ get_property (GObject *object,
g_value_set_uint (value, self->priv->simulation_delay);
break;
- case PROP_INITIAL_AUDIO:
- g_value_set_boolean (value, self->priv->initial_audio);
- break;
-
- case PROP_INITIAL_VIDEO:
- g_value_set_boolean (value, self->priv->initial_video);
- break;
-
- case PROP_INITIAL_AUDIO_NAME:
- g_value_set_string (value, self->priv->initial_audio ? "audio" : NULL);
- break;
-
- case PROP_INITIAL_VIDEO_NAME:
- g_value_set_string (value, self->priv->initial_video ? "video" : NULL);
- break;
-
- case PROP_CONTENT_PATHS:
- {
- GPtrArray *paths = g_ptr_array_sized_new (g_hash_table_size (
- self->priv->contents));
- GHashTableIter iter;
- gpointer v;
-
- g_hash_table_iter_init (&iter, self->priv->contents);
-
- while (g_hash_table_iter_next (&iter, NULL, &v))
- {
- gchar *path;
-
- g_object_get (v,
- "object-path", &path,
- NULL);
-
- g_ptr_array_add (paths, path);
- }
-
- g_value_take_boxed (value, paths);
- }
- break;
-
- case PROP_CALL_STATE:
- g_value_set_uint (value, self->priv->call_state);
- break;
-
- case PROP_CALL_FLAGS:
- g_value_set_uint (value, self->priv->call_flags);
- break;
-
- case PROP_CALL_STATE_REASON:
- g_value_set_boxed (value, self->priv->call_state_reason);
- break;
-
- case PROP_CALL_STATE_DETAILS:
- g_value_set_boxed (value, self->priv->call_state_details);
- break;
-
- case PROP_HARDWARE_STREAMING:
- /* yes, this implementation has hardware streaming */
- g_value_set_boolean (value, TRUE);
- break;
-
- case PROP_MUTABLE_CONTENTS:
- /* yes, this implementation can add contents */
- g_value_set_boolean (value, TRUE);
- break;
-
- case PROP_INITIAL_TRANSPORT:
- /* this implementation has hardware_streaming, so the initial
- * transport is rather meaningless */
- g_value_set_uint (value, TP_STREAM_TRANSPORT_TYPE_UNKNOWN);
- break;
-
- case PROP_CALL_MEMBERS:
- {
- GHashTable *uu_map = g_hash_table_new (NULL, NULL);
-
- /* There is one contact, other than the self-handle. */
- g_hash_table_insert (uu_map, GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (self->priv->peer_flags));
- g_value_take_boxed (value, uu_map);
- }
- break;
-
- case PROP_MEMBER_IDENTIFIERS:
- {
- GHashTable *us_map = g_hash_table_new (NULL, NULL);
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- /* There is one contact, other than the self-handle. */
- g_hash_table_insert (us_map, GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_handles, self->priv->handle));
- g_value_take_boxed (value, us_map);
- }
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -436,14 +213,6 @@ set_property (GObject *object,
self->priv->simulation_delay = g_value_get_uint (value);
break;
- case PROP_INITIAL_AUDIO:
- self->priv->initial_audio = g_value_get_boolean (value);
- break;
-
- case PROP_INITIAL_VIDEO:
- self->priv->initial_video = g_value_get_boolean (value);
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -457,11 +226,12 @@ example_call_channel_terminate (ExampleCallChannel *self,
TpCallStateChangeReason call_reason,
const gchar *error_name)
{
- if (self->priv->call_state != TP_CALL_STATE_ENDED)
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
+ TpCallState call_state = tp_base_call_channel_get_state (base);
+
+ if (call_state != TP_CALL_STATE_ENDED)
{
- GList *values;
- GHashTable *empty_uu_map = g_hash_table_new (NULL, NULL);
- GArray *au = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
+ GList *contents;
example_call_channel_set_state (self,
TP_CALL_STATE_ENDED, 0, actor,
@@ -470,11 +240,8 @@ example_call_channel_terminate (ExampleCallChannel *self,
/* FIXME: fd.o #24936 #c20: it's unclear in the spec whether we should
* remove peers on call termination or not. For now this example does. */
- g_array_append_val (au, self->priv->handle);
- tp_svc_channel_type_call_emit_call_members_changed (self,
- empty_uu_map, empty_uu_map, au, self->priv->call_state_reason);
- g_hash_table_unref (empty_uu_map);
- g_array_unref (au);
+ tp_base_call_channel_remove_member (base, self->priv->handle,
+ actor, call_reason, error_name, NULL);
if (actor == tp_base_connection_get_self_handle (self->priv->conn))
{
@@ -502,56 +269,22 @@ example_call_channel_terminate (ExampleCallChannel *self,
/* terminate all streams: to avoid modifying the hash table (in the
* streams-removed handler) while iterating over it, we have to copy the
* keys and iterate over those */
- values = g_hash_table_get_values (self->priv->contents);
- g_list_foreach (values, (GFunc) g_object_ref, NULL);
-
- for (; values != NULL; values = g_list_delete_link (values, values))
+ contents = tp_base_call_channel_get_contents (base);
+ contents = g_list_copy (contents);
+ for (; contents != NULL; contents = g_list_delete_link (contents, contents))
{
- ExampleCallStream *stream =
- example_call_content_get_stream (values->data);
-
- if (stream != NULL)
- example_call_stream_close (stream);
-
- g_object_unref (values->data);
+ example_call_content_remove_stream (contents->data);
+ tp_base_call_channel_remove_content (base, contents->data,
+ 0, call_reason, error_name, "");
}
}
}
-void
-example_call_channel_disconnected (ExampleCallChannel *self)
-{
- example_call_channel_terminate (self, 0,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
- TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
- TP_ERROR_STR_DISCONNECTED);
-
- if (!self->priv->closed)
- {
- self->priv->closed = TRUE;
- tp_svc_channel_emit_closed (self);
- }
-}
-
static void
dispose (GObject *object)
{
ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (object);
- if (self->priv->disposed)
- return;
-
- self->priv->disposed = TRUE;
-
- g_hash_table_unref (self->priv->contents);
- self->priv->contents = NULL;
-
- /* FIXME: right error code? arguably this should always be a no-op */
- example_call_channel_terminate (self,
- tp_base_connection_get_self_handle (self->priv->conn),
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
- TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "");
-
/* the manager is meant to hold a ref to us until we've closed */
g_assert (self->priv->closed);
@@ -559,24 +292,6 @@ dispose (GObject *object)
}
static void
-finalize (GObject *object)
-{
- ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (object);
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles
- (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- g_value_array_free (self->priv->call_state_reason);
- g_hash_table_unref (self->priv->call_state_details);
-
- tp_handle_unref (contact_handles, self->priv->handle);
- tp_handle_unref (contact_handles, self->priv->initiator);
-
- g_free (self->priv->object_path);
-
- ((GObjectClass *) example_call_channel_parent_class)->finalize (object);
-}
-
-static void
close_channel (TpBaseChannel *base)
{
ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (base);
@@ -591,66 +306,39 @@ close_channel (TpBaseChannel *base)
tp_base_channel_destroyed (base);
}
-static void
-fill_immutable_properties (TpBaseChannel *self,
- GHashTable *properties)
-{
- TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
- example_call_channel_parent_class);
-
- klass->fill_immutable_properties (self, properties);
-
- tp_dbus_properties_mixin_fill_properties_hash (
- G_OBJECT (self), properties,
- TP_IFACE_CHANNEL_TYPE_CALL, "HardwareStreaming",
- TP_IFACE_CHANNEL_TYPE_CALL, "InitialTransport",
- TP_IFACE_CHANNEL_TYPE_CALL, "InitialAudio",
- TP_IFACE_CHANNEL_TYPE_CALL, "InitialVideo",
- TP_IFACE_CHANNEL_TYPE_CALL, "InitialAudioName",
- TP_IFACE_CHANNEL_TYPE_CALL, "InitialVideoName",
- TP_IFACE_CHANNEL_TYPE_CALL, "MutableContents",
- NULL);
-}
+static void call_accept (TpBaseCallChannel *self);
+static TpBaseCallContent * call_add_content (TpBaseCallChannel *self,
+ const gchar *name,
+ TpMediaStreamType media,
+ GError **error);
+static void call_hangup (TpBaseCallChannel *self,
+ guint reason,
+ const gchar *detailed_reason,
+ const gchar *message);
static void
example_call_channel_class_init (ExampleCallChannelClass *klass)
{
- static TpDBusPropertiesMixinPropImpl call_props[] = {
- { "Contents", "content-paths", NULL },
- { "CallState", "call-state", NULL },
- { "CallFlags", "call-flags", NULL },
- { "CallStateReason", "call-state-reason", NULL },
- { "CallStateDetails", "call-state-details", NULL },
- { "HardwareStreaming", "hardware-streaming", NULL },
- { "CallMembers", "call-members", NULL },
- { "MemberIdentifiers", "member-identifiers", NULL },
- { "InitialTransport", "initial-transport", NULL },
- { "InitialAudio", "initial-audio", NULL },
- { "InitialVideo", "initial-video", NULL },
- { "InitialAudioName", "initial-audio-name", NULL },
- { "InitialVideoName", "initial-video-name", NULL },
- { "MutableContents", "mutable-contents", NULL },
- { NULL }
- };
GObjectClass *object_class = (GObjectClass *) klass;
- GParamSpec *param_spec;
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+ TpBaseCallChannelClass *call_class = (TpBaseCallChannelClass *) klass;
+ GParamSpec *param_spec;
g_type_class_add_private (klass,
sizeof (ExampleCallChannelPrivate));
- base_class->channel_type = TP_IFACE_CHANNEL_TYPE_CALL;
+ call_class->accept = call_accept;
+ call_class->add_content = call_add_content;
+ call_class->hangup = call_hangup;
+
base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
base_class->interfaces = example_call_channel_interfaces;
-
base_class->close = close_channel;
- base_class->fill_immutable_properties = fill_immutable_properties;
object_class->constructed = constructed;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
- object_class->finalize = finalize;
param_spec = g_param_spec_uint ("simulation-delay", "Simulation delay",
"Delay between simulated network events",
@@ -658,197 +346,18 @@ example_call_channel_class_init (ExampleCallChannelClass *klass)
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SIMULATION_DELAY,
param_spec);
-
- param_spec = g_param_spec_boolean ("initial-audio", "Initial audio?",
- "True if this channel had an audio stream when first announced",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_AUDIO,
- param_spec);
-
- param_spec = g_param_spec_boolean ("initial-video", "Initial video?",
- "True if this channel had a video stream when first announced",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
- param_spec);
-
- param_spec = g_param_spec_string ("initial-audio-name", "Initial audio name",
- "The name of the initial audio, if any",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_AUDIO_NAME,
- param_spec);
-
- param_spec = g_param_spec_string ("initial-video-name", "Initial video name",
- "The name of the initial video, if any",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_VIDEO_NAME,
- param_spec);
-
- param_spec = g_param_spec_boxed ("content-paths", "Content paths",
- "A list of the object paths of contents",
- TP_ARRAY_TYPE_OBJECT_PATH_LIST,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONTENT_PATHS,
- param_spec);
-
- param_spec = g_param_spec_uint ("call-state", "Call state",
- "High-level state of the call",
- 0, NUM_TP_CALL_STATES - 1, TP_CALL_STATE_PENDING_INITIATOR,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_STATE,
- param_spec);
-
- param_spec = g_param_spec_uint ("call-flags", "Call flags",
- "Flags for additional sub-states",
- 0, G_MAXUINT32, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_FLAGS,
- param_spec);
-
- param_spec = g_param_spec_boxed ("call-state-reason", "Call state reason",
- "Reason for call-state and call-flags",
- TP_STRUCT_TYPE_CALL_STATE_REASON,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_STATE_REASON,
- param_spec);
-
- param_spec = g_param_spec_boxed ("call-state-details", "Call state details",
- "Additional details of the call state/flags/reason",
- TP_HASH_TYPE_STRING_VARIANT_MAP,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_STATE_DETAILS,
- param_spec);
-
- param_spec = g_param_spec_boolean ("hardware-streaming",
- "Hardware streaming?",
- "True if this channel does all of its own streaming (it does)",
- TRUE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_HARDWARE_STREAMING,
- param_spec);
-
- param_spec = g_param_spec_boxed ("call-members", "Call members",
- "A map from call members (only one in this example) to their states",
- TP_HASH_TYPE_CALL_MEMBER_MAP,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_MEMBERS,
- param_spec);
-
- param_spec = g_param_spec_boxed ("member-identifiers", "Call member identifiers",
- "A map from call members (only one in this example) to their identifiers",
- TP_HASH_TYPE_HANDLE_IDENTIFIER_MAP,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEMBER_IDENTIFIERS,
- param_spec);
-
- param_spec = g_param_spec_uint ("initial-transport", "Initial transport",
- "The initial transport for this channel (there is none)",
- 0, NUM_TP_STREAM_TRANSPORT_TYPES,
- TP_STREAM_TRANSPORT_TYPE_UNKNOWN,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_TRANSPORT,
- param_spec);
-
- param_spec = g_param_spec_boolean ("mutable-contents", "Mutable contents?",
- "True if contents can be added to this channel (they can)",
- TRUE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MUTABLE_CONTENTS,
- param_spec);
-
- tp_dbus_properties_mixin_implement_interface (object_class,
- TP_IFACE_QUARK_CHANNEL_TYPE_CALL,
- tp_dbus_properties_mixin_getter_gobject_properties, NULL,
- call_props);
-}
-
-#if 0
-/* FIXME: there's no equivalent of this in Call (yet?) */
-
-/* This is expressed in terms of streams because it's the old API, but it
- * really means removing contents. */
-static void
-media_remove_streams (TpSvcChannelTypeStreamedMedia *iface,
- const GArray *stream_ids,
- DBusGMethodInvocation *context)
-{
- ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (iface);
- guint i;
-
- for (i = 0; i < stream_ids->len; i++)
- {
- guint id = g_array_index (stream_ids, guint, i);
-
- if (g_hash_table_lookup (self->priv->contents,
- GUINT_TO_POINTER (id)) == NULL)
- {
- GError *error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "No stream with ID %u in this channel", id);
-
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
- }
-
- for (i = 0; i < stream_ids->len; i++)
- {
- guint id = g_array_index (stream_ids, guint, i);
- ExampleCallContent *content =
- g_hash_table_lookup (self->priv->contents, GUINT_TO_POINTER (id));
- ExampleCallStream *stream = example_call_content_get_stream (content);
-
- if (stream != NULL)
- example_call_stream_close (stream);
- }
-
- tp_svc_channel_type_streamed_media_return_from_remove_streams (context);
-}
-#endif
-
-static void
-streams_removed_cb (ExampleCallContent *content,
- const GPtrArray *stream_paths G_GNUC_UNUSED,
- const GValueArray *reason,
- ExampleCallChannel *self)
-{
- gchar *path, *name;
-
- /* Contents in this example CM can only have one stream, so if their
- * stream disappears, the content has to be removed too. */
-
- g_object_get (content,
- "object-path", &path,
- "name", &name,
- NULL);
-
- g_hash_table_remove (self->priv->contents, name);
-
- tp_svc_call_content_emit_removed (content);
- tp_svc_channel_type_call_emit_content_removed (self, path, reason);
- g_free (path);
- g_free (name);
-
- if (g_hash_table_size (self->priv->contents) == 0)
- {
- /* no contents left, so the call terminates */
- example_call_channel_terminate (self, 0,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
- TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "");
- /* FIXME: is there an appropriate error? */
- }
}
static gboolean
simulate_contact_ended_cb (gpointer p)
{
ExampleCallChannel *self = p;
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
+ TpCallState call_state = tp_base_call_channel_get_state (base);
/* if the call has been cancelled while we were waiting for the
* contact to do so, do nothing! */
- if (self->priv->call_state == TP_CALL_STATE_ENDED)
+ if (call_state == TP_CALL_STATE_ENDED)
return FALSE;
g_message ("SIGNALLING: receive: call terminated: <call-terminated/>");
@@ -864,19 +373,20 @@ static gboolean
simulate_contact_answered_cb (gpointer p)
{
ExampleCallChannel *self = p;
- GHashTableIter iter;
- gpointer v;
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
+ TpCallState call_state = tp_base_call_channel_get_state (base);
+ GList *contents;
TpHandleRepoIface *contact_repo;
const gchar *peer;
/* if the call has been cancelled while we were waiting for the
* contact to answer, do nothing! */
- if (self->priv->call_state == TP_CALL_STATE_ENDED)
+ if (call_state == TP_CALL_STATE_ENDED)
return FALSE;
/* otherwise, we're waiting for a response from the contact, which now
* arrives */
- g_assert_cmpuint (self->priv->call_state, ==, TP_CALL_STATE_RINGING);
+ g_assert_cmpuint (call_state, ==, TP_CALL_STATE_RINGING);
g_message ("SIGNALLING: receive: contact answered our call");
@@ -885,11 +395,10 @@ simulate_contact_answered_cb (gpointer p)
TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "",
NULL);
- g_hash_table_iter_init (&iter, self->priv->contents);
-
- while (g_hash_table_iter_next (&iter, NULL, &v))
+ contents = tp_base_call_channel_get_contents (base);
+ for (; contents != NULL; contents = contents->next)
{
- ExampleCallStream *stream = example_call_content_get_stream (v);
+ ExampleCallStream *stream = example_call_content_get_stream (contents->data);
if (stream == NULL)
continue;
@@ -919,15 +428,17 @@ static gboolean
simulate_contact_busy_cb (gpointer p)
{
ExampleCallChannel *self = p;
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
+ TpCallState call_state = tp_base_call_channel_get_state (base);
/* if the call has been cancelled while we were waiting for the
* contact to answer, do nothing */
- if (self->priv->call_state == TP_CALL_STATE_ENDED)
+ if (call_state == TP_CALL_STATE_ENDED)
return FALSE;
/* otherwise, we're waiting for a response from the contact, which now
* arrives */
- g_assert_cmpuint (self->priv->call_state, ==, TP_CALL_STATE_RINGING);
+ g_assert_cmpuint (call_state, ==, TP_CALL_STATE_RINGING);
g_message ("SIGNALLING: receive: call terminated: <user-is-busy/>");
@@ -947,30 +458,31 @@ example_call_channel_add_content (ExampleCallChannel *self,
const gchar *requested_name,
GError **error)
{
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
+ GList *contents;
+ const gchar *type_str;
+ TpHandle creator = self->priv->handle;
+ TpCallContentDisposition disposition =
+ TP_CALL_CONTENT_DISPOSITION_NONE;
+ guint id = self->priv->next_stream_id++;
ExampleCallContent *content;
ExampleCallStream *stream;
- guint id = self->priv->next_stream_id++;
- const gchar *type_str;
- TpHandle creator;
gchar *name;
gchar *path;
- TpCallContentDisposition disposition =
- TP_CALL_CONTENT_DISPOSITION_NONE;
guint i;
- type_str = (media_type == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video");
- creator = self->priv->handle;
-
/* an arbitrary limit much less than 2**32 means we don't use ridiculous
* amounts of memory, and also means @i can't wrap around when we use it to
* uniquify content names. */
- if (g_hash_table_size (self->priv->contents) > MAX_CONTENTS_PER_CALL)
+ contents = tp_base_call_channel_get_contents (base);
+ if (g_list_length (contents) > MAX_CONTENTS_PER_CALL)
{
g_set_error (error, TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
"What are you doing with all those contents anyway?!");
return NULL;
}
+ type_str = (media_type == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video");
if (tp_str_empty (requested_name))
{
requested_name = type_str;
@@ -978,13 +490,20 @@ example_call_channel_add_content (ExampleCallChannel *self,
for (i = 0; ; i++)
{
+ GList *l;
+
if (i == 0)
name = g_strdup (requested_name);
else
name = g_strdup_printf ("%s (%u)", requested_name, i);
- if (!g_hash_table_lookup_extended (self->priv->contents, name,
- NULL, NULL))
+ for (l = contents; l != NULL; l = l->next)
+ {
+ if (!tp_strdiff (tp_base_call_content_get_name (l->data), name))
+ break;
+ }
+
+ if (l == NULL)
{
/* this name hasn't been used - good enough */
break;
@@ -1003,21 +522,24 @@ example_call_channel_add_content (ExampleCallChannel *self,
creator = self->priv->conn->self_handle;
}
- path = g_strdup_printf ("%s/Content%u", self->priv->object_path, id);
+ path = g_strdup_printf ("%s/Content%u",
+ tp_base_channel_get_object_path ((TpBaseChannel *) self),
+ id);
content = g_object_new (EXAMPLE_TYPE_CALL_CONTENT,
"connection", self->priv->conn,
"creator", creator,
- "type", media_type,
+ "media-type", media_type,
"name", name,
"disposition", disposition,
"object-path", path,
NULL);
- g_hash_table_insert (self->priv->contents, name, content);
- tp_svc_channel_type_call_emit_content_added (self, path);
+ tp_base_call_channel_add_content (base, (TpBaseCallContent *) content);
g_free (path);
- path = g_strdup_printf ("%s/Stream%u", self->priv->object_path, id);
+ path = g_strdup_printf ("%s/Stream%u",
+ tp_base_channel_get_object_path ((TpBaseChannel *) self),
+ id);
stream = g_object_new (EXAMPLE_TYPE_CALL_STREAM,
"connection", self->priv->conn,
"handle", self->priv->handle,
@@ -1028,8 +550,8 @@ example_call_channel_add_content (ExampleCallChannel *self,
example_call_content_add_stream (content, stream);
g_free (path);
- tp_g_signal_connect_object (content, "streams-removed",
- G_CALLBACK (streams_removed_cb), self, 0);
+ g_object_unref (content);
+ g_object_unref (stream);
return content;
}
@@ -1041,21 +563,10 @@ simulate_contact_ringing_cb (gpointer p)
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
(self->priv->conn, TP_HANDLE_TYPE_CONTACT);
const gchar *peer;
- GHashTable *uu_map = g_hash_table_new (NULL, NULL);
- GHashTable *us_map = g_hash_table_new (NULL, NULL);
- GArray *empty_au = g_array_sized_new (FALSE, FALSE, sizeof (guint), 0);
-
- /* ring, ring! */
- self->priv->peer_flags = TP_CALL_MEMBER_FLAG_RINGING;
- g_hash_table_insert (uu_map, GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (self->priv->peer_flags));
- g_hash_table_insert (us_map, GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_repo, self->priv->handle));
- tp_svc_channel_type_call_emit_call_members_changed (self,
- uu_map, us_map, empty_au, self->priv->call_state_reason);
- g_hash_table_unref (uu_map);
- g_array_unref (empty_au);
+ tp_base_call_channel_update_member_flags ((TpBaseCallChannel *) self,
+ self->priv->handle, TP_CALL_MEMBER_FLAG_RINGING,
+ 0, TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
/* In this example there is no real contact, so just simulate them
* answering after a short time - unless the contact's name
@@ -1089,6 +600,7 @@ static void
example_call_channel_initiate_outgoing (ExampleCallChannel *self)
{
g_message ("SIGNALLING: send: new streamed media call");
+
example_call_channel_set_state (self,
TP_CALL_STATE_RINGING, 0,
tp_base_connection_get_self_handle (self->priv->conn),
@@ -1103,54 +615,12 @@ example_call_channel_initiate_outgoing (ExampleCallChannel *self)
}
static void
-call_set_ringing (TpSvcChannelTypeCall *iface,
- DBusGMethodInvocation *context)
-{
- ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (iface);
- GError *error = NULL;
-
- if (self->priv->locally_requested)
- {
- g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "Ringing() makes no sense on an outgoing call");
- goto finally;
- }
-
- if (self->priv->call_state != TP_CALL_STATE_RINGING)
- {
- g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "Ringing() makes no sense now that we're not pending receiver");
- goto finally;
- }
-
- g_message ("SIGNALLING: send: ring, ring!");
-
- example_call_channel_set_state (self, TP_CALL_STATE_RINGING,
- self->priv->call_flags | TP_CALL_FLAG_LOCALLY_RINGING,
- tp_base_connection_get_self_handle (self->priv->conn),
- TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", NULL);
-
-finally:
- if (error == NULL)
- {
- tp_svc_channel_type_call_return_from_set_ringing (context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-static void
accept_incoming_call (ExampleCallChannel *self)
{
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
(self->priv->conn, TP_HANDLE_TYPE_CONTACT);
- GHashTableIter iter;
- gpointer v;
-
- g_assert_cmpint (self->priv->call_state, ==, TP_CALL_STATE_RINGING);
+ GList *contents;
g_message ("SIGNALLING: send: Accepting incoming call from %s",
tp_handle_inspect (contact_repo, self->priv->handle));
@@ -1161,19 +631,13 @@ accept_incoming_call (ExampleCallChannel *self)
TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "",
NULL);
- g_hash_table_iter_init (&iter, self->priv->contents);
-
- while (g_hash_table_iter_next (&iter, NULL, &v))
+ contents = tp_base_call_channel_get_contents (base);
+ for (; contents != NULL; contents = contents->next)
{
- ExampleCallStream *stream = example_call_content_get_stream (v);
- guint disposition;
-
- g_object_get (v,
- "disposition", &disposition,
- NULL);
+ ExampleCallStream *stream = example_call_content_get_stream (contents->data);
+ guint disposition = tp_base_call_content_get_disposition (contents->data);
- if (stream == NULL ||
- disposition != TP_CALL_CONTENT_DISPOSITION_INITIAL)
+ if (stream == NULL || disposition != TP_CALL_CONTENT_DISPOSITION_INITIAL)
continue;
/* we accept the proposed stream direction */
@@ -1182,155 +646,61 @@ accept_incoming_call (ExampleCallChannel *self)
}
static void
-call_accept (TpSvcChannelTypeCall *iface G_GNUC_UNUSED,
- DBusGMethodInvocation *context)
+call_accept (TpBaseCallChannel *base)
{
- ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (iface);
+ ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (base);
if (self->priv->locally_requested)
{
- if (self->priv->call_state == TP_CALL_STATE_PENDING_INITIATOR)
- {
- /* Take the contents we've already added, and make them happen */
- example_call_channel_initiate_outgoing (self);
-
- tp_svc_channel_type_call_return_from_accept (context);
- }
- else if (self->priv->call_state == TP_CALL_STATE_ENDED)
- {
- GError na = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "This call has already ended" };
-
- dbus_g_method_return_error (context, &na);
- }
- else
- {
- GError na = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "This outgoing call has already been started" };
-
- dbus_g_method_return_error (context, &na);
- }
+ /* Take the contents we've already added, and make them happen */
+ example_call_channel_initiate_outgoing (self);
}
else
{
- if (self->priv->call_state == TP_CALL_STATE_RINGING)
- {
- accept_incoming_call (self);
- tp_svc_channel_type_call_return_from_accept (context);
- }
- else if (self->priv->call_state == TP_CALL_STATE_ENDED)
- {
- GError na = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "This call has already ended" };
-
- dbus_g_method_return_error (context, &na);
- }
- else
- {
- GError na = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "This incoming call has already been accepted" };
-
- dbus_g_method_return_error (context, &na);
- }
+ accept_incoming_call (self);
}
}
static void
-call_hangup (TpSvcChannelTypeCall *iface,
+call_hangup (TpBaseCallChannel *base,
guint reason,
const gchar *detailed_reason,
- const gchar *message G_GNUC_UNUSED,
- DBusGMethodInvocation *context)
+ const gchar *message G_GNUC_UNUSED)
{
- ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (iface);
-
- if (self->priv->call_state == TP_CALL_STATE_ENDED)
- {
- GError na = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "This call has already ended" };
+ ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (base);
- dbus_g_method_return_error (context, &na);
- return;
- }
- else
- {
- example_call_channel_terminate (self,
- tp_base_connection_get_self_handle (self->priv->conn),
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE, reason, detailed_reason);
- tp_svc_channel_type_call_return_from_hangup (context);
- }
+ example_call_channel_terminate (self,
+ tp_base_connection_get_self_handle (self->priv->conn),
+ TP_CHANNEL_GROUP_CHANGE_REASON_NONE, reason, detailed_reason);
}
-static void
-call_add_content (TpSvcChannelTypeCall *iface,
+static TpBaseCallContent *
+call_add_content (TpBaseCallChannel *base,
const gchar *content_name,
guint content_type,
- DBusGMethodInvocation *context)
-{
- ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (iface);
- GError *error = NULL;
- gchar *content_path;
- ExampleCallContent *content;
-
- switch (content_type)
- {
- case TP_MEDIA_STREAM_TYPE_AUDIO:
- case TP_MEDIA_STREAM_TYPE_VIDEO:
- break;
-
- default:
- g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "%u is not a supported Media_Stream_Type", content_type);
- goto error;
- }
-
- content = example_call_channel_add_content (self, content_type, TRUE, FALSE,
- content_name, &error);
-
- if (content == NULL)
- goto error;
-
- g_object_get (content,
- "object-path", &content_path,
- NULL);
- tp_svc_channel_type_call_return_from_add_content (context,
- content_path);
- g_free (content_path);
-
- return;
-
-error:
- dbus_g_method_return_error (context, error);
- g_error_free (error);
-}
-
-static void
-call_iface_init (gpointer iface,
- gpointer data)
+ GError **error)
{
- TpSvcChannelTypeCallClass *klass = iface;
+ ExampleCallChannel *self = EXAMPLE_CALL_CHANNEL (base);
-#define IMPLEMENT(x) \
- tp_svc_channel_type_call_implement_##x (klass, call_##x)
- IMPLEMENT (set_ringing);
- IMPLEMENT (hangup);
- IMPLEMENT (accept);
- IMPLEMENT (add_content);
-#undef IMPLEMENT
+ return (TpBaseCallContent *) example_call_channel_add_content (self,
+ content_type, TRUE, FALSE, content_name, error);
}
static gboolean
simulate_hold (gpointer p)
{
ExampleCallChannel *self = p;
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
+ TpCallState call_state = tp_base_call_channel_get_state (base);
+ TpCallFlags call_flags = 0; /* FIXME */
self->priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
g_message ("SIGNALLING: hold state changed to held");
tp_svc_channel_interface_hold_emit_hold_state_changed (self,
self->priv->hold_state, self->priv->hold_state_reason);
- example_call_channel_set_state (self, self->priv->call_state,
- self->priv->call_flags | TP_CALL_FLAG_LOCALLY_HELD,
+ example_call_channel_set_state (self, call_state,
+ call_flags | TP_CALL_FLAG_LOCALLY_HELD,
tp_base_connection_get_self_handle (self->priv->conn),
TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", NULL);
@@ -1341,14 +711,17 @@ static gboolean
simulate_unhold (gpointer p)
{
ExampleCallChannel *self = p;
+ TpBaseCallChannel *base = (TpBaseCallChannel *) self;
+ TpCallState call_state = tp_base_call_channel_get_state (base);
+ TpCallFlags call_flags = 0; /* FIXME */
self->priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
g_message ("SIGNALLING: hold state changed to unheld");
tp_svc_channel_interface_hold_emit_hold_state_changed (self,
self->priv->hold_state, self->priv->hold_state_reason);
- example_call_channel_set_state (self, self->priv->call_state,
- self->priv->call_flags & ~TP_CALL_FLAG_LOCALLY_HELD,
+ example_call_channel_set_state (self, call_state,
+ call_flags & ~TP_CALL_FLAG_LOCALLY_HELD,
tp_base_connection_get_self_handle (self->priv->conn),
TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", NULL);
diff --git a/examples/future/call-cm/call-channel.h b/examples/future/call-cm/call-channel.h
index 2004df802..0bf55f57f 100644
--- a/examples/future/call-cm/call-channel.h
+++ b/examples/future/call-cm/call-channel.h
@@ -53,17 +53,15 @@ GType example_call_channel_get_type (void);
ExampleCallChannelClass))
struct _ExampleCallChannelClass {
- TpBaseChannelClass parent_class;
+ TpBaseCallChannelClass parent_class;
};
struct _ExampleCallChannel {
- TpBaseChannel parent;
+ TpBaseCallChannel parent;
ExampleCallChannelPrivate *priv;
};
-void example_call_channel_disconnected (ExampleCallChannel *self);
-
G_END_DECLS
#endif
diff --git a/examples/future/call-cm/call-content.c b/examples/future/call-cm/call-content.c
index 92210b60c..601104c22 100644
--- a/examples/future/call-cm/call-content.c
+++ b/examples/future/call-cm/call-content.c
@@ -25,35 +25,12 @@
#include <telepathy-glib/telepathy-glib.h>
#include <telepathy-glib/svc-call.h>
-G_DEFINE_TYPE_WITH_CODE (ExampleCallContent,
+G_DEFINE_TYPE (ExampleCallContent,
example_call_content,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- /* no methods, so no vtable needed */
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CALL_CONTENT, NULL))
-
-enum
-{
- PROP_OBJECT_PATH = 1,
- PROP_CONNECTION,
- PROP_INTERFACES,
- PROP_NAME,
- PROP_TYPE,
- PROP_CREATOR,
- PROP_DISPOSITION,
- PROP_STREAM_PATHS,
- N_PROPS
-};
+ TP_TYPE_BASE_CALL_CONTENT)
struct _ExampleCallContentPrivate
{
- gchar *object_path;
- TpBaseConnection *conn;
- gchar *name;
- TpMediaStreamType type;
- TpHandle creator;
- TpCallContentDisposition disposition;
ExampleCallStream *stream;
};
@@ -66,324 +43,61 @@ example_call_content_init (ExampleCallContent *self)
}
static void
-constructed (GObject *object)
-{
- ExampleCallContent *self = EXAMPLE_CALL_CONTENT (object);
- void (*chain_up) (GObject *) =
- ((GObjectClass *) example_call_content_parent_class)->constructed;
- TpHandleRepoIface *contact_repo;
-
- if (chain_up != NULL)
- chain_up (object);
-
- tp_dbus_daemon_register_object (
- tp_base_connection_get_dbus_daemon (self->priv->conn),
- self->priv->object_path, self);
-
- contact_repo = tp_base_connection_get_handles (self->priv->conn,
- TP_HANDLE_TYPE_CONTACT);
- tp_handle_ref (contact_repo, self->priv->creator);
-}
-
-static const gchar * const empty_strv[] = { NULL };
-
-static void
-get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- ExampleCallContent *self = EXAMPLE_CALL_CONTENT (object);
-
- switch (property_id)
- {
- case PROP_OBJECT_PATH:
- g_value_set_string (value, self->priv->object_path);
- break;
-
- case PROP_CONNECTION:
- g_value_set_object (value, self->priv->conn);
- break;
-
- case PROP_INTERFACES:
- g_value_set_static_boxed (value, empty_strv);
- break;
-
- case PROP_NAME:
- g_value_set_string (value, self->priv->name);
- break;
-
- case PROP_CREATOR:
- g_value_set_uint (value, self->priv->creator);
- break;
-
- case PROP_TYPE:
- g_value_set_uint (value, self->priv->type);
- break;
-
- case PROP_DISPOSITION:
- g_value_set_uint (value, self->priv->disposition);
- break;
-
- case PROP_STREAM_PATHS:
- {
- GPtrArray *paths = g_ptr_array_sized_new (1);
-
- if (self->priv->stream != NULL)
- {
- gchar *path;
-
- g_object_get (self->priv->stream,
- "object-path", &path,
- NULL);
-
- g_ptr_array_add (paths, path);
- }
-
- g_value_take_boxed (value, paths);
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- ExampleCallContent *self = EXAMPLE_CALL_CONTENT (object);
-
- switch (property_id)
- {
- case PROP_OBJECT_PATH:
- g_assert (self->priv->object_path == NULL); /* construct-only */
- self->priv->object_path = g_value_dup_string (value);
- break;
-
- case PROP_CONNECTION:
- g_assert (self->priv->conn == NULL);
- self->priv->conn = g_value_dup_object (value);
- break;
-
- case PROP_CREATOR:
- /* we don't ref it here because we don't necessarily have access to the
- * contact repo yet - instead we ref it in the constructor.
- */
- g_assert (self->priv->creator == 0); /* construct-only */
- self->priv->creator = g_value_get_uint (value);
- break;
-
- case PROP_NAME:
- g_assert (self->priv->name == NULL); /* construct-only */
- self->priv->name = g_value_dup_string (value);
- break;
-
- case PROP_TYPE:
- self->priv->type = g_value_get_uint (value);
- break;
-
- case PROP_DISPOSITION:
- self->priv->disposition = g_value_get_uint (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
dispose (GObject *object)
{
ExampleCallContent *self = EXAMPLE_CALL_CONTENT (object);
- if (self->priv->stream != NULL)
- {
- g_object_unref (self->priv->stream);
- self->priv->stream = NULL;
- }
-
- if (self->priv->conn != NULL)
- {
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles
- (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- tp_handle_unref (contact_handles, self->priv->creator);
- self->priv->creator = 0;
-
- g_object_unref (self->priv->conn);
- self->priv->conn = NULL;
- }
+ g_clear_object (&self->priv->stream);
((GObjectClass *) example_call_content_parent_class)->dispose (object);
}
static void
-finalize (GObject *object)
-{
- ExampleCallContent *self = EXAMPLE_CALL_CONTENT (object);
- void (*chain_up) (GObject *) =
- ((GObjectClass *) example_call_content_parent_class)->finalize;
-
- g_free (self->priv->object_path);
- g_free (self->priv->name);
-
- if (chain_up != NULL)
- chain_up (object);
-}
-
-static void
example_call_content_class_init (ExampleCallContentClass *klass)
{
- static TpDBusPropertiesMixinPropImpl content_props[] = {
- { "Name", "name", NULL },
- { "Interfaces", "interfaces", NULL },
- { "Type", "type", NULL },
- { "Disposition", "disposition", NULL },
- { "Streams", "stream-paths", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_CALL_CONTENT,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- content_props,
- },
- { NULL }
- };
GObjectClass *object_class = (GObjectClass *) klass;
- GParamSpec *param_spec;
g_type_class_add_private (klass,
sizeof (ExampleCallContentPrivate));
- object_class->constructed = constructed;
- object_class->set_property = set_property;
- object_class->get_property = get_property;
object_class->dispose = dispose;
- object_class->finalize = finalize;
-
- param_spec = g_param_spec_string ("object-path", "D-Bus object path",
- "The D-Bus object path used for this object on the bus.", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
-
- param_spec = g_param_spec_object ("connection", "TpBaseConnection",
- "Connection that owns this content",
- TP_TYPE_BASE_CONNECTION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
-
- param_spec = g_param_spec_uint ("type", "TpMediaStreamType",
- "Media stream type",
- 0, NUM_TP_MEDIA_STREAM_TYPES - 1, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_TYPE, param_spec);
-
- param_spec = g_param_spec_uint ("disposition",
- "TpCallContentDisposition",
- "Disposition of the content",
- 0, NUM_TP_CALL_CONTENT_DISPOSITIONS - 1,
- TP_CALL_CONTENT_DISPOSITION_NONE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DISPOSITION, param_spec);
-
- param_spec = g_param_spec_uint ("creator", "Creator's handle",
- "The contact who initiated this content",
- 0, G_MAXUINT32, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATOR, param_spec);
-
- param_spec = g_param_spec_string ("name", "Content name",
- "The name of the content",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_NAME, param_spec);
-
- param_spec = g_param_spec_boxed ("stream-paths", "Stream paths",
- "Streams' object paths",
- TP_ARRAY_TYPE_OBJECT_PATH_LIST,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STREAM_PATHS,
- param_spec);
-
- param_spec = g_param_spec_boxed ("interfaces", "Interfaces",
- "List of D-Bus interfaces",
- G_TYPE_STRV, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
-
- klass->dbus_properties_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (ExampleCallContentClass,
- dbus_properties_class));
}
ExampleCallStream *
example_call_content_get_stream (ExampleCallContent *self)
{
g_return_val_if_fail (EXAMPLE_IS_CALL_CONTENT (self), NULL);
+
return self->priv->stream;
}
-static void
-example_call_content_stream_removed_cb (ExampleCallContent *self,
+void
+example_call_content_add_stream (ExampleCallContent *self,
ExampleCallStream *stream)
{
- GPtrArray *paths;
- gchar *path;
- GValueArray *reason;
-
g_return_if_fail (EXAMPLE_IS_CALL_CONTENT (self));
g_return_if_fail (EXAMPLE_IS_CALL_STREAM (stream));
- g_return_if_fail (self->priv->stream == stream);
+ g_return_if_fail (self->priv->stream == NULL);
- g_object_get (stream,
- "object-path", &path,
- NULL);
- paths = g_ptr_array_sized_new (1);
- g_ptr_array_add (paths, path);
- reason = tp_value_array_build (4,
- G_TYPE_UINT, 0,
- G_TYPE_UINT, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
- G_TYPE_STRING, "",
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
- tp_svc_call_content_emit_streams_removed (self, paths, reason);
- g_free (path);
- g_ptr_array_unref (paths);
- g_value_array_free (reason);
+ self->priv->stream = g_object_ref (stream);
- g_object_unref (self->priv->stream);
- self->priv->stream = NULL;
+ tp_base_call_content_add_stream ((TpBaseCallContent *) self,
+ (TpBaseCallStream *) stream);
}
void
-example_call_content_add_stream (ExampleCallContent *self,
- ExampleCallStream *stream)
+example_call_content_remove_stream (ExampleCallContent *self)
{
- GPtrArray *paths;
- gchar *path;
+ TpBaseCallStream *stream;
g_return_if_fail (EXAMPLE_IS_CALL_CONTENT (self));
- g_return_if_fail (EXAMPLE_IS_CALL_STREAM (stream));
- g_return_if_fail (self->priv->stream == NULL);
+ g_return_if_fail (self->priv->stream != NULL);
- self->priv->stream = g_object_ref (stream);
- g_object_get (stream,
- "object-path", &path,
- NULL);
- paths = g_ptr_array_sized_new (1);
- g_ptr_array_add (paths, path);
- tp_svc_call_content_emit_streams_added (self, paths);
- g_free (path);
- g_ptr_array_unref (paths);
+ stream = (TpBaseCallStream *) self->priv->stream;
+ self->priv->stream = NULL;
+
+ tp_base_call_content_remove_stream ((TpBaseCallContent *) self, stream,
+ 0, TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
- tp_g_signal_connect_object (stream, "removed",
- G_CALLBACK (example_call_content_stream_removed_cb), self,
- G_CONNECT_SWAPPED);
+ g_object_unref (stream);
}
diff --git a/examples/future/call-cm/call-content.h b/examples/future/call-cm/call-content.h
index 4425dfa23..0a380af35 100644
--- a/examples/future/call-cm/call-content.h
+++ b/examples/future/call-cm/call-content.h
@@ -58,14 +58,13 @@ GType example_call_content_get_type (void);
ExampleCallContentClass))
struct _ExampleCallContentClass {
- GObjectClass parent_class;
- TpDBusPropertiesMixinClass dbus_properties_class;
+ TpBaseCallContentClass parent_class;
ExampleCallContentClassPrivate *priv;
};
struct _ExampleCallContent {
- GObject parent;
+ TpBaseCallContent parent;
ExampleCallContentPrivate *priv;
};
@@ -76,6 +75,8 @@ ExampleCallStream *example_call_content_get_stream (ExampleCallContent *self);
void example_call_content_add_stream (ExampleCallContent *self,
ExampleCallStream *stream);
+void example_call_content_remove_stream (ExampleCallContent *self);
+
G_END_DECLS
#endif
diff --git a/examples/future/call-cm/call-manager.c b/examples/future/call-cm/call-manager.c
index 494d6b4d9..69c982744 100644
--- a/examples/future/call-cm/call-manager.c
+++ b/examples/future/call-cm/call-manager.c
@@ -96,7 +96,7 @@ example_call_manager_close_all (ExampleCallManager *self)
g_hash_table_iter_init (&iter, tmp);
while (g_hash_table_iter_next (&iter, NULL, &v))
- example_call_channel_disconnected (v);
+ tp_base_channel_close (v);
g_hash_table_unref (tmp);
}
@@ -333,6 +333,7 @@ new_channel (ExampleCallManager *self,
"simulation-delay", self->priv->simulation_delay,
"initial-audio", initial_audio,
"initial-video", initial_video,
+ "mutable-contents", TRUE,
NULL);
g_free (object_path);
diff --git a/examples/future/call-cm/call-stream.c b/examples/future/call-cm/call-stream.c
index 19dd307eb..9eb2e3526 100644
--- a/examples/future/call-cm/call-stream.c
+++ b/examples/future/call-cm/call-stream.c
@@ -25,51 +25,23 @@
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/svc-call.h>
-static void stream_iface_init (gpointer, gpointer);
-
-G_DEFINE_TYPE_WITH_CODE (ExampleCallStream,
+G_DEFINE_TYPE (ExampleCallStream,
example_call_stream,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CALL_STREAM, stream_iface_init))
+ TP_TYPE_BASE_CALL_STREAM)
enum
{
- PROP_OBJECT_PATH = 1,
- PROP_CONNECTION,
- PROP_INTERFACES,
- PROP_HANDLE,
- PROP_SIMULATION_DELAY,
+ PROP_SIMULATION_DELAY = 1,
PROP_LOCALLY_REQUESTED,
- PROP_LOCAL_SENDING_STATE,
- PROP_REMOTE_MEMBERS,
- PROP_REMOTE_MEMBER_IDENTIFIERS,
+ PROP_HANDLE,
N_PROPS
};
-enum
-{
- SIGNAL_REMOVED,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS] = { 0 };
-
struct _ExampleCallStreamPrivate
{
- gchar *object_path;
- TpBaseConnection *conn;
- TpHandle handle;
- TpSendingState local_sending_state;
- TpSendingState remote_sending_state;
-
guint simulation_delay;
-
- guint connected_event_id;
-
gboolean locally_requested;
- gboolean removed;
+ TpHandle handle;
};
static void
@@ -78,10 +50,6 @@ example_call_stream_init (ExampleCallStream *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EXAMPLE_TYPE_CALL_STREAM,
ExampleCallStreamPrivate);
-
- /* start off directionless */
- self->priv->local_sending_state = TP_SENDING_STATE_NONE;
- self->priv->remote_sending_state = TP_SENDING_STATE_NONE;
}
static void example_call_stream_receive_direction_request (
@@ -99,10 +67,6 @@ constructed (GObject *object)
if (chain_up != NULL)
chain_up (object);
- tp_dbus_daemon_register_object (
- tp_base_connection_get_dbus_daemon (self->priv->conn),
- self->priv->object_path, self);
-
if (self->priv->locally_requested)
{
example_call_stream_change_direction (self, TRUE, TRUE);
@@ -111,18 +75,8 @@ constructed (GObject *object)
{
example_call_stream_receive_direction_request (self, TRUE, TRUE);
}
-
- if (self->priv->handle != 0)
- {
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- tp_handle_ref (contact_repo, self->priv->handle);
- }
}
-static const gchar * const empty_strv[] = { NULL };
-
static void
get_property (GObject *object,
guint property_id,
@@ -133,22 +87,6 @@ get_property (GObject *object,
switch (property_id)
{
- case PROP_OBJECT_PATH:
- g_value_set_string (value, self->priv->object_path);
- break;
-
- case PROP_INTERFACES:
- g_value_set_static_boxed (value, empty_strv);
- break;
-
- case PROP_HANDLE:
- g_value_set_uint (value, self->priv->handle);
- break;
-
- case PROP_CONNECTION:
- g_value_set_object (value, self->priv->conn);
- break;
-
case PROP_SIMULATION_DELAY:
g_value_set_uint (value, self->priv->simulation_delay);
break;
@@ -157,32 +95,8 @@ get_property (GObject *object,
g_value_set_boolean (value, self->priv->locally_requested);
break;
- case PROP_REMOTE_MEMBERS:
- {
- GHashTable *members = g_hash_table_new (NULL, NULL);
-
- g_hash_table_insert (members, GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (self->priv->remote_sending_state));
-
- g_value_take_boxed (value, members);
- }
- break;
-
- case PROP_REMOTE_MEMBER_IDENTIFIERS:
- {
- GHashTable *identifiers = g_hash_table_new (NULL, NULL);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- g_hash_table_insert (identifiers, GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_repo, self->priv->handle));
-
- g_value_take_boxed (value, identifiers);
- }
- break;
-
- case PROP_LOCAL_SENDING_STATE:
- g_value_set_uint (value, self->priv->local_sending_state);
+ case PROP_HANDLE:
+ g_value_set_uint (value, self->priv->handle);
break;
default:
@@ -201,20 +115,6 @@ set_property (GObject *object,
switch (property_id)
{
- case PROP_OBJECT_PATH:
- g_assert (self->priv->object_path == NULL); /* construct-only */
- self->priv->object_path = g_value_dup_string (value);
- break;
-
- case PROP_HANDLE:
- self->priv->handle = g_value_get_uint (value);
- break;
-
- case PROP_CONNECTION:
- g_assert (self->priv->conn == NULL);
- self->priv->conn = g_value_dup_object (value);
- break;
-
case PROP_SIMULATION_DELAY:
self->priv->simulation_delay = g_value_get_uint (value);
break;
@@ -223,95 +123,39 @@ set_property (GObject *object,
self->priv->locally_requested = g_value_get_boolean (value);
break;
+ case PROP_HANDLE:
+ self->priv->handle = g_value_get_uint (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
-static void
-dispose (GObject *object)
-{
- ExampleCallStream *self = EXAMPLE_CALL_STREAM (object);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- example_call_stream_close (self);
-
- if (self->priv->handle != 0)
- {
- tp_handle_unref (contact_repo, self->priv->handle);
- self->priv->handle = 0;
- }
-
- if (self->priv->conn != NULL)
- {
- g_object_unref (self->priv->conn);
- self->priv->conn = NULL;
- }
-
- ((GObjectClass *) example_call_stream_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- ExampleCallStream *self = EXAMPLE_CALL_STREAM (object);
- void (*chain_up) (GObject *) =
- ((GObjectClass *) example_call_stream_parent_class)->finalize;
-
- g_free (self->priv->object_path);
-
- if (chain_up != NULL)
- chain_up (object);
-}
+static gboolean stream_request_receiving (TpBaseCallStream *base,
+ TpHandle contact,
+ gboolean receive,
+ GError **error);
+static gboolean stream_set_sending (TpBaseCallStream *base,
+ gboolean sending,
+ GError **error);
static void
example_call_stream_class_init (ExampleCallStreamClass *klass)
{
- static TpDBusPropertiesMixinPropImpl stream_props[] = {
- { "RemoteMemberIdentifiers", "remote-member-identifiers", NULL },
- { "LocalSendingState", "local-sending-state", NULL },
- { "RemoteMembers", "remote-members", NULL },
- { "Interfaces", "interfaces", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_CALL_STREAM,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- stream_props,
- },
- { NULL }
- };
GObjectClass *object_class = (GObjectClass *) klass;
+ TpBaseCallStreamClass *stream_class = (TpBaseCallStreamClass *) klass;
GParamSpec *param_spec;
- g_type_class_add_private (klass,
- sizeof (ExampleCallStreamPrivate));
+ g_type_class_add_private (klass, sizeof (ExampleCallStreamPrivate));
object_class->constructed = constructed;
object_class->set_property = set_property;
object_class->get_property = get_property;
- object_class->dispose = dispose;
- object_class->finalize = finalize;
-
- param_spec = g_param_spec_string ("object-path", "D-Bus object path",
- "The D-Bus object path used for this object on the bus.", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
-
- param_spec = g_param_spec_object ("connection", "TpBaseConnection",
- "Connection that (indirectly) owns this stream",
- TP_TYPE_BASE_CONNECTION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
- param_spec = g_param_spec_uint ("handle", "Peer's TpHandle",
- "The handle with which this stream communicates or 0 if not applicable",
- 0, G_MAXUINT32, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_HANDLE, param_spec);
+ stream_class->request_receiving = stream_request_receiving;
+ stream_class->set_sending = stream_set_sending;
param_spec = g_param_spec_uint ("simulation-delay", "Simulation delay",
"Delay between simulated network events",
@@ -320,13 +164,6 @@ example_call_stream_class_init (ExampleCallStreamClass *klass)
g_object_class_install_property (object_class, PROP_SIMULATION_DELAY,
param_spec);
- param_spec = g_param_spec_boxed ("remote-member-identifiers", "RemoteMemberIdentifiers",
- "Map from contact handles to their identifiers",
- TP_HASH_TYPE_HANDLE_IDENTIFIER_MAP,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_REMOTE_MEMBER_IDENTIFIERS,
- param_spec);
-
param_spec = g_param_spec_boolean ("locally-requested", "Locally requested?",
"True if this channel was requested by the local user",
FALSE,
@@ -334,120 +171,42 @@ example_call_stream_class_init (ExampleCallStreamClass *klass)
g_object_class_install_property (object_class, PROP_LOCALLY_REQUESTED,
param_spec);
- param_spec = g_param_spec_boxed ("remote-members", "RemoteMembers",
- "Map from contact handles to their sending states",
- TP_HASH_TYPE_CONTACT_SENDING_STATE_MAP,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_REMOTE_MEMBERS,
- param_spec);
-
- param_spec = g_param_spec_boxed ("interfaces", "Interfaces",
- "List of D-Bus interfaces",
- G_TYPE_STRV, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
-
- param_spec = g_param_spec_uint ("local-sending-state", "LocalSendingState",
- "Local sending state",
- 0, NUM_TP_SENDING_STATES, TP_SENDING_STATE_NONE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_LOCAL_SENDING_STATE,
- param_spec);
-
- signals[SIGNAL_REMOVED] = g_signal_new ("removed",
- G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- klass->dbus_properties_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (ExampleCallStreamClass,
- dbus_properties_class));
-}
-
-void
-example_call_stream_close (ExampleCallStream *self)
-{
- if (!self->priv->removed)
- {
- self->priv->removed = TRUE;
-
- g_message ("%s: Sending to server: Closing stream",
- self->priv->object_path);
-
- if (self->priv->connected_event_id != 0)
- {
- g_source_remove (self->priv->connected_event_id);
- }
-
- /* this has to come last, because the MediaChannel may unref us in
- * response to the removed signal */
- g_signal_emit (self, signals[SIGNAL_REMOVED], 0);
- }
+ param_spec = g_param_spec_uint ("handle", "Peer's TpHandle",
+ "The handle with which this stream communicates or 0 if not applicable",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_HANDLE, param_spec);
}
void
example_call_stream_accept_proposed_direction (ExampleCallStream *self)
{
- GValueArray *reason;
+ TpBaseCallStream *base = (TpBaseCallStream *) self;
+ TpSendingState state = tp_base_call_stream_get_local_sending_state (base);
- if (self->priv->removed ||
- self->priv->local_sending_state != TP_SENDING_STATE_PENDING_SEND)
+ if (state != TP_SENDING_STATE_PENDING_SEND)
return;
- g_message ("%s: SIGNALLING: Sending to server: OK, I'll send you media",
- self->priv->object_path);
-
- self->priv->local_sending_state = TP_SENDING_STATE_SENDING;
- reason = tp_value_array_build (4,
- G_TYPE_UINT, 0,
- G_TYPE_UINT, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
- G_TYPE_STRING, "",
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
- tp_svc_call_stream_emit_local_sending_state_changed (self,
- self->priv->local_sending_state, reason);
- g_value_array_free (reason);
+ tp_base_call_stream_update_local_sending_state (base,
+ TP_SENDING_STATE_SENDING, 0, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
+ "", "");
}
void
example_call_stream_simulate_contact_agreed_to_send (ExampleCallStream *self)
{
- GHashTable *updated_members, *identifiers;
- GArray *removed_members;
- GValueArray *reason;
- TpHandleRepoIface *contact_handles;
+ TpBaseCallStream *base = (TpBaseCallStream *) self;
+ TpSendingState state = tp_base_call_stream_get_remote_sending_state (base,
+ self->priv->handle);
- if (self->priv->removed ||
- self->priv->remote_sending_state != TP_SENDING_STATE_PENDING_SEND)
- return;
+ if (state != TP_SENDING_STATE_PENDING_SEND)
+
+ g_message ("%s: SIGNALLING: Sending to server: OK, I'll send you media",
+ tp_base_call_stream_get_object_path (base));
- contact_handles = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- g_message ("%s: SIGNALLING: received: OK, I'll send you media",
- self->priv->object_path);
-
- self->priv->remote_sending_state = TP_SENDING_STATE_SENDING;
-
- updated_members = g_hash_table_new (NULL, NULL);
- removed_members = g_array_sized_new (FALSE, FALSE, sizeof (guint), 0);
- identifiers = g_hash_table_new (NULL, NULL);
- g_hash_table_insert (updated_members, GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (TP_SENDING_STATE_SENDING));
- g_hash_table_insert (identifiers, GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_handles, self->priv->handle));
- reason = tp_value_array_build (4,
- G_TYPE_UINT, 0,
- G_TYPE_UINT, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
- G_TYPE_STRING, "",
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
- tp_svc_call_stream_emit_remote_members_changed (self, updated_members,
- identifiers, removed_members, reason);
- g_hash_table_unref (updated_members);
- g_hash_table_unref (identifiers);
- g_array_unref (removed_members);
- g_value_array_free (reason);
+ tp_base_call_stream_update_remote_sending_state ((TpBaseCallStream *) self,
+ self->priv->handle, TP_SENDING_STATE_SENDING, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
}
static gboolean
@@ -461,111 +220,86 @@ static void
example_call_stream_change_direction (ExampleCallStream *self,
gboolean want_to_send, gboolean want_to_receive)
{
- GHashTable *updated_members = g_hash_table_new (NULL, NULL);
- GHashTable *updated_member_identifiers = g_hash_table_new (NULL, NULL);
- GValueArray *reason = tp_value_array_build (4,
- G_TYPE_UINT, 0,
- G_TYPE_UINT, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
- G_TYPE_STRING, "",
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
+ TpBaseCallStream *base = (TpBaseCallStream *) self;
+ TpSendingState local_sending_state =
+ tp_base_call_stream_get_local_sending_state (base);
+ TpSendingState remote_sending_state =
+ tp_base_call_stream_get_remote_sending_state (base, self->priv->handle);
if (want_to_send)
{
- if (self->priv->local_sending_state != TP_SENDING_STATE_SENDING)
+ if (local_sending_state != TP_SENDING_STATE_SENDING)
{
- if (self->priv->local_sending_state ==
- TP_SENDING_STATE_PENDING_SEND)
+ if (local_sending_state == TP_SENDING_STATE_PENDING_SEND)
{
g_message ("%s: SIGNALLING: send: I will now send you media",
- self->priv->object_path);
+ tp_base_call_stream_get_object_path (base));
}
g_message ("%s: MEDIA: sending media to peer",
- self->priv->object_path);
- self->priv->local_sending_state = TP_SENDING_STATE_SENDING;
- tp_svc_call_stream_emit_local_sending_state_changed (self,
- self->priv->local_sending_state, reason);
+ tp_base_call_stream_get_object_path (base));
+
+ tp_base_call_stream_update_local_sending_state (base,
+ TP_SENDING_STATE_SENDING, 0, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
+ "", "");
}
}
else
{
- if (self->priv->local_sending_state == TP_SENDING_STATE_SENDING)
+ if (local_sending_state == TP_SENDING_STATE_SENDING)
{
g_message ("%s: SIGNALLING: send: I will no longer send you media",
- self->priv->object_path);
+ tp_base_call_stream_get_object_path (base));
g_message ("%s: MEDIA: no longer sending media to peer",
- self->priv->object_path);
- self->priv->local_sending_state = TP_SENDING_STATE_NONE;
- tp_svc_call_stream_emit_local_sending_state_changed (self,
- self->priv->local_sending_state, reason);
+ tp_base_call_stream_get_object_path (base));
+
+ tp_base_call_stream_update_local_sending_state (base,
+ TP_SENDING_STATE_NONE, 0, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
+ "", "");
}
- else if (self->priv->local_sending_state ==
- TP_SENDING_STATE_PENDING_SEND)
+ else if (local_sending_state == TP_SENDING_STATE_PENDING_SEND)
{
g_message ("%s: SIGNALLING: send: refusing to send you media",
- self->priv->object_path);
- self->priv->local_sending_state = TP_SENDING_STATE_NONE;
- tp_svc_call_stream_emit_local_sending_state_changed (self,
- self->priv->local_sending_state, reason);
+ tp_base_call_stream_get_object_path (base));
+
+ tp_base_call_stream_update_local_sending_state (base,
+ TP_SENDING_STATE_NONE, 0, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
+ "", "");
}
}
if (want_to_receive)
{
- if (self->priv->remote_sending_state == TP_SENDING_STATE_NONE)
+ if (remote_sending_state == TP_SENDING_STATE_NONE)
{
g_message ("%s: SIGNALLING: send: send me media, please?",
- self->priv->object_path);
- self->priv->remote_sending_state = TP_SENDING_STATE_PENDING_SEND;
+ tp_base_call_stream_get_object_path (base));
+
+ tp_base_call_stream_update_remote_sending_state (
+ (TpBaseCallStream *) self,
+ self->priv->handle, TP_SENDING_STATE_PENDING_SEND, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
+
g_timeout_add_full (G_PRIORITY_DEFAULT, self->priv->simulation_delay,
simulate_contact_agreed_to_send_cb, g_object_ref (self),
g_object_unref);
-
- g_hash_table_insert (updated_members,
- GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (TP_SENDING_STATE_PENDING_SEND));
- g_hash_table_insert (updated_member_identifiers,
- GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_repo, self->priv->handle));
}
}
else
{
- if (self->priv->remote_sending_state != TP_SENDING_STATE_NONE)
+ if (remote_sending_state != TP_SENDING_STATE_NONE)
{
g_message ("%s: SIGNALLING: send: Please stop sending me media",
- self->priv->object_path);
+ tp_base_call_stream_get_object_path (base));
g_message ("%s: MEDIA: suppressing output of stream",
- self->priv->object_path);
- self->priv->remote_sending_state = TP_SENDING_STATE_NONE;
-
- g_hash_table_insert (updated_members,
- GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (TP_SENDING_STATE_NONE));
- g_hash_table_insert (updated_member_identifiers,
- GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_repo, self->priv->handle));
- }
- }
-
- if (g_hash_table_size (updated_members) != 0)
- {
- GArray *removed_members = g_array_sized_new (FALSE, FALSE,
- sizeof (guint), 0);
+ tp_base_call_stream_get_object_path (base));
- tp_svc_call_stream_emit_remote_members_changed (self,
- updated_members, updated_member_identifiers,
- removed_members, reason);
-
- g_array_unref (removed_members);
+ tp_base_call_stream_update_remote_sending_state (
+ (TpBaseCallStream *) self,
+ self->priv->handle, TP_SENDING_STATE_NONE, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
+ }
}
-
- g_hash_table_unref (updated_members);
- g_hash_table_unref (updated_member_identifiers);
- g_value_array_free (reason);
}
/* The remote user wants to change the direction of this stream according
@@ -575,16 +309,12 @@ example_call_stream_receive_direction_request (ExampleCallStream *self,
gboolean local_send,
gboolean remote_send)
{
- GHashTable *updated_members = g_hash_table_new (NULL, NULL);
- GHashTable *updated_member_identifiers = g_hash_table_new (NULL, NULL);
- GValueArray *reason = tp_value_array_build (4,
- G_TYPE_UINT, 0,
- G_TYPE_UINT, TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
- G_TYPE_STRING, "",
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
+ TpBaseCallStream *base = (TpBaseCallStream *) self;
+ TpSendingState local_sending_state =
+ tp_base_call_stream_get_local_sending_state (base);
+ TpSendingState remote_sending_state =
+ tp_base_call_stream_get_remote_sending_state (base, self->priv->handle);
+
/* In some protocols, streams cannot be neither sending nor receiving, so
* if a stream is set to TP_MEDIA_STREAM_DIRECTION_NONE, this is equivalent
* to removing it. (This is true in XMPP, for instance.)
@@ -596,14 +326,15 @@ example_call_stream_receive_direction_request (ExampleCallStream *self,
if (local_send)
{
g_message ("%s: SIGNALLING: send: Please start sending me media",
- self->priv->object_path);
+ tp_base_call_stream_get_object_path (base));
- if (self->priv->local_sending_state == TP_SENDING_STATE_NONE)
+ if (local_sending_state == TP_SENDING_STATE_NONE)
{
/* ask the user for permission */
- self->priv->local_sending_state = TP_SENDING_STATE_PENDING_SEND;
- tp_svc_call_stream_emit_local_sending_state_changed (self,
- self->priv->local_sending_state, reason);
+ tp_base_call_stream_update_local_sending_state (base,
+ TP_SENDING_STATE_PENDING_SEND, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
+ "", "");
}
else
{
@@ -614,24 +345,26 @@ example_call_stream_receive_direction_request (ExampleCallStream *self,
else
{
g_message ("%s: SIGNALLING: receive: Please stop sending me media",
- self->priv->object_path);
+ tp_base_call_stream_get_object_path (base));
g_message ("%s: SIGNALLING: reply: OK!",
- self->priv->object_path);
+ tp_base_call_stream_get_object_path (base));
- if (self->priv->local_sending_state == TP_SENDING_STATE_SENDING)
+ if (local_sending_state == TP_SENDING_STATE_SENDING)
{
g_message ("%s: MEDIA: no longer sending media to peer",
- self->priv->object_path);
- self->priv->local_sending_state = TP_SENDING_STATE_NONE;
- tp_svc_call_stream_emit_local_sending_state_changed (self,
- self->priv->local_sending_state, reason);
+ tp_base_call_stream_get_object_path (base));
+
+ tp_base_call_stream_update_local_sending_state (base,
+ TP_SENDING_STATE_NONE, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
+ "", "");
}
- else if (self->priv->local_sending_state ==
- TP_SENDING_STATE_PENDING_SEND)
+ else if (local_sending_state == TP_SENDING_STATE_PENDING_SEND)
{
- self->priv->local_sending_state = TP_SENDING_STATE_NONE;
- tp_svc_call_stream_emit_local_sending_state_changed (self,
- self->priv->local_sending_state, reason);
+ tp_base_call_stream_update_local_sending_state (base,
+ TP_SENDING_STATE_NONE, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN,
+ "", "");
}
else
{
@@ -642,131 +375,72 @@ example_call_stream_receive_direction_request (ExampleCallStream *self,
if (remote_send)
{
g_message ("%s: SIGNALLING: receive: I will now send you media",
- self->priv->object_path);
+ tp_base_call_stream_get_object_path (base));
- if (self->priv->remote_sending_state != TP_SENDING_STATE_SENDING)
+ if (remote_sending_state != TP_SENDING_STATE_SENDING)
{
- self->priv->remote_sending_state = TP_SENDING_STATE_SENDING;
-
- g_hash_table_insert (updated_members,
- GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (TP_SENDING_STATE_SENDING));
- g_hash_table_insert (updated_member_identifiers,
- GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_repo, self->priv->handle));
+ tp_base_call_stream_update_remote_sending_state (
+ (TpBaseCallStream *) self,
+ self->priv->handle, TP_SENDING_STATE_SENDING, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
}
}
else
{
- if (self->priv->remote_sending_state ==
- TP_SENDING_STATE_PENDING_SEND)
+ if (remote_sending_state == TP_SENDING_STATE_PENDING_SEND)
{
g_message ("%s: SIGNALLING: receive: No, I refuse to send you media",
- self->priv->object_path);
- self->priv->remote_sending_state = TP_SENDING_STATE_NONE;
-
- g_hash_table_insert (updated_members,
- GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (TP_SENDING_STATE_NONE));
- g_hash_table_insert (updated_member_identifiers,
- GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_repo, self->priv->handle));
+ tp_base_call_stream_get_object_path (base));
+
+ tp_base_call_stream_update_remote_sending_state (
+ (TpBaseCallStream *) self,
+ self->priv->handle, TP_SENDING_STATE_NONE, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
}
- else if (self->priv->remote_sending_state ==
- TP_SENDING_STATE_SENDING)
+ else if (remote_sending_state == TP_SENDING_STATE_SENDING)
{
g_message ("%s: SIGNALLING: receive: I will no longer send media",
- self->priv->object_path);
- self->priv->remote_sending_state = TP_SENDING_STATE_NONE;
-
- g_hash_table_insert (updated_members,
- GUINT_TO_POINTER (self->priv->handle),
- GUINT_TO_POINTER (TP_SENDING_STATE_NONE));
- g_hash_table_insert (updated_member_identifiers,
- GUINT_TO_POINTER (self->priv->handle),
- (gpointer) tp_handle_inspect (contact_repo, self->priv->handle));
- }
- }
-
- if (g_hash_table_size (updated_members) != 0)
- {
- GArray *removed_members = g_array_sized_new (FALSE, FALSE,
- sizeof (guint), 0);
+ tp_base_call_stream_get_object_path (base));
- tp_svc_call_stream_emit_remote_members_changed (self,
- updated_members, updated_member_identifiers,
- removed_members, reason);
-
- g_array_unref (removed_members);
+ tp_base_call_stream_update_remote_sending_state (
+ (TpBaseCallStream *) self,
+ self->priv->handle, TP_SENDING_STATE_NONE, 0,
+ TP_CALL_STATE_CHANGE_REASON_UNKNOWN, "", "");
+ }
}
-
- g_hash_table_unref (updated_members);
- g_hash_table_unref (updated_member_identifiers);
- g_value_array_free (reason);
}
-static void
-stream_set_sending (TpSvcCallStream *iface G_GNUC_UNUSED,
+static gboolean
+stream_set_sending (TpBaseCallStream *base,
gboolean sending,
- DBusGMethodInvocation *context)
+ GError **error)
{
- ExampleCallStream *self = EXAMPLE_CALL_STREAM (iface);
+ ExampleCallStream *self = EXAMPLE_CALL_STREAM (base);
+ TpSendingState remote_sending_state =
+ tp_base_call_stream_get_remote_sending_state (base, self->priv->handle);
example_call_stream_change_direction (self, sending,
- (self->priv->remote_sending_state == TP_SENDING_STATE_SENDING));
+ (remote_sending_state == TP_SENDING_STATE_SENDING));
- tp_svc_call_stream_return_from_set_sending (context);
+ return TRUE;
}
-static void
-stream_request_receiving (TpSvcCallStream *iface,
+static gboolean
+stream_request_receiving (TpBaseCallStream *base,
TpHandle contact,
gboolean receive,
- DBusGMethodInvocation *context)
+ GError **error)
{
- ExampleCallStream *self = EXAMPLE_CALL_STREAM (iface);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
- (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
- GError *error = NULL;
+ ExampleCallStream *self = EXAMPLE_CALL_STREAM (base);
+ TpSendingState local_sending_state =
+ tp_base_call_stream_get_local_sending_state (base);
- if (!tp_handle_is_valid (contact_repo, contact, &error))
- {
- goto finally;
- }
-
- if (contact != self->priv->handle)
- {
- g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "Can't receive from contact #%u: this stream only contains #%u",
- contact, self->priv->handle);
- goto finally;
- }
+ /* This is the only member */
+ g_assert (contact == self->priv->handle);
example_call_stream_change_direction (self,
- (self->priv->local_sending_state == TP_SENDING_STATE_SENDING),
+ (local_sending_state == TP_SENDING_STATE_SENDING),
receive);
-finally:
- if (error == NULL)
- {
- tp_svc_call_stream_return_from_request_receiving (context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-static void
-stream_iface_init (gpointer iface,
- gpointer data)
-{
- TpSvcCallStreamClass *klass = iface;
-
-#define IMPLEMENT(x) \
- tp_svc_call_stream_implement_##x (klass, stream_##x)
- IMPLEMENT (set_sending);
- IMPLEMENT (request_receiving);
-#undef IMPLEMENT
+ return TRUE;
}
diff --git a/examples/future/call-cm/call-stream.h b/examples/future/call-cm/call-stream.h
index e3093202e..0d705da2f 100644
--- a/examples/future/call-cm/call-stream.h
+++ b/examples/future/call-cm/call-stream.h
@@ -56,19 +56,18 @@ GType example_call_stream_get_type (void);
ExampleCallStreamClass))
struct _ExampleCallStreamClass {
- GObjectClass parent_class;
+ TpBaseCallStreamClass parent_class;
TpDBusPropertiesMixinClass dbus_properties_class;
ExampleCallStreamClassPrivate *priv;
};
struct _ExampleCallStream {
- GObject parent;
+ TpBaseCallStream parent;
ExampleCallStreamPrivate *priv;
};
-void example_call_stream_close (ExampleCallStream *self);
void example_call_stream_accept_proposed_direction (ExampleCallStream *self);
void example_call_stream_connect (ExampleCallStream *self);