diff options
author | Tom Swindell <t.swindell@rubyx.co.uk> | 2013-03-03 11:28:06 +0000 |
---|---|---|
committer | Tom Swindell <t.swindell@rubyx.co.uk> | 2013-03-03 11:28:06 +0000 |
commit | 428422824318778129585c0dfd0aac368f9bdf0d (patch) | |
tree | a340cb0289b78edb309f74886e775befb8c17c20 | |
parent | ab3b6d31cf41a0d1578d5f5f788f63d68945e0ee (diff) |
Migrate RingMediaChannel to use TpBaseChannel
Signed-off-by: Tom Swindell <t.swindell@rubyx.co.uk>
-rw-r--r-- | src/ring-call-channel.c | 136 | ||||
-rw-r--r-- | src/ring-conference-channel.c | 62 | ||||
-rw-r--r-- | src/ring-conference-channel.h | 5 | ||||
-rw-r--r-- | src/ring-media-channel.c | 323 | ||||
-rw-r--r-- | src/ring-media-channel.h | 19 | ||||
-rw-r--r-- | src/ring-media-manager.c | 6 |
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, |