summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Swindell <t.swindell@rubyx.co.uk>2013-03-03 11:28:06 +0000
committerTom Swindell <t.swindell@rubyx.co.uk>2013-03-03 11:28:06 +0000
commit428422824318778129585c0dfd0aac368f9bdf0d (patch)
treea340cb0289b78edb309f74886e775befb8c17c20
parentab3b6d31cf41a0d1578d5f5f788f63d68945e0ee (diff)
Migrate RingMediaChannel to use TpBaseChannel
Signed-off-by: Tom Swindell <t.swindell@rubyx.co.uk>
-rw-r--r--src/ring-call-channel.c136
-rw-r--r--src/ring-conference-channel.c62
-rw-r--r--src/ring-conference-channel.h5
-rw-r--r--src/ring-media-channel.c323
-rw-r--r--src/ring-media-channel.h19
-rw-r--r--src/ring-media-manager.c6
6 files changed, 425 insertions, 126 deletions
diff --git a/src/ring-call-channel.c b/src/ring-call-channel.c
index a86f2af..95d3a9c 100644
--- a/src/ring-call-channel.c
+++ b/src/ring-call-channel.c
@@ -87,6 +87,7 @@ struct _RingCallChannelPrivate
char *initial_emergency_service;
TpHandle peer_handle, initial_remote;
+ TpHandle initiator, target;
char *accepted;
@@ -127,6 +128,15 @@ struct _RingCallChannelPrivate
enum
{
PROP_NONE,
+ PROP_CHANNEL_PROPERTIES,
+ PROP_INTERFACES,
+
+ PROP_TARGET,
+ PROP_TARGET_ID,
+ PROP_TARGET_TYPE,
+
+ PROP_INITIATOR,
+ PROP_INITIATOR_ID,
PROP_ANON_MODES,
@@ -173,6 +183,7 @@ static gboolean ring_call_channel_remote_pending(
G_DEFINE_TYPE_WITH_CODE(
RingCallChannel, ring_call_channel, RING_TYPE_MEDIA_CHANNEL,
G_IMPLEMENT_INTERFACE(RING_TYPE_MEMBER_CHANNEL, NULL);
+ G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_DBUS_PROPERTIES, tp_dbus_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
tp_group_mixin_iface_init);
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_INTERFACE_CALL_STATE,
@@ -191,8 +202,7 @@ const char *ring_call_channel_interfaces[] = {
NULL
};
-static void ring_call_channel_fill_immutable_properties(TpBaseChannel *base,
- GHashTable *props);
+static GHashTable *ring_call_channel_properties(RingCallChannel *self);
static void ring_call_channel_update_state(RingMediaChannel *_self,
guint state, guint causetype, guint cause);
@@ -253,15 +263,22 @@ ring_call_channel_constructed(GObject *object)
{
RingCallChannel *self = RING_CALL_CHANNEL(object);
RingCallChannelPrivate *priv = self->priv;
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
- TpBaseConnection *connection = tp_base_channel_get_connection (base);
+ TpBaseConnection *connection = NULL;
+ TpHandleRepoIface *repo;
TpHandle self_handle;
if (G_OBJECT_CLASS(ring_call_channel_parent_class)->constructed)
G_OBJECT_CLASS(ring_call_channel_parent_class)->constructed(object);
+ connection = TP_BASE_CONNECTION(self->base.connection);
+ repo = tp_base_connection_get_handles(connection, TP_HANDLE_TYPE_CONTACT);
+ if (priv->target)
+ tp_handle_ref(repo, priv->target);
+
+ tp_handle_ref(repo, priv->initiator);
+
if (priv->peer_handle != 0)
- g_assert(priv->peer_handle == tp_base_channel_get_target_handle (base));
+ g_assert(priv->peer_handle == priv->target);
self_handle = tp_base_connection_get_self_handle(connection);
@@ -279,7 +296,6 @@ ring_call_channel_emit_initial(RingMediaChannel *_self)
TpGroupMixin *mixin = TP_GROUP_MIXIN(_self);
RingCallChannel *self = RING_CALL_CHANNEL(_self);
RingCallChannelPrivate *priv = self->priv;
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
TpHandle self_handle = mixin->self_handle;
TpIntSet *member_set = tp_intset_new();
TpIntSet *local_pending_set = NULL, *remote_pending_set = NULL;
@@ -287,9 +303,9 @@ ring_call_channel_emit_initial(RingMediaChannel *_self)
TpChannelGroupChangeReason reason = 0;
TpChannelGroupFlags add = 0, del = 0;
- tp_intset_add(member_set, tp_base_channel_get_initiator (base));
+ tp_intset_add(member_set, priv->initiator);
- if (!tp_base_channel_is_requested (base)) {
+ if (priv->initiator == priv->target) {
/* Incoming call */
message = "Channel created for incoming call";
reason = TP_CHANNEL_GROUP_CHANGE_REASON_INVITED;
@@ -308,7 +324,7 @@ ring_call_channel_emit_initial(RingMediaChannel *_self)
/* Outgoing call, but without handle */
message = "Channel created";
reason = TP_CHANNEL_GROUP_CHANGE_REASON_NONE;
- if (tp_base_channel_get_target_handle (base) == 0)
+ if (priv->target == 0)
add |= TP_CHANNEL_GROUP_FLAG_CAN_ADD;
}
@@ -321,7 +337,7 @@ ring_call_channel_emit_initial(RingMediaChannel *_self)
tp_group_mixin_change_members(G_OBJECT(self), message,
member_set, NULL,
local_pending_set, remote_pending_set,
- tp_base_channel_get_initiator (base), reason);
+ priv->initiator, reason);
tp_intset_destroy(member_set);
if (local_pending_set) tp_intset_destroy(local_pending_set);
@@ -336,8 +352,32 @@ ring_call_channel_get_property(GObject *obj,
{
RingCallChannel *self = RING_CALL_CHANNEL(obj);
RingCallChannelPrivate *priv = self->priv;
+ char const *id;
switch (property_id) {
+ case PROP_CHANNEL_PROPERTIES:
+ g_value_take_boxed(value, ring_call_channel_properties(self));
+ break;
+ case PROP_INTERFACES:
+ g_value_set_boxed(value, ring_call_channel_interfaces);
+ break;
+ case PROP_TARGET:
+ g_value_set_uint(value, priv->target);
+ break;
+ case PROP_TARGET_TYPE:
+ g_value_set_uint(value, priv->target ? TP_HANDLE_TYPE_CONTACT : TP_HANDLE_TYPE_NONE);
+ break;
+ case PROP_TARGET_ID:
+ id = ring_connection_inspect_contact(self->base.connection, priv->target);
+ g_value_set_string(value, id);
+ break;
+ case PROP_INITIATOR:
+ g_value_set_uint(value, priv->initiator);
+ break;
+ case PROP_INITIATOR_ID:
+ id = ring_connection_inspect_contact(self->base.connection, priv->initiator);
+ g_value_set_string(value, id);
+ break;
case PROP_ANON_MODES:
g_value_set_uint(value, priv->anon_modes);
break;
@@ -400,12 +440,17 @@ ring_call_channel_set_property(GObject *obj,
{
RingCallChannel *self = RING_CALL_CHANNEL(obj);
RingCallChannelPrivate *priv = self->priv;
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
switch (property_id) {
case PROP_ANON_MODES:
priv->anon_modes = g_value_get_uint(value);
break;
+ case PROP_TARGET:
+ priv->target = g_value_get_uint(value);
+ break;
+ case PROP_INITIATOR:
+ priv->initiator = g_value_get_uint(value);
+ break;
case PROP_ORIGINATING:
priv->originating = g_value_get_boolean(value);
break;
@@ -417,8 +462,7 @@ ring_call_channel_set_property(GObject *obj,
break;
case PROP_PEER:
if (priv->peer_handle == 0) {
- if (tp_base_channel_get_target_handle (base) == 0 ||
- tp_base_channel_get_target_handle (base) == g_value_get_uint(value))
+ if (priv->target == 0 || priv->target == g_value_get_uint(value))
priv->peer_handle = g_value_get_uint(value);
}
break;
@@ -436,7 +480,6 @@ ring_call_channel_dispose(GObject *object)
{
RingCallChannel *self = RING_CALL_CHANNEL(object);
RingCallChannelPrivate *priv = self->priv;
- TpBaseChannel *base = TP_BASE_CHANNEL (object);
if (self->priv->disposed)
return;
@@ -444,7 +487,7 @@ ring_call_channel_dispose(GObject *object)
if (priv->member.handle) {
TpHandleRepoIface *repo = tp_base_connection_get_handles(
- tp_base_channel_get_connection (base), TP_HANDLE_TYPE_CONTACT);
+ (TpBaseConnection*)(self->base.connection), TP_HANDLE_TYPE_CONTACT);
tp_handle_unref(repo, priv->member.handle);
priv->member.handle = 0;
}
@@ -479,7 +522,6 @@ static void
ring_call_channel_class_init(RingCallChannelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
- TpBaseChannelClass *base_chan_class = TP_BASE_CHANNEL_CLASS (klass);
g_type_class_add_private(klass, sizeof (RingCallChannelPrivate));
@@ -489,10 +531,6 @@ ring_call_channel_class_init(RingCallChannelClass *klass)
object_class->dispose = ring_call_channel_dispose;
object_class->finalize = ring_call_channel_finalize;
- base_chan_class->interfaces = ring_call_channel_interfaces;
- base_chan_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
- base_chan_class->fill_immutable_properties = ring_call_channel_fill_immutable_properties;
-
ring_call_channel_implement_media_channel (RING_MEDIA_CHANNEL_CLASS(klass));
klass->dbus_properties_class.interfaces =
@@ -509,6 +547,27 @@ ring_call_channel_class_init(RingCallChannelClass *klass)
tp_group_mixin_class_set_remove_with_reason_func(
object_class, ring_call_channel_remove_member_with_reason);
+ g_object_class_override_property(
+ object_class, PROP_CHANNEL_PROPERTIES, "channel-properties");
+
+ g_object_class_override_property(
+ object_class, PROP_INTERFACES, "interfaces");
+
+ g_object_class_override_property(
+ object_class, PROP_TARGET_TYPE, "handle-type");
+
+ g_object_class_override_property(
+ object_class, PROP_TARGET, "handle");
+
+ g_object_class_override_property(
+ object_class, PROP_TARGET_ID, "handle-id");
+
+ g_object_class_override_property(
+ object_class, PROP_INITIATOR, "initiator");
+
+ g_object_class_override_property(
+ object_class, PROP_INITIATOR_ID, "initiator-id");
+
g_object_class_install_property(
object_class, PROP_ANON_MODES, ring_param_spec_anon_modes());
@@ -608,24 +667,23 @@ ring_call_channel_dbus_property_interfaces[] = {
{ NULL }
};
-static void
-ring_call_channel_fill_immutable_properties(TpBaseChannel *base,
- GHashTable *props)
+static GHashTable*
+ring_call_channel_properties(RingCallChannel *self)
{
- RingCallChannel *self = RING_CALL_CHANNEL (base);
- GObject *obj = (GObject *) self;
+ GHashTable *properties;
- TP_BASE_CHANNEL_CLASS (ring_call_channel_parent_class)->fill_immutable_properties (
- base, props);
+ properties = ring_media_channel_properties(RING_MEDIA_CHANNEL(self));
- tp_dbus_properties_mixin_fill_properties_hash (obj, props,
+ ring_channel_add_properties(self, properties,
TP_IFACE_CHANNEL_INTERFACE_SERVICE_POINT, "CurrentServicePoint",
NULL);
if (!RING_STR_EMPTY(self->priv->initial_emergency_service))
- tp_dbus_properties_mixin_fill_properties_hash (obj, props,
+ ring_channel_add_properties(self, properties,
TP_IFACE_CHANNEL_INTERFACE_SERVICE_POINT, "InitialServicePoint",
NULL);
+
+ return properties;
}
/* ====================================================================== */
@@ -812,7 +870,6 @@ ring_call_channel_validate_media_handle (gpointer _self,
DEBUG("enter");
RingCallChannel *self = RING_CALL_CHANNEL(_self);
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
TpGroupMixin *mixin = TP_GROUP_MIXIN(self);
TpHandleRepoIface *repo;
RingCallChannelPrivate *priv = self->priv;
@@ -823,10 +880,10 @@ ring_call_channel_validate_media_handle (gpointer _self,
if (handle == 0)
handle = priv->peer_handle;
if (handle == 0)
- handle = tp_base_channel_get_target_handle (base);
+ handle = priv->target;
repo = tp_base_connection_get_handles(
- tp_base_channel_get_connection(base), TP_HANDLE_TYPE_CONTACT);
+ (TpBaseConnection*)(self->base.connection), TP_HANDLE_TYPE_CONTACT);
if (!tp_handle_is_valid(repo, handle, error))
return FALSE;
@@ -846,7 +903,7 @@ ring_call_channel_validate_media_handle (gpointer _self,
if (!tp_handle_set_is_member(self->group.members, handle) &&
!tp_handle_set_is_member(self->group.remote_pending, handle) &&
- handle != tp_base_channel_get_target_handle (base)) {
+ handle != priv->target) {
g_set_error(error,
TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
"given handle %u is not a member of the channel",
@@ -987,7 +1044,6 @@ reply_to_modem_call_request_dial(ModemCallService *_service,
{
RingCallChannel *self = RING_CALL_CHANNEL(_channel);
RingCallChannelPrivate *priv = self->priv;
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
GError *error0 = NULL;
TpChannelGroupChangeReason reason;
char *debug;
@@ -1006,9 +1062,7 @@ reply_to_modem_call_request_dial(ModemCallService *_service,
manager = modem_request_get_qdata(request, g_type_qname(RING_TYPE_MEDIA_MANAGER));
if (ci)
- g_object_set(self,
- "initial-remote", tp_base_channel_get_target_handle (base),
- NULL);
+ g_object_set(self, "initial-remote", priv->target, NULL);
ring_media_manager_emit_new_channel(manager, channelrequest, self, NULL);
}
@@ -1308,9 +1362,7 @@ ring_call_channel_request_remote(GObject *iface,
RingCallChannel *self = RING_CALL_CHANNEL(iface);
char const *destination;
- destination = ring_connection_inspect_contact(
- RING_CONNECTION(tp_base_channel_get_connection(TP_BASE_CHANNEL(self))),
- handle);
+ destination = ring_connection_inspect_contact(self->base.connection, handle);
DEBUG("Trying to add %u=\"%s\" to remote pending", handle, destination);
@@ -1781,9 +1833,7 @@ ring_call_channel_get_member_handle(RingCallChannel *self)
TpHandle owner = priv->peer_handle;
if (handle == 0) {
- TpHandleRepoIface *repo = tp_base_connection_get_handles(
- tp_base_channel_get_connection(TP_BASE_CHANNEL(self)),
- TP_HANDLE_TYPE_CONTACT);
+ TpHandleRepoIface *repo = tp_base_connection_get_handles(self->base.connection, TP_HANDLE_TYPE_CONTACT);
gpointer context = ring_network_normalization_context();
char *object_path, *unique, *membername;
diff --git a/src/ring-conference-channel.c b/src/ring-conference-channel.c
index ca22fba..88e3fed 100644
--- a/src/ring-conference-channel.c
+++ b/src/ring-conference-channel.c
@@ -101,7 +101,7 @@ struct _RingConferenceChannelPrivate
gboolean requested;
} hold;
- unsigned streams_created:1, conf_created:1, hangup:1, closing:1, disposed:1, :0;
+ unsigned streams_created:1, conf_created:1, hangup:1, closing:1, closed:1, disposed:1, :0;
};
/* properties */
@@ -109,7 +109,11 @@ enum
{
PROP_NONE,
+ /* telepathy-glib properties */
+ PROP_CHANNEL_PROPERTIES,
+
/* o.f.T.Channel.Interfaces */
+ PROP_INTERFACES,
PROP_INITIAL_CHANNELS,
PROP_CHANNELS,
@@ -140,8 +144,7 @@ static gboolean ring_conference_channel_remove_member_with_reason(
static GPtrArray *ring_conference_get_channels(
RingConferenceChannel const *self);
-static void ring_conference_channel_fill_immutable_properties(TpBaseChannel *base,
- GHashTable *props);
+static GHashTable* ring_conference_channel_properties(RingConferenceChannel *self);
static void ring_conference_channel_emit_channel_merged(
RingConferenceChannel *channel,
@@ -163,7 +166,7 @@ static gboolean ring_conference_channel_create_streams(RingConferenceChannel *_s
/* GObject interface */
G_DEFINE_TYPE_WITH_CODE(
- RingConferenceChannel, ring_conference_channel, TP_TYPE_BASE_CHANNEL,
+ RingConferenceChannel, ring_conference_channel, RING_TYPE_MEDIA_CHANNEL,
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_INTERFACE_DTMF,
@@ -242,11 +245,8 @@ modem_call_service_join_reply (ModemCallService *service,
context = modem_request_steal_data(request, "tp-request");
if (!error) {
- RingConnection *conn = RING_CONNECTION (
- tp_base_channel_get_connection (TP_BASE_CHANNEL (self)));
-
member_path = modem_request_get_data(request, "member-object-path");
- member = ring_connection_lookup_channel(conn, member_path);
+ member = ring_connection_lookup_channel(self->base.connection, member_path);
if (ring_conference_channel_join(self, member, &error)) {
ring_svc_channel_interface_mergeable_conference_return_from_merge
@@ -273,9 +273,7 @@ ring_mergeable_conference_merge(RingSvcChannelInterfaceMergeableConference *ifac
DEBUG("enter");
- member = ring_connection_lookup_channel(
- RING_CONNECTION(tp_base_channel_get_connection(TP_BASE_CHANNEL(self))),
- channel_path);
+ member = ring_connection_lookup_channel(self->base.connection, channel_path);
if (!member || !RING_IS_MEMBER_CHANNEL(member)) {
error = g_error_new(TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
@@ -914,8 +912,7 @@ ring_conference_channel_constructed(GObject *object)
{
RingConferenceChannel *self = RING_CONFERENCE_CHANNEL(object);
TpBaseChannel *base = TP_BASE_CHANNEL (self);
- TpBaseConnection *connection =
- tp_base_channel_get_connection(base);
+ TpBaseConnection *connection = TP_BASE_CONNECTION(self->base.connection);
const gchar *object_path;
char *nick;
@@ -948,8 +945,7 @@ ring_conference_channel_emit_initial(RingConferenceChannel *_self)
RingConferenceChannel *self = RING_CONFERENCE_CHANNEL(_self);
RingConferenceChannelPrivate *priv = self->priv;
- RingConnection *connection =
- RING_CONNECTION(tp_base_channel_get_connection(TP_BASE_CHANNEL(self)));
+ RingConnection *connection = self->base.connection;
TpGroupMixin *group = TP_GROUP_MIXIN(self);
char const *message;
TpChannelGroupChangeReason reason;
@@ -1005,6 +1001,12 @@ ring_conference_channel_get_property(GObject *obj,
RingConferenceChannelPrivate *priv = self->priv;
switch (property_id) {
+ case PROP_CHANNEL_PROPERTIES:
+ g_value_take_boxed(value, ring_conference_channel_properties(self));
+ break;
+ case PROP_INTERFACES:
+ g_value_set_boxed(value, ring_conference_channel_interfaces);
+ break;
case PROP_INITIAL_CHANNELS:
g_value_set_boxed(value, priv->initial_members);
break;
@@ -1086,7 +1088,6 @@ static void
ring_conference_channel_class_init(RingConferenceChannelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
- TpBaseChannelClass *base_chan_class = TP_BASE_CHANNEL_CLASS (klass);
g_type_class_add_private(klass, sizeof (RingConferenceChannelPrivate));
@@ -1096,12 +1097,6 @@ ring_conference_channel_class_init(RingConferenceChannelClass *klass)
object_class->dispose = ring_conference_channel_dispose;
object_class->finalize = ring_conference_channel_finalize;
- base_chan_class->channel_type = TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA;
- base_chan_class->close = (TpBaseChannelCloseFunc) ring_conference_channel_close;
- base_chan_class->interfaces = ring_conference_channel_interfaces;
- base_chan_class->target_handle_type = TP_HANDLE_TYPE_NONE;
- base_chan_class->fill_immutable_properties = ring_conference_channel_fill_immutable_properties;
-
klass->dbus_properties_class.interfaces =
ring_conference_channel_dbus_property_interfaces;
tp_dbus_properties_mixin_class_init(
@@ -1117,6 +1112,12 @@ ring_conference_channel_class_init(RingConferenceChannelClass *klass)
object_class, ring_conference_channel_remove_member_with_reason);
tp_group_mixin_init_dbus_properties(object_class);
+ g_object_class_override_property(
+ object_class, PROP_CHANNEL_PROPERTIES, "channel-properties");
+
+ g_object_class_override_property(
+ object_class, PROP_INTERFACES, "interfaces");
+
g_object_class_install_property(
object_class, PROP_INITIAL_CHANNELS,
g_param_spec_boxed("initial-channels",
@@ -1161,14 +1162,11 @@ ring_conference_channel_dbus_property_interfaces[] = {
{ NULL }
};
-static void
-ring_conference_channel_fill_immutable_properties(TpBaseChannel *base,
- GHashTable *props)
+static GHashTable*
+ring_conference_channel_properties(RingConferenceChannel *self)
{
- TP_BASE_CHANNEL_CLASS (ring_conference_channel_parent_class)->fill_immutable_properties (
- base, props);
-
- tp_dbus_properties_mixin_fill_properties_hash (G_OBJECT(base), props,
+ return ring_channel_add_properties(
+ self, ring_media_channel_properties(RING_MEDIA_CHANNEL(self)),
TP_IFACE_CHANNEL_INTERFACE_CONFERENCE, "InitialChannels",
NULL);
}
@@ -1269,7 +1267,7 @@ ring_conference_channel_remove_member_with_reason(GObject *iface,
DEBUG("enter");
selfhandle = tp_base_connection_get_self_handle(
- tp_base_channel_get_connection(TP_BASE_CHANNEL(self)));
+ TP_BASE_CONNECTION(self->base.connection));
removing = tp_intset_new();
@@ -1668,7 +1666,7 @@ ring_conference_channel_close_impl (RingConferenceChannel *self,
tp_base_channel_destroyed (base);
}
- return TRUE;
+ return priv->closed = TRUE;
}
/**
@@ -1786,7 +1784,7 @@ ring_conference_channel_create_streams (RingConferenceChannel *_self,
priv->streams_created = 1;
- baseconn = tp_base_channel_get_connection (TP_BASE_CHANNEL (self));
+ baseconn = self->base.connection;
if (!ring_connection_validate_initial_members (RING_CONNECTION (baseconn),
priv->initial_members, error))
diff --git a/src/ring-conference-channel.h b/src/ring-conference-channel.h
index dab4c17..cdf5826 100644
--- a/src/ring-conference-channel.h
+++ b/src/ring-conference-channel.h
@@ -24,7 +24,6 @@
#include <glib-object.h>
#include <telepathy-glib/base-channel.h>
-#include <telepathy-glib/group-mixin.h>
G_BEGIN_DECLS
@@ -40,13 +39,13 @@ G_END_DECLS
G_BEGIN_DECLS
struct _RingConferenceChannelClass {
- TpBaseChannelClass parent_class;
+ RingMediaChannelClass parent_class;
TpGroupMixinClass group_class;
TpDBusPropertiesMixinClass dbus_properties_class;
};
struct _RingConferenceChannel {
- TpBaseChannel parent;
+ RingMediaChannel base;
TpGroupMixin group;
RingConferenceChannelPrivate *priv;
gchar *nick;
diff --git a/src/ring-media-channel.c b/src/ring-media-channel.c
index c8c97d8..3a1b8e1 100644
--- a/src/ring-media-channel.c
+++ b/src/ring-media-channel.c
@@ -69,6 +69,10 @@
struct _RingMediaChannelPrivate
{
+ TpBaseConnection *connection;
+
+ gchar *object_path;
+
GQueue requests[1]; /* Requests towards the modem */
uint8_t state;
@@ -79,10 +83,11 @@ struct _RingMediaChannelPrivate
uint8_t requested; /* Hold state requested by client */
} hold;
+ unsigned requested:1;
unsigned initial_audio:1; /* property */
unsigned disposed:1;
- unsigned closing:1;
+ unsigned closing:1, closed:1;
unsigned :0;
ModemRequest *control;
@@ -110,8 +115,22 @@ struct _RingMediaChannelPrivate
/* properties */
enum {
PROP_NONE,
+ /* telepathy-glib properties */
+ PROP_OBJECT_PATH,
+ PROP_CHANNEL_PROPERTIES,
+ PROP_CHANNEL_DESTROYED,
+ PROP_CHANNEL_TYPE,
+ PROP_TARGET,
+ PROP_TARGET_ID,
+ PROP_TARGET_TYPE,
/* DBUs properties */
+ PROP_INTERFACES,
+
+ PROP_REQUESTED,
+ PROP_INITIATOR,
+ PROP_INITIATOR_ID,
+
PROP_HOLD_STATE, /* o.f.T.Channel.Interface.Hold */
PROP_HOLD_REASON, /* o.f.T.Channel.Interface.Hold */
@@ -121,25 +140,28 @@ enum {
/* ring-specific properties */
PROP_PEER,
+ PROP_CONNECTION,
PROP_CALL_INSTANCE,
PROP_TONES,
LAST_PROPERTY
};
-static void ring_media_channel_fill_immutable_properties(TpBaseChannel *base,
- GHashTable *props);
+static TpDBusPropertiesMixinIfaceImpl
+ring_media_channel_dbus_property_interfaces[];
+static void ring_media_channel_channel_iface_init(gpointer, gpointer);
static void ring_media_channel_dtmf_iface_init(gpointer, gpointer);
-
static void ring_channel_hold_iface_init(gpointer, gpointer);
#if nomore
static void ring_channel_dial_strings_iface_init(gpointer, gpointer);
#endif
G_DEFINE_TYPE_WITH_CODE(
- RingMediaChannel, ring_media_channel, TP_TYPE_BASE_CHANNEL,
+ RingMediaChannel, ring_media_channel, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
+G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL,
+ ring_media_channel_channel_iface_init);
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_INTERFACE_DTMF,
ring_media_channel_dtmf_iface_init);
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_INTERFACE_HOLD,
@@ -151,6 +173,8 @@ G_DEFINE_TYPE_WITH_CODE(
#endif
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAMED_MEDIA,
ring_streamed_media_mixin_iface_init);
+ G_IMPLEMENT_INTERFACE(TP_TYPE_EXPORTABLE_CHANNEL, NULL);
+ G_IMPLEMENT_INTERFACE(TP_TYPE_CHANNEL_IFACE, NULL);
);
static void ring_media_channel_set_call_instance(RingMediaChannel *self,
@@ -202,21 +226,16 @@ static void
ring_media_channel_constructed(GObject *object)
{
RingMediaChannel *self = RING_MEDIA_CHANNEL(object);
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
- const gchar *object_path;
+ RingMediaChannelPrivate *priv = self->priv;
+ TpBaseConnection *connection = TP_BASE_CONNECTION(priv->connection);
+ TpDBusDaemon *bus_daemon = tp_base_connection_get_dbus_daemon(connection);
if (G_OBJECT_CLASS(ring_media_channel_parent_class)->constructed)
G_OBJECT_CLASS(ring_media_channel_parent_class)->constructed(object);
- object_path = tp_base_channel_get_object_path (base);
- g_assert(object_path != NULL);
-
- self->nick = strrchr(object_path, '/');
- g_assert (self->nick++ != NULL);
-
DEBUG("(%p) with %s", self, self->nick);
- tp_base_channel_register (base);
+ tp_dbus_daemon_register_object(bus_daemon, priv->object_path, object);
}
static void
@@ -227,11 +246,46 @@ ring_media_channel_get_property(GObject *obj,
{
RingMediaChannel *self = RING_MEDIA_CHANNEL(obj);
RingMediaChannelPrivate *priv = self->priv;
+ guint initiator;
+ gchar const *id;
switch (property_id) {
+ case PROP_OBJECT_PATH:
+ g_value_set_string(value, priv->object_path);
+ break;
+ case PROP_CHANNEL_DESTROYED:
+ g_value_set_boolean(value, TRUE);
+ break;
+ case PROP_CHANNEL_PROPERTIES:
+ g_value_take_boxed(value, ring_media_channel_properties(self));
+ break;
+ case PROP_CHANNEL_TYPE:
+ g_value_set_static_string(value, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
+ break;
case PROP_PEER:
g_value_set_uint(value, 0);
break;
+ case PROP_TARGET:
+ g_value_set_uint(value, 0);
+ break;
+ case PROP_TARGET_TYPE:
+ g_value_set_uint(value, 0);
+ break;
+ case PROP_TARGET_ID:
+ g_value_set_uint(value, 0);
+ break;
+ case PROP_INITIATOR:
+ initiator = tp_base_connection_get_self_handle(priv->connection);
+ g_value_set_uint(value, initiator);
+ break;
+ case PROP_INITIATOR_ID:
+ initiator = tp_base_connection_get_self_handle(priv->connection);
+ id = ring_connection_inspect_contact(RING_CONNECTION(priv->connection), initiator);
+ g_value_set_static_string(value, id);
+ break;
+ case PROP_REQUESTED:
+ g_value_set_boolean(value, priv->requested);
+ break;
case PROP_HOLD_STATE:
g_value_set_uint(value, priv->hold.state);
break;
@@ -247,6 +301,9 @@ ring_media_channel_get_property(GObject *obj,
case PROP_IMMUTABLE_STREAMS:
g_value_set_boolean(value, TRUE);
break;
+ case PROP_CONNECTION:
+ g_value_set_object(value, priv->connection);
+ break;
case PROP_CALL_INSTANCE:
g_value_set_pointer(value, self->call_instance);
break;
@@ -266,10 +323,24 @@ ring_media_channel_set_property(GObject *obj,
RingMediaChannelPrivate *priv = self->priv;
switch (property_id) {
+ case PROP_OBJECT_PATH:
+ priv->object_path = g_strdup(value);
+ self->nick = strrchr(priv->object_path, '/');
+ if(!self->nick++) self->nick = "";
+ DEBUG("(%p) with nick '%s", self, self->nick);
+ break;
+ case PROP_CHANNEL_TYPE:
+ case PROP_INITIATOR:
+ case PROP_TARGET:
+ case PROP_TARGET_ID:
+ case PROP_TARGET_TYPE:
case PROP_PEER:
/* these property is writable in the interface, but not actually
* meaningfully changable on this channel, so we do nothing */
break;
+ case PROP_REQUESTED:
+ priv->requested = g_value_get_boolean(value);
+ break;
case PROP_HOLD_STATE:
priv->hold.state = g_value_get_uint(value);
break;
@@ -279,6 +350,9 @@ ring_media_channel_set_property(GObject *obj,
case PROP_INITIAL_AUDIO:
priv->initial_audio = g_value_get_boolean(value);
break;
+ case PROP_CONNECTION:
+ priv->connection = g_value_get_object(value);
+ break;
case PROP_CALL_INSTANCE:
ring_media_channel_set_call_instance (self, g_value_get_pointer (value));
break;
@@ -323,7 +397,8 @@ ring_media_channel_finalize(GObject *object)
{
RingMediaChannel *self = RING_MEDIA_CHANNEL(object);
RingMediaChannelPrivate *priv = self->priv;
- gchar *nick = g_strdup (self->nick);
+ gchar const *nick = self->nick;
+ gchar *object_path = priv->object_path;
ring_streamed_media_mixin_finalize (object);
@@ -331,8 +406,8 @@ ring_media_channel_finalize(GObject *object)
G_OBJECT_CLASS(ring_media_channel_parent_class)->finalize(object);
- DEBUG("(%p) on %s", object, nick);
- g_free(nick);
+ DEBUG("(%p) on %s", (gpointer)object, nick);
+ g_free(object_path);
}
/* ====================================================================== */
@@ -342,7 +417,6 @@ static void
ring_media_channel_class_init(RingMediaChannelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
- TpBaseChannelClass *base_chan_class = TP_BASE_CHANNEL_CLASS (klass);
g_type_class_add_private(klass, sizeof (RingMediaChannelPrivate));
@@ -352,10 +426,38 @@ ring_media_channel_class_init(RingMediaChannelClass *klass)
object_class->dispose = ring_media_channel_dispose;
object_class->finalize = ring_media_channel_finalize;
- base_chan_class->channel_type = TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA;
- base_chan_class->close = (TpBaseChannelCloseFunc) ring_media_channel_close;
- base_chan_class->fill_immutable_properties =
- ring_media_channel_fill_immutable_properties;
+ g_object_class_override_property(
+ object_class, PROP_OBJECT_PATH, "object-path");
+
+ g_object_class_override_property(
+ object_class, PROP_CHANNEL_PROPERTIES, "channel-properties");
+
+ g_object_class_override_property(
+ object_class, PROP_CHANNEL_DESTROYED, "channel-destroyed");
+
+ g_object_class_override_property(
+ object_class, PROP_CHANNEL_TYPE, "channel-type");
+
+ g_object_class_override_property(
+ object_class, PROP_TARGET_TYPE, "handle-type");
+
+ g_object_class_override_property(
+ object_class, PROP_TARGET, "handle");
+
+ g_object_class_install_property(
+ object_class, PROP_TARGET_ID, ring_param_spec_handle_id(0));
+
+ g_object_class_install_property(
+ object_class, PROP_INTERFACES, ring_param_spec_interfaces());
+
+ g_object_class_install_property(
+ object_class, PROP_REQUESTED, ring_param_spec_requested(G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property(
+ object_class, PROP_INITIATOR, ring_param_spec_initiator(0));
+
+ g_object_class_install_property(
+ object_class, PROP_INITIATOR_ID, ring_param_spec_initiator_id(0));
g_object_class_install_property(
object_class, PROP_HOLD_STATE,
@@ -380,6 +482,9 @@ ring_media_channel_class_init(RingMediaChannelClass *klass)
G_PARAM_STATIC_STRINGS));
g_object_class_install_property(
+ object_class, PROP_CONNECTION, ring_param_spec_connection());
+
+ g_object_class_install_property(
object_class, PROP_PEER,
g_param_spec_uint("peer",
"Peer handle",
@@ -443,14 +548,59 @@ ring_media_channel_class_init(RingMediaChannelClass *klass)
* org.freedesktop.DBus properties
*/
-static void
-ring_media_channel_fill_immutable_properties (TpBaseChannel *base,
- GHashTable *props)
-{
- TP_BASE_CHANNEL_CLASS (ring_media_channel_parent_class)->
- fill_immutable_properties (base, props);
+static TpDBusPropertiesMixinPropImpl channel_properties[] = {
+ { "ChannelType", "channel-type", NULL },
+ { "Interfaces", "interfaces", NULL },
+ { "TargetHandle", "handle", NULL },
+ { "TargetID", "handle-id", NULL },
+ { "TargetHandleType", "handle-type", NULL },
+ { "Requested", "requested", NULL },
+ { "InitiatorHandle", "initiator" },
+ { "InitiatorId", "initiator-id" },
+ { NULL }
+};
+
+static TpDBusPropertiesMixinPropImpl media_properties[] = {
+ { "InitialAudio", "initial-audio", NULL },
+ { "InitialVideo", "initial-video", NULL },
+ { NULL }
+};
+
+static TpDBusPropertiesMixinIfaceImpl
+ring_media_channel_dbus_property_interfaces[] = {
+ {
+ TP_IFACE_CHANNEL,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ channel_properties,
+ },
+ {
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ media_properties,
+ },
+ { NULL }
+};
- ring_streamed_media_mixin_fill_immutable_properties (base, props);
+GHashTable*
+ring_media_channel_properties(RingMediaChannel *self)
+{
+ return tp_dbus_properties_mixin_make_properties_hash(
+ G_OBJECT(self),
+ TP_IFACE_CHANNEL, "ChannelType",
+ TP_IFACE_CHANNEL, "Interfaces",
+ TP_IFACE_CHANNEL, "TargetHandle",
+ TP_IFACE_CHANNEL, "TargetHandleType",
+ TP_IFACE_CHANNEL, "TargetID",
+ TP_IFACE_CHANNEL, "InitiatorHandle",
+ TP_IFACE_CHANNEL, "InitiatorID",
+ TP_IFACE_CHANNEL, "Requested",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialAudio",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialVideo",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "ImmutableStreams",
+ NULL
+ );
}
/* ====================================================================== */
@@ -458,12 +608,11 @@ ring_media_channel_fill_immutable_properties (TpBaseChannel *base,
ModemCallService *
ring_media_channel_get_call_service (RingMediaChannel *self)
{
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
- TpBaseConnection *base_connection;
+ RingMediaChannelPrivate *priv = self->priv;
+ TpBaseConnection *base_connection = priv->connection;
RingConnection *connection;
ModemOface *oface;
- base_connection = tp_base_channel_get_connection (base);
connection = RING_CONNECTION (base_connection);
oface = ring_connection_get_modem_interface (connection,
MODEM_OFACE_CALL_MANAGER);
@@ -518,11 +667,12 @@ ring_media_channel_close(RingMediaChannel *self)
RingMediaChannelClass *cls = RING_MEDIA_CHANNEL_GET_CLASS(self);
gboolean ready = TRUE;
- if (tp_base_channel_is_destroyed (TP_BASE_CHANNEL (self)))
+ if (priv->closed)
return;
if (priv->closing)
return;
+
priv->closing = TRUE;
if (priv->playing)
@@ -550,17 +700,19 @@ static gboolean
ring_media_channel_emit_closed(RingMediaChannel *self)
{
RingMediaChannelPrivate *priv = self->priv;
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
RingMediaChannelClass *cls = RING_MEDIA_CHANNEL_GET_CLASS(self);
if (priv->close_timer)
g_source_remove(priv->close_timer), priv->close_timer = 0;
- if (tp_base_channel_is_destroyed (TP_BASE_CHANNEL (self)))
+ if (priv->closed)
return FALSE;
+ priv->closed = TRUE;
+
if (priv->playing)
modem_tones_stop(priv->tones, priv->playing);
+
priv->playing = 0;
cls->close(self, TRUE);
@@ -568,14 +720,111 @@ ring_media_channel_emit_closed(RingMediaChannel *self)
if (self->call_instance)
g_object_set(self, "call-instance", NULL, NULL);
- tp_base_channel_destroyed (base);
+ tp_svc_channel_emit_closed((TpSvcChannel*)self);
- DEBUG("emitted Closed on %s", self->nick);
+ DEBUG("emit Closed on %s", self->nick);
return FALSE;
}
/* ====================================================================== */
+/**
+ * Telepathy.Channel DBus interface
+ *
+ * Close() -> nothing
+ * GetChannelType() -> s
+ * GetHandle() -> u, u
+ * GetInterfaces() -> as
+ *
+ * Signals:
+ * -> Closed(
+ */
+
+/** DBus method Close ( ) -> nothing
+ *
+ * Request that the channel be closed. This is not the case until the Closed
+ * signal has been emitted, and depending on the connection manager this may
+ * simply remove you from the channel on the server, rather than causing it
+ * to stop existing entirely. Some channels such as contact list channels
+ * may not be closed.
+ */
+void
+ring_media_channel_method_close(TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ DEBUG("Close() entered");
+ ring_media_channel_close(RING_MEDIA_CHANNEL(iface));
+ tp_svc_channel_return_from_close(context);
+}
+
+/** DBus method GetChannelType() -> s
+ *
+ * Returns the interface name for this type of channel.
+ */
+static void
+ring_media_channel_method_get_channel_type(TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ DEBUG("GetChannelType() entered");
+ gchar *type = NULL;
+ g_object_get(iface, "channel-type", &type, NULL);
+ tp_svc_channel_return_from_get_channel_type(context, type);
+ g_free(type);
+}
+
+/** DBus method GetHandle() -> u, u
+ *
+ * Returns the handle type and number if this channel represents a
+ * communication with a particular contact, room or server-stored list, or
+ * zero if it is transient and defined only by its' contents.
+ */
+static void
+ring_media_channel_method_get_handle(TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ DEBUG("GetHandle() entered");
+ guint type = 0, target = 0;
+ g_object_get(iface, "handle-type", &type, "handle", &target, NULL);
+ tp_svc_channel_return_from_get_handle(context, type, target);
+}
+
+/** DBus method GetInterfaces() -> as
+ *
+ * Get the optional interfaces implemented by this channel.
+ */
+static void
+ring_media_channel_method_get_interfaces(TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ DEBUG("GetInterfaces() entered");
+ gchar **interfaces = NULL;
+ g_object_get(iface, "interfaces", &interfaces, NULL);
+ tp_svc_channel_return_from_get_interfaces(
+ context,
+ (char const **)interfaces);
+ g_strfreev(interfaces);
+}
+
+static void
+ring_media_channel_channel_iface_init(gpointer g_iface, gpointer iface_data)
+{
+ TpSvcChannelClass *klass = (TpSvcChannelClass*) g_iface;
+
+#define IMPLEMENT(x) \
+ tp_svc_channel_implement_##x(klass, ring_media_channel_method_##x)
+
+ IMPLEMENT(close);
+ IMPLEMENT(get_channel_type);
+ IMPLEMENT(get_handle);
+ IMPLEMENT(get_interfaces);
+
+#undef IMPLEMENT
+}
+
+/* ====================================================================== */
+
+
+/* ====================================================================== */
/*
* Telepathy.Channel.Interface.DTMF DBus interface - version 0.15
*/
diff --git a/src/ring-media-channel.h b/src/ring-media-channel.h
index 1fd4dc8..70630e8 100644
--- a/src/ring-media-channel.h
+++ b/src/ring-media-channel.h
@@ -23,8 +23,7 @@
#define RING_MEDIA_CHANNEL_H
#include <glib-object.h>
-
-#include <telepathy-glib/base-channel.h>
+#include <telepathy-glib/group-mixin.h>
#include <telepathy-glib/dbus-properties-mixin.h>
#include <telepathy-glib/svc-channel.h>
#include <ring-streamed-media-mixin.h>
@@ -44,7 +43,8 @@ G_END_DECLS
G_BEGIN_DECLS
struct _RingMediaChannelClass {
- TpBaseChannelClass parent_class;
+ GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_properties_class;
RingStreamedMediaMixinClass streamed_media_class;
@@ -55,12 +55,14 @@ struct _RingMediaChannelClass {
};
struct _RingMediaChannel {
- TpBaseChannel parent;
+ GObject parent;
+
+ RingConnection *connection;
RingStreamedMediaMixin streamed_media;
/* Read-only */
ModemCall *call_instance;
- char *nick;
+ char const *nick;
RingMediaChannelPrivate *priv;
};
@@ -129,13 +131,16 @@ void ring_media_channel_set_state(RingMediaChannel *self,
guint causetype,
guint cause);
+GHashTable *ring_media_channel_properties(RingMediaChannel *self);
+
void ring_media_channel_dtmf_start_tone(TpSvcChannelInterfaceDTMF *iface,
guint stream_id,
guchar event,
- DBusGMethodInvocation *context);
+ DBusGMethodInvocation *context);
+
void ring_media_channel_dtmf_stop_tone(TpSvcChannelInterfaceDTMF *iface,
guint stream_id,
- DBusGMethodInvocation *context);
+ DBusGMethodInvocation *context);
G_END_DECLS
diff --git a/src/ring-media-manager.c b/src/ring-media-manager.c
index 1eccecd..2fcebeb 100644
--- a/src/ring-media-manager.c
+++ b/src/ring-media-manager.c
@@ -878,7 +878,7 @@ ring_media_manager_outgoing_call(RingMediaManager *self,
"connection", priv->connection,
"tones", priv->tones,
"object-path", object_path,
- "initiator-handle", initiator,
+ "initiator", initiator,
"handle-type", htype,
"handle", target,
"peer", target,
@@ -988,7 +988,7 @@ on_modem_call_incoming(ModemCallService *call_service,
"connection", priv->connection,
"tones", priv->tones,
"object-path", object_path,
- "initiator-handle", handle,
+ "initiator", handle,
"handle-type", TP_HANDLE_TYPE_CONTACT,
"handle", handle,
"peer", handle,
@@ -1052,8 +1052,6 @@ on_modem_call_created(ModemCallService *call_service,
"connection", priv->connection,
"tones", priv->tones,
"object-path", object_path,
- "initiator-handle", tp_base_connection_get_self_handle(
- TP_BASE_CONNECTION(priv->connection)),
"handle-type", TP_HANDLE_TYPE_CONTACT,
"handle", handle,
"peer", handle,